??? 01/13/06 12:47 Modified: 01/13/06 13:06 Read: times |
#107264 - I2C routine getting stuck. |
Dear Forum Members,
- In one of my new products I am using P89C669 microcontroller with PCF8591 ADC and AT24C64 EEPROM connected to I2C bus of P89C669 port pins P1.6 and P1.7. - The I2C bus has pull up resistors on SCL and SDA each 4k7. - The trace width of SDA and SCL is 13 mils and trace length approx 2 inches. - Device address ADC 000 EEPROM 001 - 24MHz crystal is being used for clocking micro. - The boards are double sided PTH with solid ground plane on bottom. Hardly a couple of small tracks on bottom rest all ground plane. Empty area on top too is ground plane reinforced with bottom with lots of vias. Now the problem is the adc reading routines hangs sometimes. The frequency of getting hung increases with increase in I2C bus clock freqency and reduces with reduction in frequencies. micro ADC and EEPROM all three support 100kHz but adc routine gets stuck badly even at 80kHz. Even at 40kHz it hangs. Time to hang--- 100kHz ---> less than a min. 80kHz ----> approx 5mins. 40kHz ---> approx 30 mins. In my earlier design i had used EEPROM on port 3 using bit banged i2c and ADC on hardware i2c it never gave problem this time i connected both devices onto i2c and it is giving problems. I have investigated and found that it is adc reading routine where it always gets stuck. It gets stuck in the while loops waiting for SI flag. Following is code for same. Please help me. // Parameters pointer to location where reading is stored and adc channel number. I2SCL & I2SCH = 133 in main program. void read_pcf8591( uchar *adrdbuff, uchar adch) { I2CON=0x40; //Initializing for 94KHz I2CON|=0x20; //Send a start. while(!(I2CON&0x08)); //Wait for SI I2CON&=0xDF; //Clear start bit. I2DAT=0x90; //Slave address 000 and write. I2CON&=0xF7; //Clear the SI Flag. while(!(I2CON&0x08)); //Wait for slave address to be sent. I2DAT=adch; //Send the ADC channel number. I2CON&=0xF7; //Clear SI bit. while(!(I2CON&0x08)); //Wait for sending ADC channel. I2CON&=0xF7; //Clear SI bit. I2CON|=0x10; //Send Stop condition. while(I2CON&0x10); //Wait for stop condition to be sent. I2CON=0x40; I2CON|=0x20; while(!(I2CON&0x08)); //Wait for start sending. I2CON&=0xDF; //Clear Start bit. I2DAT=0x91; //Slave address 000 and read. I2CON&=0xF7; //Clear SI bit. while(!(I2CON&0x08)); //Wait for slave address to be sent. // First Reading Dummy read to clear old value. I2CON|=0x04; //Set Auto Acknowledge. I2CON&=0xF7; //Clear SI bit. while(!(I2CON&0x08)); //Wait for ADC value to be received. *adrdbuff=I2DAT; //Store the ADC value. I2CON&=0xFB; //Clear Auto Acknowledge. I2CON&=0xF7; //Clear SI. while(!(I2CON&0x08)); //Wait for ADC value to be received. *adrdbuff=I2DAT; //Store the ADC value. I2CON&=0xF7; //clear SI bit. I2CON|=0x10; //Send stop Condition. while(I2CON&0x10); //Wait for stop condition to be sent. } Thanks & Regards, Prahlad Purohit. |
Topic | Author | Date |
I2C routine getting stuck. | 01/01/70 00:00 | |
you can get working code by using | 01/01/70 00:00 | |
Re: Getting code working | 01/01/70 00:00 | |
I took aquick look at the I2con use and | 01/01/70 00:00 | |
Re: Why not interrupt. | 01/01/70 00:00 | |
24MHz without four layer board? | 01/01/70 00:00 | |
Re: 24MHz | 01/01/70 00:00 | |
What max freq can be used with two layer | 01/01/70 00:00 | |
who knows | 01/01/70 00:00 | |
I2C routine getting stuck. | 01/01/70 00:00 | |
Working very well with C668 @ 94khz bus | 01/01/70 00:00 | |
Bit Bangin Works fine. | 01/01/70 00:00 | |
Problem Solved. | 01/01/70 00:00 | |
maybe worth putting it into code library | 01/01/70 00:00 | |
Uploaded into code library.![]() | 01/01/70 00:00 |