cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Slave not responding

enbw
Associate

Originally tagged-on to this old thread. Split to new thread for better visibility.


Hello,

I seem to have a similar problem, besides, that DMA is disabled.
I have an STM32H503RB (NUCLEO-H503RB) trying to read out some I2C slave devices. It actually works only for one of the devices. This tells me, that the I2C bus is somehow working correctly.
But for the remaining three IC (Temperature, GPIO & ADC), there is no way for me to even send the register address.

Right after the Device address, the communication ends. See the attached file. This is the communication to an MCP9801T temperature sensor (device address [W] = 0x92).

I actually don't understand the reason, why this happens.

f=100kHz

What I did:
- changing pull-ups: same behaviour for 4.7kOhm & 3.0 kOhm
- soldering the device on an otherwise empty PCB: only the 100nF, the pull-ups and the MCP9801T is there.
- I2C-Deinit as well as I2C-Init.
The source code is as simple as that:

 

 

 

while (1)
{
    data[0]=0x00; data[1]=0x01;
    HAL_I2C_Master_Transmit(&hi2c1, Temp_ADDR_W, &data, 2, 10);
    HAL_Delay(1000);
}

 

 

 

Has anyone at least an idea where to look at? Of course, let me know, what information you are missing.
Thank you very much in advance!
Best regards!

STM32H503_MCP9801_2025-01-22.jpg

1 ACCEPTED SOLUTION

Accepted Solutions
enbw
Associate

Who is betting that the mistake is a *** one? :)

This is how I continued:
- I connected the additional sensor, that once was working as a single device without the PCB with the others. It was working.
- so i kept the wiring as much as I could as it is: just adding some cable who forward the signals and power to the PCB: the GPIO, ADC & Temp were responding! Yeah.

Mistake: I mixed up SDA & SCL  and connected them vice versa... :\
Why was the LED-Driver still working? Because I also mixed up these two signals at its pins. Two errors sometimes equal out and create some confusion.

Ok, so I identified it now. Thank you very much for your assistance during the debugging! :)

View solution in original post

5 REPLIES 5
Karl Yamashita
Lead III

The MCP9801 slave address is 0x48

The HAL driver requires you to shift the slave address left by 1. So your value should be (0x48 << 1) = 0x90, not 0x92. The HAL driver takes care of the read bit..

 

#define MCP9801_SLAVE_ADDRESS (0x48 << 1)

HAL_I2C_Master_Transmit(&hi2c1, MCP9801_SLAVE_ADDRESS , &data, 2, 10);

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.
enbw
Associate

Hello Karl,

thank you for your quick reply. Indeed, i missed to mention that fact: Pin A0 of that chip I connected to 3.3V, A1 & A2 to GND. So in my case it is 0x92.
But what I did, just to check address mistakes: I went through all available addresses:
0x00, 0x02, 0x04,..., 0xFC, 0xFE
to see, if any of these addresses would allo to also send the register address byte. But no address did. Except for the working IC.

To give the full picture, what I have on this PCB:
- MCP9801T, Temperature (write address 0x92): failure in transmission
- PCA9554PW, 8ch GPIO (write address 0x4E): failure in transmission
- MCP3427, 2ch ADC (write address 0xD0): failure in transmission
- KTD2052, 4ch RGB-LED driver (write address E8): successful transmission

I have two PCBs with the full set of ICs. Because on both boards the behaviour is the same, I doubt, that I destroyed all 6 ICs with the soldering. I think it sth systematic - which, of course, I don't understand.
Here is the picture of addressing all 4 ICs one after each other:

STM32H503_all4_2025-01-23.jpg

while (1){
    data[0]=0x00;// data[1]=0x01;
    HAL_I2C_Master_Transmit(&hi2c1, GPIO_ADDR_W, &data[0], 1, 10);
    HAL_I2C_Master_Transmit(&hi2c1, ADC_ADDR_W, &data[0], 1, 10);
    HAL_I2C_Master_Transmit(&hi2c1, Temp_ADDR_W, &data[0], 1, 10);
    HAL_I2C_Master_Transmit(&hi2c1, LED_DRV_ADDR_W, &data[0], 1, 10);
    HAL_Delay(1000);
}

This is my I2C configuration:

CubeIDE_I2C-config_2025-01-23.png

Thanks again for your help!

 

But what I did, just to check address mistakes: I went through all available addresses:
0x00, 0x02, 0x04,..., 0xFC, 0xFE

You trying all these different slave address is the wrong approach. You need to read up the I2C protocol. I2C has reserved addresses 0x00-0x07 and 0x78-0x7f

The MCP9801T uses 7 bit address so there is no possible way to have an address greater than 0x7F, so 0x92 is NOT a viable slave address

Your slave address is technically 0x49 based off A0 connected to 3.3V, but you would pass the value (not address) of 0x92 to the HAL driver because you need to shift the slave address 0x49 left by 1.

 

Not sure what you're doing with this? You need a register address and data, so at least 2-3 bytes need to be sent, not 1.

HAL_I2C_Master_Transmit(&hi2c1, Temp_ADDR_W, &data[0], 1, 10);

Since the MCP9801T has registers, so you should be using HAL_I2C_Mem_Write

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.
enbw
Associate

Hello Karl,

sorry for the confusion. When I was talking about the addresses I took the device address and attached the write-bit already. Meaning:
- MCP9801T, Temperature (dev-addr:0x49; full write address 0x92): failure in transmission
- PCA9554PW, 8ch GPIO (dev-addr:0x27; full write address 0x4E): failure in transmission
- MCP3427, 2ch ADC (dev-addr: 0x68; full write address 0xD0): failure in transmission
- KTD2052, 4ch RGB-LED driver (dev-addr: 0x74; full write address E8): successful transmission

So when I was talking about all the addresses, that I was checking, i meant the device addresses 0x00 ... 0x7F plus the write bit=0. I know about the reserved broadcasting addresses, though I wanted to have them tested just for the complete picture.

I have changed HAL_I2C_Master_Transmit now to Mem_write:

uint8_t reg_addr = 0x00;
uint8_t data16[] = {0,0};
while (1){
    HAL_I2C_Mem_Write(&hi2c1,Temp_ADDR_W, &reg_addr,I2C_MEMADD_SIZE_8BIT, data16,2,10);
    HAL_Delay(1000);
}

 The result remains disappointing:

STM32H503_MCP9801_2025-01-23_HAL_MEM_Write.jpg

What I tried additionally:
- changing to 400kHz: no improvement
- changing to 50kHz: no improvement
- adding an I2C sensor that I successfully used in the past with another microcontroller which has Pull-ups of 1kOhm soldered next to it. This sensor cannot be addressed as well. Same picture on the oscilloscope.
- with these 1kOhm-Pull-ups I tried to access the 4 other Slaves: picture unchanged: GPIO, ADC & Temp failed, LED-DRV still possible to send the address byte.

Best regards

enbw
Associate

Who is betting that the mistake is a *** one? :)

This is how I continued:
- I connected the additional sensor, that once was working as a single device without the PCB with the others. It was working.
- so i kept the wiring as much as I could as it is: just adding some cable who forward the signals and power to the PCB: the GPIO, ADC & Temp were responding! Yeah.

Mistake: I mixed up SDA & SCL  and connected them vice versa... :\
Why was the LED-Driver still working? Because I also mixed up these two signals at its pins. Two errors sometimes equal out and create some confusion.

Ok, so I identified it now. Thank you very much for your assistance during the debugging! :)