void IIC_read_bytes(byte Command, byte addr){
byte RD_data;
char i;
IIC1C1_TXAK = 0;
IIC1C1 |= 0X30;
IIC1D = Command|I2C_WRITE;
while (!IIC1S_IICIF){}
IIC1S_IICIF=1;
while (IIC1S_RXAK){}
DelayMs(5);
IIC1D = addr;
while (!IIC1S_IICIF){}
IIC1S_IICIF=1;
while (IIC1S_RXAK){}
DelayMs(5);
IIC1C1_RSTA = 1;
IIC1D = Command|I2C_READ;
while (!IIC1S_IICIF){}
IIC1S_IICIF=1;
while (IIC1S_RXAK){}
DelayMs(5);
IIC1C1_TX = 0;
Dato[0] = IIC1D;
while (!IIC1S_IICIF){}
IIC1S_IICIF=1;
while (IIC1S_RXAK){}
DelayMs(5);
for(i=0;i<5;i++){
IIC1C1_TXAK = 0;
Dato[i] = IIC1D;
}
IIC1C1_TXAK = 1;
Dato[5] = IIC1D;
IIC1C1_MST = 0;
}void main(void) {
MCU_Init();
Clock_Init();
Port_Init();
Init_I2C();
SCI1_Init();
SCI1C2_RIE=1;
State_Led=1;
EnableInterrupts;
//Iniciar el Wii Motion Plus
//**** Desactiva el Wii Motion Plus inicialmente
IIC_Start();
IIC_PutChar(0XA6);
IIC_PutChar(0XF0);
IIC_PutChar(0X55);
IIC_Stop();
//****Activa el Wii motion Plus
DelayMs(10);
IIC_Start();
IIC_PutChar(0XA6);
IIC_PutChar(0XFE);
IIC_PutChar(0X04);
IIC_Stop();
//****
DelayMs(10);
IIC_Start();
IIC_PutChar(0XA4);
IIC_PutChar(0XFB);
IIC_PutChar(0X00);
IIC_Stop();
//****
DelayMs(40);
for(;;) {
IIC_read_bytes(0XA4,0X00);
SCI1_Puts("Informacion Wii Motion Plus");
SCI1_PutChar(LF);
SCI1_PutChar(CR);
SCI1_PutChar(Dato[0]|0X30);
SCI1_PutChar(Dato[1]|0X30);
SCI1_PutChar(Dato[2]|0X30);
SCI1_PutChar(Dato[3]|0X30);
SCI1_PutChar(Dato[4]|0X30);
SCI1_PutChar(Dato[5]|0X30);
SCI1_PutChar(LF);
SCI1_PutChar(CR);
SCI1_PutChar(LF);
SCI1_PutChar(CR);
State_Led=~State_Led;
DelayMs(100);
}
}Hola Mauricio, las recomendaciones en el foro de FreeScale se refieren a que es recomendable usar el IIC por medio de interrupciones y no por polling ( es como lo estas realizando ). La otra consideración a tener en cuenta en códigos de producción es colocar de alguna manera un timer para detectar dead-loops, como en este ejemplo:Saludos. muchas gracias por la respuesta. acabo de probar otro codigo desde una librería para I2C de este archivo: HCS08QRUGSW.Código: C
while (!IIC1S_IICIF){}
Este código tiene dos problemas si algo anda mal, primero si trabajas con watch-dog este nunca se refresca, y si por casualidad el componente exterior no funciona o no responde nunca salís del while.
Lo idea para mi sería hacer algo asi.Código: C
timer_event_set_msec( &Event, 1500 ); do { /* Kick the dog */ WatchDog_Clear(); if ( IIC1S_IICIF) { break; } }while ( !timer_event_has_expired( &Event ))
Aunque el código es más largo, es más seguro. Se espera porque cambie ese flag, mientras se resetea el watch dog, si esto no pasa en cierta cantidad salís del loop.
Saludos !