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

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

为了实现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/

    你可能感兴趣的文章
    Nginx 反向代理解决跨域问题
    查看>>
    Nginx 反向代理配置去除前缀
    查看>>
    nginx 后端获取真实ip
    查看>>
    Nginx 多端口配置和访问异常问题的排查与优化
    查看>>
    Nginx 如何代理转发传递真实 ip 地址?
    查看>>
    Nginx 学习总结(16)—— 动静分离、压缩、缓存、黑白名单、性能等内容温习
    查看>>
    Nginx 学习总结(17)—— 8 个免费开源 Nginx 管理系统,轻松管理 Nginx 站点配置
    查看>>
    Nginx 学习(一):Nginx 下载和启动
    查看>>
    nginx 常用指令配置总结
    查看>>
    Nginx 常用配置清单
    查看>>
    nginx 常用配置记录
    查看>>
    nginx 开启ssl模块 [emerg] the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx
    查看>>
    Nginx 我们必须知道的那些事
    查看>>
    Nginx 的 proxy_pass 使用简介
    查看>>
    Nginx 的配置文件中的 keepalive 介绍
    查看>>
    Nginx 结合 consul 实现动态负载均衡
    查看>>
    Nginx 负载均衡与权重配置解析
    查看>>
    Nginx 负载均衡详解
    查看>>
    nginx 配置 单页面应用的解决方案
    查看>>
    nginx 配置https(一)—— 自签名证书
    查看>>