STM32F030x I2C从设备意外响应双地址的问题排查求助
问题
开发简易切换器项目时,配置STM32F030x的I2C从机通信,初始化后设备会响应两个地址:头文件中配置的合法地址0x10,以及未配置的0x40。未开启双地址模式或配置第二个从机地址,移除多路复用器后问题仍存在,如何让设备仅响应指定单个地址?
初始化代码如下:
void i2c_Initialization() { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_InitTypeDef i2c; GPIO_InitTypeDef port; NVIC_InitTypeDef nvic; port.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; port.GPIO_Speed = GPIO_Speed_50MHz; port.GPIO_Mode = GPIO_Mode_AF; port.GPIO_PuPd = GPIO_PuPd_NOPULL; port.GPIO_OType = GPIO_OType_OD; GPIO_Init(GPIOB, &port); GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); nvic.NVIC_IRQChannel = I2C1_IRQn; nvic.NVIC_IRQChannelPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); //I2C_DeInit(I2C1); I2C_Cmd(I2C1, DISABLE); I2C_StructInit(&i2c); i2c.I2C_Mode = I2C_Mode_I2C; i2c.I2C_OwnAddress1 = (I2C_SLAVE_ADDR) << 1; i2c.I2C_SlaveAddressConfig = I2C_SLAVE_ADDR <<1; i2c.I2C_Timing = (0xB << I2C_OFFSET_TIMINGR_PRESC)| (0x13 << I2C_OFFSET_TIMINGR_SCLL)| (0xF << I2C_OFFSET_TIMINGR_SCLH)| (0x4 << I2C_OFFSET_TIMINGR_SCLDEL)| (0x2 << I2C_OFFSET_TIMINGR_SDADEL); i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //I2C_ITConfig(I2C_IT_TCI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI, ENABLE); I2C_ITConfig(I2C1, I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_STOPI, ENABLE); I2C_Init(I2C1, &i2c); I2C_Cmd(I2C1, ENABLE); //while ((I2C1->CR1 & I2C_CR1_PE)==0) {}; }
排查与解决方法
- 移除错误的结构体赋值:代码中
i2c.I2C_SlaveAddressConfig = I2C_SLAVE_ADDR <<1;是错误用法。STM32F0标准库的I2C_InitTypeDef结构体没有I2C_SlaveAddressConfig成员,它是一个独立的库函数I2C_SlaveAddressConfig(),仅用于双地址模式下配置第二个从地址。直接给不存在的结构体成员赋值会导致内存非法覆盖,破坏I2C配置参数,引发异常地址响应,删除这一行即可。 - 复位I2C外设:取消注释
I2C_DeInit(I2C1);,在配置前先复位I2C外设,清除硬件中残留的错误配置,确保初始化从干净状态开始。 - 验证地址配置:确认
I2C_SLAVE_ADDR宏定义确实为0x10,且I2C_OwnAddress1的左移操作正确(7位地址需左移1位,因为STM32的地址寄存器包含读写位)。 - 检查中断处理逻辑:查看
I2C1_IRQHandler函数,确保在地址匹配中断(ADDRI)触发时,检查实际匹配的地址是否为0x10<<1,若不是则不发送ACK,避免误响应非法地址。
内容的提问来源于stack exchange,提问作者Damir Mustafin
相关产品推荐
相关产品推荐

