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

STM32F030F4裸机环境下I2C1无法正常启动问题求助(附代码)

解决STM32F030F4 I2C1 SDA无法正常工作的问题

我帮你排查了代码里的几个关键问题,这些大概率是导致SDA端口异常的核心原因,咱们一步步来修正:

1. 最关键的错误:外设时钟未正确使能

你的RCC配置完全没打开GPIOA和I2C1的时钟,这会导致这两个外设完全无法工作:

  • GPIOA时钟:RCC->AHBENR = 0x200000; 这个值对应的是DMA1的时钟位(bit21),而GPIOA的时钟使能位是AHBENR的bit17,对应值为0x00020000(即1 << 17)。
  • I2C1时钟:RCC->APB1ENR = 0x4040; 这个值开启的是USART2和SPI2的时钟,I2C1的时钟使能位是APB1ENR的bit21,对应值为0x2000000(即1 << 21)。

建议用|=操作来置位时钟位,避免直接赋值关闭其他外设的时钟,修正后的RCC配置:

// 开启GPIOA时钟
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
// 开启I2C1时钟
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;

(如果你的开发环境没有定义RCC_AHBENR_GPIOAEN这些宏,直接用数值也可以:RCC->AHBENR |= 0x00020000; 和 RCC->APB1ENR |= 0x2000000;)

2. I2C配置的潜在问题

(1)CR2寄存器的FREQ字段需匹配总线时钟

I2C1->CR2 = 0x307001c; 里的FREQ字段(CR2的bit5~bit0)设置为0x30,对应48MHz的APB1总线时钟。你需要确保你的系统时钟配置确实让APB1运行在48MHz,否则TIMINGR的时序参数会不匹配,导致I2C通信时序错误。

(2)TXDR赋值超出寄存器范围

I2C1->TXDR = 0x111; 中,TXDR是8位寄存器,0x111是9位数据,会被自动截断为0x11。如果你要发送的是8位数据,请改为8位值,比如0x11。

(3)标准的I2C主发送流程

你的启动流程有点简略,正确的主模式发送步骤应该是:

// 设置从机地址(7位地址的话,SADD是地址左移1位,写模式末位为0)
I2C1->CR2 = (0x1C << 1); // 对应你原来的0x1c,这里假设是7位地址写模式
// 设置要发送的字节数
I2C1->CR2 |= (7 << 16); // NBYTES=7,对应你原来的0x7
// 启动传输
I2C1->CR2 |= I2C_CR2_START;
// 等待发送中断标志,然后发送数据
while(!(I2C1->ISR & I2C_ISR_TXIS)){}
I2C1->TXDR = 0x11; // 改为8位数据
// 后续循环发送剩余字节,直到传输完成

3. 其他验证点

  • 确认你的I2C总线上接了合适的上拉电阻(一般是4.7kΩ~10kΩ),STM32内部上下拉可能不足以驱动总线;
  • 用示波器观察SCL和SDA引脚的波形,先确认时钟使能后GPIO是否有电平变化,再检查I2C启动后的时序是否符合标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:28:08