TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: rachelies en 04 de Junio de 2010, 11:40:44
-
Hola:
Verán, estoy utilizando 2 pic: el que llamo B, el esclavo, lee una variable analogica y la almacena en un registro. El otro PIC, el A, es el maestro. El maestro lee otra variable analogica y a la vez, se comunica por I2C con el B para leer la variable analogica que leyó. cuando tiene las 2 variables, las envia por USB al PC. El caso es que la variable que lee el propio A, sí que me la envía por USB, pero la del B no la lee, es como si no llegase a solicitar la lectura el Master al Slave. Sin embargo, todo este mismo codigo pero sin comunicacion USB si que la lee el Master del Slave.
Pego los códigos de ambos pic por si alguien me puede ayudar:
MASTER (A)
#include <18F2455.h>
#device ADC=8
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#DEFINE USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 8
#include <pic18_usb.h>
#include <.\include\midi_hid2.h>
#include <usb.c>
#include <ctype.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER,SCL=PIN_B1,SDA=PIN_B0,SLOW,FORCE_HW)
int8 pichA,pichB;
int8 out_data[2];
void main(void) {
delay_ms(1000);
set_tris_A(0b0000001);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
usb_init_cs();
while (TRUE) {
usb_task();
if (usb_enumerated())
{
output_high(PIN_A2);
set_adc_channel(0);
delay_us(20);
pichA=read_adc();
i2c_start();
i2c_write(0xA0+1);
pichB=i2c_read(0);
i2c_stop();
out_data[0]=pichB;
out_data[1]=pichA;
usb_put_packet(1,out_data,2,USB_DTS_TOGGLE);
}
}
}
ESCLAVO B:
#include <16F873A.h>
#device ADC=8
#fuses HS,NOWDT,PUT
#use delay(clock=20000000)
#use i2c(SLAVE,SCL=PIN_C3,SDA=PIN_C4,SLOW,FORCE_HW,ADDRESS=0x0A)
int pichB,state,buffer[0x01],adress;
#INT_SSP
void ssp_interrupt()
{
state=i2c_isr_state();
if(state==0x80){
i2c_write(buffer[0x00]);
output_high(PIN_A1); //este no se llega a encender, asi que no realiza la lectura el MASTER
}
}
void main(){
set_tris_A(0b00000001);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(20);
pichB=read_adc();
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
adress=0x00;
while(TRUE){
set_adc_channel(0);
delay_us(20);
pichB=read_adc();
buffer[0x00]=pichB;
delay_ms(1);
}
}
Muchas gracias a todos. Saludos
-
no tengo mucha experiencia con el tema del I2C, pero por lo que comentas es como que no esta entrando en la interrupcion o la condicion state==0x80 no se esta cumpliendo.
Yo cuando trabajo con interrupciones suelo poner alguna indicacion externa de un led, como has hecho creo con el RA1 del 16F873, podrias hacer lo mismo pero en varias partes del programa para indicarte en que parte está. Por ejemplo asi:
void ssp_interrupt()
{
output_high(PIN_A2); //SI ESTE LED NO SE ENCIENDE ES PORQUE NO ENTRA EN LA INTERRUPCION
state=i2c_isr_state();
if(state==0x80)
{
i2c_write(buffer[0x00]);
output_high(PIN_A1); //este no se llega a encender, asi que no realiza la lectura el MASTER
}
}