基于STM32实现模拟3个I2C口操作2个SHT20和1个DS3231,并通过串口输出数据

基于STM32实现模拟3个I2C口操作2个SHT20和1个DS3231,并通过串口输出数据的解决方案。结合了软件I2C的灵活性和硬件I2C的稳定性,适用于需要多设备通信的场景。

硬件连接

  1. SHT20传感器:假设连接到两个不同的GPIO口组合,分别作为两个I2C总线。

    • SHT20_1:SCL -> PA0, SDA -> PA1
    • SHT20_2:SCL -> PA2, SDA -> PA3
  2. DS3231:使用STM32自带的硬件I2C接口(如I2C1),SCL -> PB6, SDA -> PB7。

软件设计

  1. 软件I2C实现:用于操作两个SHT20传感器。参考实现软件I2C通信,定义两个I2C结构体分别对应两个SHT20。
  2. 硬件I2C实现:用于操作DS3231,使用HAL库配置I2C1。
  3. 串口通信:用于输出数据,配置USART接口。

代码

1. 软件I2C驱动(部分代码)

#include "stm32f1xx_hal.h"

#define IIC_DELAY_TIME 1

typedef struct {
    GPIO_TypeDef* SCL_GPIO;
    uint16_t SCL_Pin;
    GPIO_TypeDef* SDA_GPIO;
    uint16_t SDA_Pin;
} IIC_TypeDef;

void IIC_Init(IIC_TypeDef* iic) {
    // GPIO初始化代码
}

void IIC_Start(IIC_TypeDef* iic) {
    // 软件I2C起始信号
}

void IIC_Stop(IIC_TypeDef* iic) {
    // 软件I2C停止信号
}

void IIC_SendByte(IIC_TypeDef* iic, uint8_t dat) {
    // 发送字节
}

uint8_t IIC_ReadByte(IIC_TypeDef* iic) {
    // 读取字节
    return 0;
}

uint8_t IIC_Sack(IIC_TypeDef* iic) {
    // 等待应答
    return 0;
}

2. SHT20操作函数

#define SHT20_ADDR 0x80

float SHT20_ReadTemperature(IIC_TypeDef* iic) {
    uint8_t cmd = 0xF3;
    IIC_Start(iic);
    IIC_SendByte(iic, SHT20_ADDR);
    IIC_SendByte(iic, cmd);
    IIC_Stop(iic);
    HAL_Delay(85); // 等待测量完成
    IIC_Start(iic);
    IIC_SendByte(iic, SHT20_ADDR | 1); // 读模式
    uint8_t data[2];
    data[0] = IIC_ReadByte(iic);
    IIC_Ack(iic, 1);
    data[1] = IIC_ReadByte(iic);
    IIC_Ack(iic, 0);
    IIC_Stop(iic);
    float temp = -46.85 + 175.72 * (((uint16_t)data[0] << 8) | data[1]) / 65536.0;
    return temp;
}

3. DS3231操作函数

#define DS3231_ADDR 0x68

void DS3231_ReadTime(I2C_HandleTypeDef* hi2c, uint8_t* time) {
    HAL_I2C_Master_Transmit(hi2c, DS3231_ADDR, 0x00, 1, 1000);
    HAL_I2C_Master_Receive(hi2c, DS3231_ADDR, time, 7, 1000);
}

参考代码 stm32 模拟3个IIC口操作2个SHT20和1个DS3231,串口输出数据 youwenfan.com/contenttea/56853.html

4. 主函数

int main(void) {
    HAL_Init();
    // 初始化硬件I2C和USART
    IIC_TypeDef iic1 = {GPIOA, GPIO_PIN_0, GPIOA, GPIO_PIN_1}; // SHT20_1
    IIC_TypeDef iic2 = {GPIOA, GPIO_PIN_2, GPIOA, GPIO_PIN_3}; // SHT20_2
    IIC_Init(&iic1);
    IIC_Init(&iic2);

    I2C_HandleTypeDef hi2c1; // 硬件I2C1
    DS3231_Init(&hi2c1);

    while (1) {
        float temp1 = SHT20_ReadTemperature(&iic1);
        float temp2 = SHT20_ReadTemperature(&iic2);
        uint8_t time[7];
        DS3231_ReadTime(&hi2c1, time);

        // 通过串口输出数据
        printf("SHT20_1 Temp: %.2f C\n", temp1);
        printf("SHT20_2 Temp: %.2f C\n", temp2);
        printf("DS3231 Time: %02d:%02d:%02d\n", time[2], time[1], time[0]);
        HAL_Delay(1000);
    }
}

注意事项

  1. GPIO初始化:确保GPIO的模式和速度配置正确。
  2. I2C设备地址:SHT20和DS3231的I2C地址是固定的,注意不要冲突。
  3. 延时处理:SHT20的测量需要一定时间,确保延时足够。

通过上述代码,可以实现STM32模拟多个I2C口操作多个设备,并通过串口输出数据。

专注于matlab/simulink,电子电路,编程