博客
关于我
小熊派GD32开发(7)— 使用软件模拟I2C读取SHT30温湿度传感器
阅读量:554 次
发布时间:2019-03-09

本文共 4372 字,大约阅读时间需要 14 分钟。

为了实现GD32开发板上使用软件模拟I2C读取SHT30温湿度传感器的功能,我们需要编写相应的驱动程序和应用程序。以下是详细的步骤说明:

一、编写软件模拟I2C驱动程序

  • 初始化I2C引脚

    • soft_i2c.c文件中,初始化I2C总线的时钟和数据线。
    void IIC_Init(void) {    rcu_periph_clock_enable(RCU_GPIOB);  // 启用GPIOB时钟    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);  // PB6(IIC_SCL)设置为推挽输出    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);  // PB7(IIC_SDA)设置为推挽输出    gpio_bit_set(GPIOB, GPIO_PIN_6);  // 确保SCL引脚拉高    gpio_bit_set(GPIOB, GPIO_PIN_7);  // 确保SDA引脚拉高}
  • 编写us延时函数

    void delay_us(uint32_t nus) {    uint32_t ticks;    uint32_t told, tnow, tcnt = 0;    uint32_t reload = SysTick->LOAD;  // 滴答定时器的重装载值    ticks = nus * 120;  // 转换为对定时器节拍的计算    told = SysTick->VAL;  // 刚进入函数时的计数器值    while (1) {        tnow = SysTick->VAL;        if (tnow != told) {            if (tnow < told) {                tcnt += told - tnow;            } else {                tcnt += reload - tnow + told;            }            if (tcnt >= ticks) break;            told = tnow;        }    }}
  • 实现I2C通信函数

    • 启动I2C总线
    void IIC_Start(void) {    SDA_OUT();  // SDA引脚输出    IIC_SDA(1);  // SDA拉高    IIC_SCL(1);  // SCL拉高    delay_us(4);  // 等待SCL和SDA稳定    IIC_SDA(0);  // SDA拉低    delay_us(4);  // 等待SCL和SDA稳定    IIC_SCL(0);  // SCL拉低}
    • 结束I2C总线
    void IIC_Stop(void) {    SDA_OUT();  // SDA引脚输出    IIC_SCL(0);  // SCL拉低    IIC_SDA(0);  // SDA拉低    delay_us(4);  // 等待SCL和SDA稳定    IIC_SCL(1);  // SCL拉高    delay_us(4);  // 等待SCL和SDA稳定    IIC_SDA(1);  // SDA拉高    delay_us(4);  // 等待SCL和SDA稳定}
    • 发送ACK和NACK
    void IIC_ACK(void) {    SDA_OUT();    IIC_SCL(0);    delay_us(2);    IIC_SDA(0);    delay_us(2);    IIC_SCL(1);    delay_us(2);    IIC_SCL(0);    delay_us(1);}
    void IIC_NACK(void) {    SDA_OUT();    IIC_SCL(0);    delay_us(2);    IIC_SDA(1);    delay_us(2);    IIC_SCL(1);    delay_us(2);    IIC_SCL(0);    delay_us(1);}
    • 接收并处理ACK
    uint8_t IIC_wait_ACK(void) {    uint8_t t = 200;    SDA_OUT();    IIC_SDA(1);    delay_us(1);    IIC_SCL(0);    delay_us(1);    SDA_IN();  // 释放数据线    delay_us(1);    while (READ_SDA) {        t--;        delay_us(1);        if (t == 0) {            IIC_SCL(0);            return 1;        }        delay_us(1);    }    delay_us(1);    IIC_SCL(1);    delay_us(1);    IIC_SCL(0);    delay_us(1);    return 0;}
    • 发送和接收一个字节数据
    void IIC_SendByte(uint8_t byte) {    uint8_t BitCnt;    SDA_OUT();    IIC_SCL(0);    for (BitCnt = 0; BitCnt < 8; BitCnt++) {        if ((byte & 0x80) != 0) {            IIC_SDA(1);        } else {            IIC_SDA(0);        }        byte <<= 1;        delay_us(2);        IIC_SCL(1);        delay_us(2);        IIC_SCL(0);        delay_us(2);    }}
    uint8_t IIC_RcvByte(void) {    uint8_t retc = 0;    uint8_t BitCnt;    SDA_IN();    delay_us(1);    for (BitCnt = 0; BitCnt < 8; BitCnt++) {        IIC_SCL(0);        delay_us(2);        IIC_SCL(1);        retc = retc << 1;        if (READ_SDA) {            retc |= 1;        }        delay_us(1);    }    IIC_SCL(0);    return retc;}
  • 二、编写SHT30应用程序

  • 初始化SHT30传感器

    uint8_t SHT3x_Init(void) {    // 初始化传感器地址和其他配置    return 0;}
  • 读取传感器编号

    uint8_t SHT3x_ReadSerialNumber(uint32_t* serialNumber) {    // 发送读取传感器编号命令并接收数据    return 0;}
  • 单次读取温湿度数据

    uint8_t SHT3x_Get_Humiture_single(double* Tem_val, double* Hum_val) {    // 发送测量命令并接收数据    return 0;}
  • 周期读取温湿度数据

    uint8_t SHT3x_Get_Humiture_periodic(double* Tem_val, double* Hum_val) {    // 设置为周期读取模式并读取数据    return 0;}
  • 数据校验函数

    uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value) {    // CRC8校验    return 0;}
  • 三、集成到主程序并上传到云端

  • 主函数初始化
    int main(void) {    // 初始化系统时钟、UART、I2C等    systick_config();    LED_init();    uart_init(115200);    // 其他初始化    printf("Hello world! \r\n");    while (NB_Start()) {        // 处理NBIoT模块的通信    }    // 初始化SHT30传感器    if (0 == SHT3x_Init()) {        printf("SHT3x_Init OK \r\n");    } else {        printf("SHT3x_Init ERR \r\n");    }    // 设置定时任务读取温湿度数据    while (1) {        if (update_flag == 1) {            update_flag = 0;            // 采集数据并上传到EMQ            if (SHT3x_Get_Humiture_periodic(&Tem_val, &Hum_val) == 0) {                // 生成数据包并发送                // ...            } else {                printf("Get_Humiture ERR\r\n");            }        }        // 处理NBIoT模块的收数据    }}
  • 四、注意事项

    • 延时函数:确保延时函数准确无误,避免I2C通信错误。
    • 数据校验:在接收数据时进行CRC校验,确保数据完整性。
    • 错误处理:增加错误处理逻辑,确保系统稳定运行。
    • 定时任务:在多任务环境中,确保定时任务的正确执行。
    • 云端通信:验证NBIoT模块的通信配置,确保数据能成功上传。

    通过以上步骤,可以实现使用软件模拟I2C读取SHT30温湿度传感器的功能,并将数据上传到云端,完成一个完整的开发流程。

    转载地址:http://qtqsz.baihongyu.com/

    你可能感兴趣的文章
    Postman高阶技能:Collection集合批量运行!
    查看>>
    postMessage跨标签页共享数据
    查看>>
    QImage对一般图像的处理
    查看>>
    post为什么会发送两次请求?
    查看>>
    Post表单提交TextArea的值出现转译乱码问题 - Spring MVC处理表单提交
    查看>>
    Power BI 中的 Python 可视化需要什么设置?任何特定的 matplotlib 包版本或系统设置?
    查看>>
    Power BI:如何在 Power Query 编辑器中将 Python 与多个表一起使用?
    查看>>
    power english (3) main text -emotion mastery - focus
    查看>>
    POWER ENGLISH (6) - MODEL
    查看>>
    power english (1) —— passion
    查看>>
    Power English (1) 原文
    查看>>
    power English (3)原文
    查看>>
    POWER ENGLISH(7)- repetition
    查看>>
    SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
    查看>>
    powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
    查看>>
    QGIS怎样设置简体中文以及新建可编辑的多边形的图层
    查看>>
    PowerBuilder 使用自定义事件触发键盘Enter事件
    查看>>
    PowerCreatorCMS UploadResourcePic 任意文件上传漏洞复现
    查看>>
    PowerDesigner 使用的一些技巧(转)
    查看>>
    QGIS在Windows上下载安装与建立空间数据库连接
    查看>>