[STM32F1] STM32F103 的 I2C 问题

[复制链接]
 楼主| 我的牙白 发表于 2025-5-25 10:00 | 显示全部楼层 |阅读模式
本帖最后由 我的牙白 于 2025-7-29 22:49 编辑

STM32F103带一个 4x20 LCD,需要两个 PWM 开关,以及一个 Si5351A 的 I2C 接口和几个外部中断。测试 LCD 的接口;没问题,测试两个 PWM;同样没问题,
但 I2C 接口无法工作。SDA 和 SCL 在示波器上没有显示波形
对 HAL_I2C_Master_Transmit() 的调用只返回一个HAL_BUSY。
查看生成的代码,发现 MX_GPIO_Init() 例程没有 I2C  io口的任何配置;
程序如下
static void MX_GPIO_Init(void){  GPIO_InitTypeDef GPIO_InitStruct = {0};   /* GPIO Ports Clock Enable */  __HAL_RCC_GPIOC_CLK_ENABLE();  __HAL_RCC_GPIOD_CLK_ENABLE();  __HAL_RCC_GPIOA_CLK_ENABLE();  __HAL_RCC_GPIOB_CLK_ENABLE();   /*Configure GPIO pin Output Level */  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);   /*Configure GPIO pin Output Level */  HAL_GPIO_WritePin(GPIOB, D2_Pin|D3_Pin|E_Pin|RS_Pin                           |D0_Pin|D1_Pin, GPIO_PIN_RESET);   /*Configure GPIO pin : LD2_Pin */  GPIO_InitStruct.Pin = LD2_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pins : D2_Pin D3_Pin E_Pin RS_Pin                            D0_Pin D1_Pin */  GPIO_InitStruct.Pin = D2_Pin|D3_Pin|E_Pin|RS_Pin                           |D0_Pin|D1_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); }static void MX_I2C1_Init(void){   /* USER CODE BEGIN I2C1_Init 0 */   /* USER CODE END I2C1_Init 0 */   /* USER CODE BEGIN I2C1_Init 1 */   /* USER CODE END I2C1_Init 1 */  hi2c1.Instance = I2C1;  hi2c1.Init.ClockSpeed = 100000;  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;  hi2c1.Init.OwnAddress1 = 0;  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;  hi2c1.Init.OwnAddress2 = 0;  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;  if (HAL_I2C_Init(&hi2c1) != HAL_OK)  {    Error_Handler();  }   /* USER CODE BEGIN I2C1_Init 2 */   /* USER CODE END I2C1_Init 2 */ }

公羊子丹 发表于 2025-5-27 07:40 | 显示全部楼层
看起来你没通过 CubeMX 给 I2C 配 GPIO,建议回到 .ioc 文件中重新勾选 I2C1 的引脚,再生成代码试试。
周半梅 发表于 2025-5-27 07:41 | 显示全部楼层
HAL_I2C_Master_Transmit() 一直返回 HAL_BUSY,很多时候是因为 SDA/SCL 没配置成复用功能(AF),建议手动检查下寄存器。
帛灿灿 发表于 2025-5-27 07:42 | 显示全部楼层
可以在 MX_I2C1_Init() 之后手动调用 __HAL_AFIO_REMAP_I2C1_ENABLE() 看看有没有效果,有些 F1 芯片需要显式重映射。
童雨竹 发表于 2025-5-27 07:43 | 显示全部楼层
看下 SDA/SCL 引脚有没有接上拉电阻?F103 的 I2C 是开漏输出,需要外部上拉才有波形。
万图 发表于 2025-5-27 07:43 | 显示全部楼层
建议在 MX_GPIO_Init() 中打印一下 GPIOB 的 MODER/AFR 设置,看看是不是默认成普通输出了。
Wordsworth 发表于 2025-5-27 07:44 | 显示全部楼层
我之前遇到类似情况,是因为 LCD 占用了 I2C 的 GPIO 引脚,检查下你的 LCD 接口有没有跟 I2C 重叠。
Bblythe 发表于 2025-5-27 07:45 | 显示全部楼层
如果用的是 PB6/PB7,注意它们默认功能是 I2C1 的 SCL/SDA,但有些开发板预接了别的模块,冲突了。
Pulitzer 发表于 2025-5-27 07:45 | 显示全部楼层
你可以尝试用 STM32CubeMX 生成一个最小工程,只启用 I2C,然后拿逻辑分析仪看下是否能产生起始条件。
Uriah 发表于 2025-5-27 07:46 | 显示全部楼层
HAL_BUSY 有时是因为 I2C 总线挂死了,可以加个 HAL_I2C_DeInit() 再 HAL_I2C_Init() 的软复位试试看。
Clyde011 发表于 2025-5-27 07:47 | 显示全部楼层
如果这些都不行,就直接用软件模拟 I2C 做个测试,确认是不是硬件 I2C模块或者 GPIO 初始化没配好。
t60yz 发表于 2025-5-31 23:42 | 显示全部楼层
配置好GPIO后,重新测试SCL、SDA波形是否有时钟和数据。
t60yz 发表于 2025-5-31 23:42 | 显示全部楼层
HAL层I2C函数返回BUSY一般是总线忙或者状态机没重置,没正常发起传输。GPIO配置是根本原因。
小迷糊仙 发表于 2025-6-4 12:25 | 显示全部楼层
感谢分享 学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

40

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

40

主题

40

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部