OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6783|回复: 0

开源一个driver库: 非阻塞模式读取sht20

[复制链接]

44

主题

187

帖子

0

精华

高级会员

Rank: 4

积分
563
金钱
563
注册时间
2016-9-28
在线时间
158 小时
发表于 2022-12-22 21:22:06 | 显示全部楼层 |阅读模式
本帖最后由 mftang2016 于 2022-12-23 19:30 编辑

引子:
自疫情完全放开后,今天问了一下朋友圈里的人,基本上全部沦陷,新冠的攻击能力太强了。最近,本人公司也居家办公居多。今天有时间把之前写的sht20 driver拿出来移植到N32G45XVL-STB开发板上。测试一把,感觉还不错。拿出来分享一下
主要修改特性如下:
1) 优化读取温湿度流程,采用非阻塞模式读数据,有效提高CPU的利用率
2)定义数据结构,存储sht20参数状态

1671343237862.png

8.1 硬件特性

sht20 特性
1671701805985.png

影响编程的参数:
1671702735949.png

转换时间参数,这个参数非常重要,必须等待转换完成后,在读取温湿度值,否则会一直取不到值。
1671702761730.png

命令参数:
1671710010204.png

对应代码实现:
1671710052117.png


8.2 时序分析
如何读数据:
1) Hold master mode
1671711234967.png
2) Unhold master mode
1671711721424.png

8.3  温湿度值转换
温度转换公式:
1671712733218.png
代码实现:
1671712761671.png
湿度转换公式:
1671712788484.png
代码实现:
1671712829880.png

8.4 核心代码实现
gitee 地址:
采用非阻塞方式实现读取温湿度值:

  1. typedef struct {
  2.     uint8_t _step;
  3.     uint8_t ret;
  4.    
  5.     uint8_t finish;     //1: finished, 0: idle
  6.     uint8_t dataValid;  //1: valid, 0: invalid
  7.    
  8.     int32_t _tryCnt;
  9.     int32_t value;
  10.     float outVal;
  11. } shtdrv;

  12. typedef struct {
  13.     shtdrv st_Temp;
  14.     shtdrv st_RH;
  15.     int32_t errorCode;
  16. }shtOpt;
复制代码

核心读取数据函数:
  1. static void sht2xdrv_readVal(uint8_t cmd, shtdrv *pShtdrv )
  2. {
  3.     uint8_t checksum;                   //checksum
  4.     uint8_t data[3] = {0, 0, 0};        //data array for checksum v
  5.     uint8_t cmd_fail = 0;
  6.    
  7.     if(  pShtdrv->finish )
  8.          return;
  9.    
  10.     pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
  11.     switch( pShtdrv->_step )
  12.     {
  13.         default:
  14.         case 0:
  15.             i2c_Start();
  16.             i2c_SendByte( I2C_ADDRESS | I2C_WR );  // Device address
  17.             if (i2c_WaitAck() != 0)
  18.             {
  19.                 cmd_fail = 1;
  20.                 break;
  21.             }
  22.             pShtdrv->_step = 1;
  23.             break;
  24.             
  25.         case 1:
  26.             i2c_SendByte( cmd);
  27.             if (i2c_WaitAck() != 0)
  28.             {
  29.                 cmd_fail = 1;
  30.                 break;
  31.             }
  32.             pShtdrv->_step = 2;
  33.             pShtdrv->_tryCnt = 0;
  34.             break;
  35.             
  36.         case 2:
  37.             i2c_Start();
  38.             i2c_SendByte(I2C_ADDRESS | I2C_RD);
  39.             if (i2c_WaitAck() != 0)
  40.             {
  41.                 pShtdrv->_tryCnt ++;
  42.                 if( pShtdrv->_tryCnt > 10 )
  43.                 {
  44.                     cmd_fail = 1;
  45.                     break;
  46.                 }
  47.             }
  48.             pShtdrv->_step = 3;
  49.             pShtdrv->_tryCnt = 0;
  50.             break;
  51.             
  52.         case 3:
  53.             // Notes: convert time must >= 4 ms
  54.             i2c_Delay( 3 );
  55.             pShtdrv->_tryCnt ++;
  56.             if( pShtdrv->_tryCnt > 4500 )
  57.             {
  58.                 pShtdrv->_tryCnt = 0;
  59.                 pShtdrv->_step = 4;
  60.             }
  61.             break;
  62.         
  63.         case 4:
  64.             data[0] = i2c_ReadByte();
  65.             i2c_Ack();
  66.             
  67.             data[1] = i2c_ReadByte();
  68.             i2c_Ack();
  69.             
  70.             data[2] = i2c_ReadByte();
  71.             i2c_NAck();

  72.             i2c_Stop();
  73.             
  74.             checksum = data[2];
  75.             pShtdrv->ret = sht2xdrv_CheckCrc(data, 2, checksum);
  76.          
  77.             if ( pShtdrv->ret != SHT2x_STATUS_OK)
  78.             {
  79.                 pShtdrv->_step = 2;
  80.                 break;
  81.             }
  82.             
  83.             pShtdrv->value = ((uint16_t)data[0] << 8) | data[1];
  84.             pShtdrv->_step = 0;
  85.             pShtdrv->finish = 1;
  86.             break;
  87.     }
  88.    
  89.     if( cmd_fail )
  90.     {
  91.         pShtdrv->finish = 1;
  92.         pShtdrv->_tryCnt =0;
  93.         pShtdrv->_step = 0;
  94.         pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
  95.         i2c_Stop();
  96.     }
  97. }
复制代码
8. 5 KEIL Debug

1671714342552.png

8.6 逻辑分析仪抓包
1671714481456.png



1671701805985.png
1671714342552.png
1671714481456.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 20:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表