2017-02-22 12:59 AM
Hi,
Trying to get I2C communication between a F334 and a 24C32 EEPROM working,
The read and write functions do return correctly, but the reads do not match what
has been written to the EEPROM. Struggling to find the issue at hand and in the
thought that someone could possibly lend me a hand on this issue, which would
be very helpful. The EEPROM's address lines are all grounded, which effectively
puts the EEPROM at an address of 0xA0
The output I am reading in a terminal, which says:
-------------= I2C1 REG dump =------------- I2C_CR1 : 0x01 I2C_CR2 : 0x20404a1 I2C_OAR1 : 0x8000 I2C_OAR2 : 0x00 I2C_TIMINGR : 0x10c08dcf I2C_TIMEOUTR: 0x00 I2C_ISR : 0x01 I2C_ICR : 0x00 I2C_PECR : 0x00 I2C_RXDR : 0xff I2C_TXDR : 0x00 ------------------------------------------- Data: ff ff ff ff -------------= I2C1 REG dump =------------- I2C_CR1 : 0x01 I2C_CR2 : 0x20404a1 I2C_OAR1 : 0x8000 I2C_OAR2 : 0x00 I2C_TIMINGR : 0x10c08dcf I2C_TIMEOUTR: 0x00 I2C_ISR : 0x01 I2C_ICR : 0x00 I2C_PECR : 0x00 I2C_RXDR : 0xff I2C_TXDR : 0x00 ------------------------------------------- Data: ff ff ff ffwhich doesnt reflect what I have written. I was expecting 0x00, 0x01, 0x02, 0x03
as expected as in:
i2c_wr(0xa0, 0x00, 0x00);
i2c_wr(0xa0, 0x01, 0x01); i2c_wr(0xa0, 0x02, 0x02); i2c_wr(0xa0, 0x03, 0x03);instead of 0xff, 0xff, 0xff, 0xff.
Any thoughts/suggestions ?
Thanks.
#stm32f334-i2c Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-01-20 01:14 AM
In that case it would help if you colud post a part of your code for the communication with the 24c08.
Regards
2018-01-20 03:37 AM
Well i am simply calling
HAL_I2C_Mem_Read(&hi2c1, 0xA0, 1023, I2C_MEMADD_SIZE_16BIT, rData, 1, 1000);�?
0xA0 is device address for 24C I am reading address 1023 in 24C08 and reading into rData, size is 1 and 1000 is timout.
2018-01-20 04:14 AM
What is the exact paart numer of the EEPROM you are using?
Some parts such as Microchip's 24C08B only support WORD addressing.
Regards
2018-01-20 04:27 AM
Ideally, look at SDA and SCL on a scope to understand what's wrong. Sometime the function requires the 7 bit address shifted right 1, do you know if the address is MSB byte first or not? 32kbit=2 kbytes, check if the address is 16 bit or mixed in the slave address. Read the spec of the eeprom carefully.
2018-01-20 04:53 AM
Well i am using Atmel 24C08B and in the data sheet they have mentioned it is 8Kbit which is 1024byte eeprom. So technically i can access 1024 address on eeprom. Well over the internet i have read that HAL routine requires device address as 0x50 << 1 instead of 0xA0. i think that is left aligned ? so how about read will it be 0x51 <<1 or something else.....
2018-01-21 10:29 PM
Hello, Am using STM32F0 uC for interfacing with a AT24C64. I am not able to write sequentially to the EEPROM after one page, i.e 32 Bytes. Can someone please if the logic is wrong.
This is the code:
data[0]=0x00; //First word address 8bit
data[1]=0x00; //Second word address 8bit for(i=2;i<34;i++) { data[i]=0x11; } HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 34, 50); //data is int type,34 is number bytes of data data[0]=0x00; //First word address 8bit data[1]=0x20; //Second word address 8bit// Next Page for(i=2;i<34;i++) { data[i]=0x22; } HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 34, 50); //data is int type,34 is number bytes of data while (1) { /* USER CODE END WHILE */data[0]=0x00;data[1]=0x00;HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 2, 50); //data is int type pointing to first address here for(i=0;i<32;i++) {HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS<<1, &dataout[i], 1, 50);//maximum is 32 byte data locations } data[0]=0x00;data[1]=0x20;HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS<<1, data, 2, 50); //data is int type pointing to first address here for(i=0;i<32;i++) {HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS<<1, &dataout_1[i], 1, 50);//maximum is 32 byte data locations }}
2018-02-22 01:14 AM
Hi, I'm not sure there is a clean answer, yet.
Here is what works for me in mbed:
/* start code */
#define AT24C32_PAGE_SIZE 32
int imin(int a, int b) { return a < b ? a : b; }
bool read_eeprom(int i2c_addr, int address, char *buffer, int len)
{ int lx; char cmd[2]; char mem_addr = (i2c_addr & 0xFE);while ((lx = imin(AT24C32_PAGE_SIZE - (address % AT24C32_PAGE_SIZE),len)) > 0)
{ cmd[0] = ((address & 0x1F00) >> 8); cmd[1] = (address & 0xFF); i2c_bus.write(mem_addr,cmd,2); i2c_bus.read(mem_addr,buffer,lx); address += lx; buffer += lx; len -= lx; } return true;}bool write_eeprom(int i2c_addr, int address, char *source, int len)
{ int lx, i; char cmd[AT24C32_PAGE_SIZE+2]; char mem_addr = (i2c_addr & 0xFE);while ((lx = imin(AT24C32_PAGE_SIZE - (address % AT24C32_PAGE_SIZE),len)) > 0)
{ cmd[0] = ((address & 0x1F00) >> 8); cmd[1] = (address & 0xFF); address += lx; len -= lx; lx += 2; for (i=2;i < lx;i++) {cmd[i] = *source++;} i2c_bus.write(mem_addr,cmd,lx); wait_ms(10); // wait until write cycle is complete } return true;}/* end code*/
And here is how you use these functions:
#define AT24C32_ADR 0xa0
read_eeprom(AT24C32_ADR,20,rtc_buf,sizeof(rtc_buf));
write_eeprom(AT24C32_ADR,40,txt,sizeof(txt));
The functions take care of sequential reads/writes across page boundaries.
Please note: larger EEPROMs like the AT24C32 or the AT24C64 require 2 byte addresses. Smaller ones like the AT24C08 uses 1 byte address. That's why these access functions are not (easily) compatible. See the data sheets for more detail.