You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32执行阶段能否修改I2C从设备地址?如何实现?

动态修改STM32 I2C从地址的可行方案(Nucleo-F207GZ适用)

直接修改OwnAddress1后调用HAL_I2C_Init或先DeInit再Init无效的核心原因是:HAL_I2C_Init在从模式下不会重新配置地址寄存器,而DeInit可能重置过多外设状态导致后续初始化异常。正确的做法是直接操作I2C地址寄存器,步骤如下:

操作步骤

  1. 停止当前I2C从模式操作
    如果使用中断监听模式,先关闭监听中断:

    HAL_I2C_DisableListen_IT(&hi2cX);
    

    若启用了DMA,需同步停止DMA传输:

    HAL_DMA_Abort(&hdma_i2cX_rx);
    HAL_DMA_Abort(&hdma_i2cX_tx);
    
  2. 禁用I2C外设
    修改地址寄存器前必须先禁用外设,否则硬件不允许写入:

    __HAL_I2C_DISABLE(&hi2cX);
    
  3. 更新句柄中的地址配置
    根据地址类型(7位/10位)修改OwnAddress1,比如7位地址需左移1位(匹配HAL库的寄存器配置规则):

    hi2cX.Init.OwnAddress1 = (new_7bit_addr << 1);
    hi2cX.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // 明确地址模式
    
  4. 重新配置I2C地址寄存器
    调用HAL库专门的地址配置函数,直接更新硬件寄存器:

    HAL_I2C_SetOwnAddressConfig(&hi2cX, &hi2cX.Init);
    
  5. 重新启用I2C外设

    __HAL_I2C_ENABLE(&hi2cX);
    
  6. 恢复从模式操作
    重新开启监听中断或DMA传输,恢复设备的从模式响应能力:

    HAL_I2C_EnableListen_IT(&hi2cX);
    // 若用DMA,重新启动接收/传输
    HAL_I2C_Slave_Receive_DMA(&hi2cX, rx_buf, buf_len);
    

代码示例(中断模式下处理地址修改指令)

假设在I2C从接收完成回调中处理地址修改指令:

uint8_t rx_buf[2]; // rx_buf[0]为触发指令,rx_buf[1]为新7位地址
uint8_t tx_buf[1]; // 用于发送修改确认

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    if(hi2c->Instance == I2C1)
    {
        // 匹配特定修改地址指令
        if(rx_buf[0] == 0xAA)
        {
            uint8_t new_addr = rx_buf[1];
            
            // 停止当前监听
            HAL_I2C_DisableListen_IT(hi2c);
            // 禁用I2C外设
            __HAL_I2C_DISABLE(hi2c);
            
            // 更新地址配置
            hi2c->Init.OwnAddress1 = (new_addr << 1);
            hi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
            // 重新配置地址寄存器
            HAL_I2C_SetOwnAddressConfig(hi2c, &hi2c->Init);
            
            // 重新启用外设并恢复监听
            __HAL_I2C_ENABLE(hi2c);
            HAL_I2C_EnableListen_IT(hi2c);
            
            // 发送修改成功确认
            tx_buf[0] = 0x01;
            HAL_I2C_Slave_Transmit_IT(hi2c, tx_buf, 1);
        }
        else
        {
            // 处理其他指令,重新开启接收
            HAL_I2C_Slave_Receive_IT(hi2c, rx_buf, 2);
        }
    }
}

注意事项

  • 确保修改地址时I2C总线处于空闲状态,避免总线冲突导致修改失败。
  • 新地址不能与总线上其他设备地址重复,否则会引发通信异常。
  • 若使用10位地址,需将AddressingMode改为I2C_ADDRESSINGMODE_10BIT,OwnAddress1直接填写10位地址值。

内容的提问来源于stack exchange,提问作者grybouilli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:47:09