STM32
直播中

英雄孤寂

13年用户 1280经验值
私信 关注
[问答]

STM32G070 I2C主机只发送设备地址读测试是否产生stop位?

程序主机配置NBYTES为0,AUTOEND为自动结束模式,发起读,抓波形发现不会产生stop位,是什么原因?
调用的函数是:
if (HAL_I2C_Master_Receive_IT(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t *)aRxBuffer, 0) != HAL_OK)
{
Error_Handler();
}

回帖(1)

gvxiaot

2025-8-20 17:01:30

在STM32G070的I2C主机模式下,当您使用HAL_I2C_Master_Receive_IT函数进行读操作并设置接收长度为0时,不会生成STOP条件。以下是原因分析和解决方案:




根本原因




  1. HAL库函数限制:



    • HAL_I2C_Master_Receive_IT函数内部会对传输长度(Size)进行校验。当Size = 0时,函数会直接返回HAL_ERROR(不会启动传输)。

    • 您的代码中调用了Error_Handler(),说明传输未被真正执行,I2C总线无任何操作。




  2. 硬件行为 (AUTOEND模式):



    • 即使忽略HAL库限制强行设置NBYTES=0并启动传输,STM32G070的硬件设计也不会为0字节传输生成STOP条件。

    • 根据STM32G070参考手册(RM0454),在AUTOEND模式下:

      • STOP条件仅在NBYTES > 0且传输完成后生成。

      • NBYTES=0会被视为无效配置,硬件可能忽略请求或产生错误标志。







解决方案


方案1:改用 HAL_I2C_Mem_Read_IT 函数(推荐)


通过寄存器读取操作模拟0字节读,并强制STOP:


// 设置DeviceAddress, MemAddress, MemAddSize
// 设置Size=0并启用AUTOEND
if (HAL_I2C_Mem_Read_IT(&hi2c1, I2C_ADDRESS, 0, I2C_MEMADD_SIZE_8BIT, aRxBuffer, 0) != HAL_OK) {
    Error_Handler();
}

优点:此函数允许Size=0并在地址发送后生成STOP。


方案2:底层寄存器配置


直接操作寄存器强制生成STOP:


// 发送START条件
hi2c1.Instance->CR2 |= I2C_CR2_START;
while (!(hi2c1.Instance->ISR & I2C_ISR_TXIS)); // 等待地址发送

// 发送设备地址(读方向)
hi2c1.Instance->TXDR = (I2C_ADDRESS << 1) | 0x01;
while (!(hi2c1.Instance->ISR & I2C_ISR_TC));   // 等待传输完成

// 立即生成STOP
hi2c1.Instance->CR2 |= I2C_CR2_STOP;

注意:需确保总线空闲(BUSY=0)。


方案3:使用软件复位(应急)


生成STOP后复位I2C外设:


hi2c1.Instance->CR1 |= I2C_CR1_SWRST;  // 复位I2C
hi2c1.Instance->CR1 &= ~I2C_CR1_SWRST; // 退出复位
HAL_I2C_Init(&hi2c1);                  // 重新初始化

风险:可能导致总线状态不一致,慎用。




关键配置验证



  1. AUTOEND模式
    确保CR2寄存器中AUTOEND=1(默认启用):
    hi2c1.Instance->CR2 |= I2C_CR2_AUTOEND;

  2. NBYTES设置
    即使传输0字节,也要确保NBYTES字段不为0(如设为1后取消传输)。




波形分析建议



  1. 预期波形
    S (Start) | SLA+R (Addr) | P (Stop)

  2. 调试步骤

    • 检查HAL_I2C_Master_Receive_IT返回值,确认是否跳过传输。

    • 用逻辑分析仪捕获总线,观察START是否出现(若无,说明传输未启动)。





总结



  • 根本原因:HAL库拒绝0字节传输 + 硬件不支持NBYTES=0生成STOP。

  • 解决方案:改用HAL_I2C_Mem_Read_IT或手动控制STOP位。

  • 配置要点:确保AUTOEND启用,避免无效的NBYTES=0设置。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分