GD32F103配置I2C
时间: 2025-04-30 12:40:59 浏览: 37
### 关于GD32F103微控制器I2C接口配置
#### 配置概述
GD32F103系列微控制器支持硬件I2C外设,同时也可通过软件实现模拟I2C功能。对于某些特定应用场合(如驱动TLC59116),可能需要通过GPIO模拟I2C协议来完成通信[^1]。
以下是基于GD32F103的I2C配置方法及相关示例代码:
---
#### 硬件I2C配置
如果使用硬件I2C模块,则需初始化相应的寄存器并设置波特率、地址模式等参数。以下是一个典型的硬件I2C初始化流程:
```c
#include "gd32f10x.h"
void i2c_hardware_init(void) {
// 使能I2C时钟
rcu_periph_clock_enable(RCU_I2C1);
// GPIO配置为复用推挽模式
gpio_mode_set(GPIOB, GPIO_MODE_AFOD, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_6 | GPIO_PIN_7);
// 初始化I2C
i2c_deinit(I2C1); // 复位I2C外设
i2c_struct_para_init(&i2c_init_struct); // 结构体清零
i2c_init_struct.i2c_analog_filter = I2C_ANALOG_FILTER_ENABLE;
i2c_init_struct.i2c_digital_filter = 0;
i2c_init_struct.i2c_ack = I2C_ACK_ENABLE; // 开启应答
i2c_init_struct.i2c_own_address1 = 0xA0; // 主设备无需设置自己的地址
i2c_init_struct.i2c_timing = 0x10A11E89; // 设置时序参数 (具体值取决于频率)
i2c_init(I2C1, &i2c_init_struct);
// 启用I2C
i2c_enable(I2C1);
}
```
上述代码实现了硬件I2C的基本初始化过程,其中`i2c_timing`参数需要根据实际系统时钟计算得出。
---
#### 软件模拟I2C配置
当无法使用硬件I2C或目标芯片不兼容标准I2C协议时,可以通过GPIO模拟I2C信号。以下是一个简单的模拟I2C发送数据的例子:
```c
#define SDA_PIN GPIO_PIN_0
#define SCL_PIN GPIO_PIN_1
#define I2C_PORT GPIOA
// 延迟函数
void delay_us(uint32_t us) {
for (; us > 0; us--);
}
// 控制SDA电平
void sda_out(int level) {
if(level){
gpio_bit_set(I2C_PORT, SDA_PIN);
}else{
gpio_bit_reset(I2C_PORT, SDA_PIN);
}
}
// 控制SCL电平
void scl_out(int level) {
if(level){
gpio_bit_set(I2C_PORT, SCL_PIN);
}else{
gpio_bit_reset(I2C_PORT, SCL_PIN);
}
}
// 发送起始条件
void i2c_start() {
sda_out(1);
scl_out(1);
delay_us(5);
sda_out(0);
delay_us(5);
scl_out(0);
}
// 发送停止条件
void i2c_stop() {
sda_out(0);
delay_us(5);
scl_out(1);
delay_us(5);
sda_out(1);
}
// 发送一字节数据
uint8_t i2c_send_byte(uint8_t data) {
uint8_t ack;
for(int i=0;i<8;i++) {
if(data & 0x80){
sda_out(1);
}else{
sda_out(0);
}
data <<= 1;
delay_us(5);
scl_out(1);
delay_us(5);
scl_out(0);
}
// 获取ACK
sda_out(1);
scl_out(1);
delay_us(5);
ack = gpio_input_bit_get(I2C_PORT, SDA_PIN);
scl_out(0);
return ack;
}
```
此代码片段展示了如何利用GPIO引脚手动控制I2C总线上的START、STOP以及字节传输操作。
---
#### 中断处理与外部事件触发
在一些应用场景下,可能还需要结合外部中断EXTI机制来优化程序逻辑。例如,在接收到从设备响应后触发后续动作。相关内容可参考如下链接中的说明[^2]:
- EXTI及NVIC简介;
- 如何编写针对指定引脚的中断服务例程(ISR)。
---
### 总结
无论是采用硬件还是软件方式实现I2C通讯,都需要仔细规划资源分配,并确保所有涉及的时间延迟满足规范要求。此外,建议测试过程中逐步增加复杂度以验证每一步骤的功能正确性。
阅读全文
相关推荐



















