STM32 HAL写入I2C外接EEPROM无ACK响应问题求助
Hey there, let’s troubleshoot this I2C ACK issue with your EEPROM on STM32 HAL step by step. You’ve already ruled out some common gotchas (like swapped SDA/SCL, and confirmed the EEPROM works on Arduino plus another I2C sensor works on STM32), so let’s focus on the specific differences and checks that might be tripping you up:
Double-check I2C clock speed and GPIO drive settings
Arduino’s default I2C speed is usually 100kHz, but if you configured your STM32 for 400kHz fast mode, some older EEPROMs might not keep up. Also, STM32’s internal pull-up resistors are weaker than Arduino’s—if your wiring is long or the EEPROM requires stronger pull-ups, you’ll need to add external 4.7kΩ resistors on both SDA and SCL lines (connected to your board’s VCC).
Try dropping the STM32’s I2C clock speed to 100kHz in your HAL init (look forhi2c.Init.ClockSpeed), and verify your GPIO pins are set to open-drain alternate function mode (GPIO_MODE_AF_OD)—this is mandatory for I2C, as the bus relies on open-drain signaling.Verify the EEPROM’s I2C address format
I2C addresses can be tricky because Arduino uses 8-bit addresses (7-bit device ID + R/W bit), but STM32 HAL expects the 7-bit device ID only (it handles the R/W bit automatically). For example, if you used0xA0in Arduino (which is 7-bit0x50+ write bit0), you should pass0x50as theDevAddressparameter in STM32 HAL functions likeHAL_I2C_Master_Transmit.
Double-check your EEPROM’s datasheet for the address pins (A0/A1/A2) configuration—if you have any of these pins tied to VCC or GND, that changes the 7-bit address. Make sure your calculation matches the physical wiring.Validate GPIO alternate function (AF) assignments
Swapping SDA/SCL is a good first check, but you also need to ensure the pins are mapped to the correct I2C peripheral’s alternate function. For example, on STM32F1, PB6 is I2C1_SCL (AF4) and PB7 is I2C1_SDA (AF4)—if you accidentally assigned them to a different AF (like UART), the I2C signals won’t work.
Use CubeMX (or your HAL config code) to confirm the pins are assigned to the right I2C peripheral’s AF, and that the GPIO mode is set to open-drain with pull-up (or add external pull-ups as mentioned earlier).Debug with signal capture (oscilloscope/logic analyzer)
If the above checks don’t fix it, grab a logic analyzer or oscilloscope to look at the I2C bus signals. Compare the STM32’s output to the working Arduino signals:- Is the start bit being sent correctly?
- Is the address byte matching what you expect?
- Does the EEPROM pull SDA low during the ACK bit slot?
This will tell you if the issue is with the STM32’s signal output, the EEPROM not receiving the signal, or a timing mismatch.
Check HAL initialization and error codes
Don’t skip checking the return values of your HAL functions! For example, after callingHAL_I2C_Init(&hi2c), verify it returnsHAL_OK—if not, there’s an issue with your peripheral configuration. You can also useHAL_I2C_IsDeviceReady(&hi2c, DEV_ADDR, 3, HAL_MAX_DELAY)to test if the EEPROM responds; the return code will tell you if it’s a timeout, error, or success.
内容的提问来源于stack exchange,提问作者KamilWitek

