打印

GD32E230与I2C传感器通信实现

[复制链接]
78|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sj8zw8|  楼主 | 2025-2-23 08:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通过 I2C 协议与温湿度传感器进行通信,是嵌入式系统中常见的操作。
GD32E230 作为一款基于 ARM Cortex-M0+ 的微控制器,具备丰富的外设支持,可以很方便地与 I2C 设备进行通信。
以下是实现与温湿度传感器通信的基本流程,包括配置 I2C 外设、读取数据、处理数据和使用中断优化性能的方式。


配置 I2C 外设
GD32E230 配备了 I2C 外设,首先需要配置 I2C 相关寄存器来启用通信。一般的配置步骤如下:

开启 I2C 时钟:首先需要确保 I2C 外设的时钟已开启。

c
rcu_periph_clock_enable(RCU_I2C0);
配置 I2C 引脚:为 I2C 通信配置适当的引脚,通常是 SCL 和 SDA。GPIO 配置如下:

c
gpio_init(GPIOB, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_PIN_6);  // SCL
gpio_init(GPIOB, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_PIN_7);  // SDA
I2C 参数配置:配置 I2C 工作模式、速率、地址等参数。以 100kHz 的标准模式为例:

c
i2c_deinit(I2C0);
i2c_master_mode(I2C0);
i2c_clock_config(I2C0, 100000);  // 100kHz I2C 时钟
i2c_address_config(I2C0, 0x44, I2C_ADDR_7BIT);  // 设备地址为 0x44
使能 I2C 外设:
c
i2c_enable(I2C0);
与传感器进行通信
接下来,我们需要通过 I2C 向温湿度传感器发送命令,并读取数据。以 SHT30 传感器为例,读取温湿度数据的流程如下:

发送命令:SHT30 传感器需要特定的命令才能开始测量。比如,发送测量命令。

c
uint8_t cmd[] = {0x2C, 0x06};  // 启动测量命令
i2c_master_transmit(I2C0, 0x44, cmd, 2, I2C_SENDING_STOP);  // 发送命令到地址为 0x44 的设备
读取数据:传感器返回的温湿度数据是 6 字节的格式,包括温度和湿度的原始数据。读取数据的过程如下:

c
uint8_t rx_data[6];
i2c_master_receive(I2C0, 0x44, rx_data, 6);
解析数据:解析传感器返回的数据,根据 SHT30 的文档,温度和湿度的原始数据可以通过公式转换为实际值。

c
uint16_t raw_temp = (rx_data[0] << 8) | rx_data[1];
uint16_t raw_humidity = (rx_data[3] << 8) | rx_data[4];
float temperature = -45 + 175 * ((float)raw_temp / 65535);
float humidity = 100 * ((float)raw_humidity / 65535);
使用中断优化性能
为了优化性能,尤其是在传感器数据采集过程中避免阻塞,可以利用 I2C 的中断机制来异步处理数据。

启用中断:在配置 I2C 时,可以使能 I2C 的中断功能,以便在数据传输完成时触发中断。

c
i2c_interrupt_enable(I2C0, I2C_INT_BUF | I2C_INT_EV | I2C_INT_ERR);
中断处理函数:在中断服务例程(ISR)中处理数据的接收。可以根据 I2C 中断状态来判断是否接收完成,或者是否出现错误。

c
void I2C0_EV_IRQHandler(void)
{
    if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)) {
        uint8_t data = i2c_data_receive(I2C0);
        // 处理接收到的数据
    }
    if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) {
        // 数据发送完毕的处理
    }
}
通过中断的方式,可以在 I2C 数据传输过程中进行其他任务的处理,而不需要等待每次数据传输的完成。这种方式可以提高系统的响应速度和并发能力。

完整代码示例
c
#include "gd32e230.h"

#define SENSOR_ADDR 0x44  // SHT30 地址

void i2c_init(void) {
    rcu_periph_clock_enable(RCPU_I2C0);
    gpio_init(GPIOB, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_PIN_6);  // SCL
    gpio_init(GPIOB, GPIO_MODE_AF, GPIO_OSPEED_50MHZ, GPIO_PIN_7);  // SDA
    i2c_deinit(I2C0);
    i2c_master_mode(I2C0);
    i2c_clock_config(I2C0, 100000);  // 100kHz I2C 时钟
    i2c_address_config(I2C0, SENSOR_ADDR, I2C_ADDR_7BIT);
    i2c_enable(I2C0);
    i2c_interrupt_enable(I2C0, I2C_INT_BUF | I2C_INT_EV | I2C_INT_ERR);  // 启用中断
}

void read_sensor(void) {
    uint8_t cmd[] = {0x2C, 0x06};  // 启动测量
    i2c_master_transmit(I2C0, SENSOR_ADDR, cmd, 2, I2C_SENDING_STOP);

    uint8_t rx_data[6];
    i2c_master_receive(I2C0, SENSOR_ADDR, rx_data, 6);

    uint16_t raw_temp = (rx_data[0] << 8) | rx_data[1];
    uint16_t raw_humidity = (rx_data[3] << 8) | rx_data[4];
    float temperature = -45 + 175 * ((float)raw_temp / 65535);
    float humidity = 100 * ((float)raw_humidity / 65535);

    // 处理温湿度数据
}
结论
通过配置 I2C 外设和适当的中断机制,可以实现与 SHT30 或其他 I2C 温湿度传感器的高效通信。使用中断不仅能提高系统的响应能力,还能减少因等待数据传输完成而引起的处理时间浪费,适合高效的实时数据采集。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

324

帖子

1

粉丝