本帖最后由 mftang2016 于 2022-12-23 19:30 编辑
引子:自疫情完全放开后,今天问了一下朋友圈里的人,基本上全部沦陷,新冠的攻击能力太强了。最近,本人公司也居家办公居多。今天有时间把之前写的sht20 driver拿出来移植到N32G45XVL-STB开发板上。测试一把,感觉还不错。拿出来分享一下 主要修改特性如下: 1) 优化读取温湿度流程,采用非阻塞模式读数据,有效提高CPU的利用率 2)定义数据结构,存储sht20参数状态
8.1 硬件特性
sht20 特性
影响编程的参数:
转换时间参数,这个参数非常重要,必须等待转换完成后,在读取温湿度值,否则会一直取不到值。
命令参数:
对应代码实现:
8.2 时序分析如何读数据: 1) Hold master mode 2) Unhold master mode
8.3 温湿度值转换温度转换公式: 代码实现: 湿度转换公式: 代码实现:
8.4 核心代码实现gitee 地址: 采用非阻塞方式实现读取温湿度值:
- typedef struct {
- uint8_t _step;
- uint8_t ret;
-
- uint8_t finish; //1: finished, 0: idle
- uint8_t dataValid; //1: valid, 0: invalid
-
- int32_t _tryCnt;
- int32_t value;
- float outVal;
- } shtdrv;
- typedef struct {
- shtdrv st_Temp;
- shtdrv st_RH;
- int32_t errorCode;
- }shtOpt;
复制代码
核心读取数据函数: - static void sht2xdrv_readVal(uint8_t cmd, shtdrv *pShtdrv )
- {
- uint8_t checksum; //checksum
- uint8_t data[3] = {0, 0, 0}; //data array for checksum v
- uint8_t cmd_fail = 0;
-
- if( pShtdrv->finish )
- return;
-
- pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
- switch( pShtdrv->_step )
- {
- default:
- case 0:
- i2c_Start();
- i2c_SendByte( I2C_ADDRESS | I2C_WR ); // Device address
- if (i2c_WaitAck() != 0)
- {
- cmd_fail = 1;
- break;
- }
- pShtdrv->_step = 1;
- break;
-
- case 1:
- i2c_SendByte( cmd);
- if (i2c_WaitAck() != 0)
- {
- cmd_fail = 1;
- break;
- }
- pShtdrv->_step = 2;
- pShtdrv->_tryCnt = 0;
- break;
-
- case 2:
- i2c_Start();
- i2c_SendByte(I2C_ADDRESS | I2C_RD);
- if (i2c_WaitAck() != 0)
- {
- pShtdrv->_tryCnt ++;
- if( pShtdrv->_tryCnt > 10 )
- {
- cmd_fail = 1;
- break;
- }
- }
- pShtdrv->_step = 3;
- pShtdrv->_tryCnt = 0;
- break;
-
- case 3:
- // Notes: convert time must >= 4 ms
- i2c_Delay( 3 );
- pShtdrv->_tryCnt ++;
- if( pShtdrv->_tryCnt > 4500 )
- {
- pShtdrv->_tryCnt = 0;
- pShtdrv->_step = 4;
- }
- break;
-
- case 4:
- data[0] = i2c_ReadByte();
- i2c_Ack();
-
- data[1] = i2c_ReadByte();
- i2c_Ack();
-
- data[2] = i2c_ReadByte();
- i2c_NAck();
- i2c_Stop();
-
- checksum = data[2];
- pShtdrv->ret = sht2xdrv_CheckCrc(data, 2, checksum);
-
- if ( pShtdrv->ret != SHT2x_STATUS_OK)
- {
- pShtdrv->_step = 2;
- break;
- }
-
- pShtdrv->value = ((uint16_t)data[0] << 8) | data[1];
- pShtdrv->_step = 0;
- pShtdrv->finish = 1;
- break;
- }
-
- if( cmd_fail )
- {
- pShtdrv->finish = 1;
- pShtdrv->_tryCnt =0;
- pShtdrv->_step = 0;
- pShtdrv->ret = SHT2x_STATUS_ERR_BAD_DATA;
- i2c_Stop();
- }
- }
复制代码 8. 5 KEIL Debug
8.6 逻辑分析仪抓包
|