STM32F103 的 I2C 问题
本帖最后由 我的牙白 于 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() 例程没有 I2Cio口的任何配置;
程序如下
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 */ }
看起来你没通过 CubeMX 给 I2C 配 GPIO,建议回到 .ioc 文件中重新勾选 I2C1 的引脚,再生成代码试试。 HAL_I2C_Master_Transmit() 一直返回 HAL_BUSY,很多时候是因为 SDA/SCL 没配置成复用功能(AF),建议手动检查下寄存器。 可以在 MX_I2C1_Init() 之后手动调用 __HAL_AFIO_REMAP_I2C1_ENABLE() 看看有没有效果,有些 F1 芯片需要显式重映射。 看下 SDA/SCL 引脚有没有接上拉电阻?F103 的 I2C 是开漏输出,需要外部上拉才有波形。 建议在 MX_GPIO_Init() 中打印一下 GPIOB 的 MODER/AFR 设置,看看是不是默认成普通输出了。 我之前遇到类似情况,是因为 LCD 占用了 I2C 的 GPIO 引脚,检查下你的 LCD 接口有没有跟 I2C 重叠。 如果用的是 PB6/PB7,注意它们默认功能是 I2C1 的 SCL/SDA,但有些开发板预接了别的模块,冲突了。 你可以尝试用 STM32CubeMX 生成一个最小工程,只启用 I2C,然后拿逻辑分析仪看下是否能产生起始条件。 HAL_BUSY 有时是因为 I2C 总线挂死了,可以加个 HAL_I2C_DeInit() 再 HAL_I2C_Init() 的软复位试试看。 如果这些都不行,就直接用软件模拟 I2C 做个测试,确认是不是硬件 I2C模块或者 GPIO 初始化没配好。 配置好GPIO后,重新测试SCL、SDA波形是否有时钟和数据。 HAL层I2C函数返回BUSY一般是总线忙或者状态机没重置,没正常发起传输。GPIO配置是根本原因。 感谢分享 学习了
页:
[1]