Hi everyone!! I've trying for a while to make the I2C module to work in polling mode, but I found that interrupt bit (SI) bit doesn't clear whenever I write a 1 in the I2CONCLR register. Every other bits seem to change accordingly in the way one expects, but this one refuses to do so. The user manual says that writing a 1 in I2CONCLR clears that bit, and I need to see changes in this bit for polling correctly, otherwise I'll need to check all over the 26 status codes!! The general idea is to read and program the flash memory 24LC32 (as well as other devices like RTC's), but before I needed to write the I2C driver. When writing a byte I had no problems (I guess), but I don't know whether it works or not 'cause I'm not able to read it 'til now. Here is an excerpt from my code (sorry, comments are in spanish, my mother tongue). There is no enough nor clear information over the net for using the I2C module, so as soon as I make it work as it should I'll share it with the community. Please take a look at the iicSndStart() and iicRdBy() functions Thanks in advanced =) /* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */ void iicInit(void) { IO0SET|=(3<<2); // config PINES PINSEL0|=(1<<4)|(1<<6); // baud rate para 100 KHz: i2scl=60x10_6/100x10_3=600=300+300 I2SCLH=300; I2SCLL=300; // igual que después del reset I2CONCLR=0x6c; // NOTA: no se debe escribir 0xFF !! I2CONSET=IIC_I2EN_BIT; // habilita el módulo IIC } /* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */ bool_t iicSndStart(ubyte_t addr, bool_t t) { I2CONSET=IIC_STA_BIT; // envía el start while(!(I2STAT&0x08)) ; I2CONCLR=IIC_STAC_BIT; // evita start's consecutivos I2CONCLR=IIC_SIC_BIT; // <-- DOESN'T CHANGE THE SI BIT !! if(t==IIC_WRITE){ addr&=~(IIC_READ); } else{ addr|=(IIC_READ); } I2DAT=addr; // envía la dirección I2CONCLR=IIC_SIC_BIT; // <-- DOESN'T CHANGE THE SI BIT !! while(!(I2CONCLR&IIC_SI_BIT)) // espera a que se transmita el byte ; if(I2STAT==0x18){ // se recibió el ack del esclavo (wr mode) return true; } if(I2STAT==0x40){ // se recibió el ack del esclavo (rd mode) return true; } return false; } /* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */ void iicSndStop(void) { I2CONSET=IIC_STO_BIT; //envía el stop. Automáticamente se pone en 0 } /* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */ bool_t iicWrBy(ubyte_t data) { I2DAT=data; // transmite el dato I2CONCLR=IIC_SIC_BIT; // resetea la bandera SI while(!(I2CONCLR&IIC_SI_BIT)) // espera a que se transmita el byte ; if(I2STAT==0x28){ // se recibió el ack del esclavo (wr mode) return true; } return false; } /* I'M STILL WORKING IN THIS ONE 'CAUSE SI BIT DOESN'T CHANGE ubyte_t iicRdBy(void) { I2CONCLR=IIC_SIC_BIT; // <-- DOESN'T CHANGE THE SI BIT !! while(!(I2CONSET&IIC_SI_BIT)) // espera a recibir el dato ; if(I2STAT==0x58){ // se contestó al slave return I2DAT; } }
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.