1469 views|1 replies

250

Posts

5

Resources
The OP
 

[RVB2601 Creative Application Development] Temperature and Humidity Sensor Measurement [Copy link]

 

After receiving it, I started to test its interface functions and found that CDK is very convenient, but it is still troublesome to find the calling relationship. I also found that the packages inside are quite messy. However, it does not affect this test, and it is basically the same as STM32 development.

In this experience, I used the IIC interface, but I used software to simulate the IIC. As shown in the figure below, I removed the jumper cap.

Then the wiring is as shown below:

The power supply on the board is also used.

The next step is to transplant. I use its GUI process, which contains the code for testing the display screen. It is convenient for subsequent use.

It adds two files on its basis.

#include "sht20.h"







#include "oled.h"



IIC_INFO iicInfo;

const int16_t POLYNOMIAL = 0x131;



SHT20_INFO sht20Info;



static void sht20_pinmux_init()

{

 csi_pin_set_mux(PA8, PIN_FUNC_GPIO); //scl

 csi_pin_set_mux(PA9, PIN_FUNC_GPIO); //sda



}



static void sht20_gpio_init()

{

 //

 csi_gpio_pin_init(&pin_scl, PA8);

 csi_gpio_pin_dir(&pin_scl, GPIO_DIRECTION_OUTPUT);

// csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_INPUT);

 csi_gpio_pin_mode(&pin_scl, GPIO_MODE_OPEN_DRAIN);

 csi_gpio_pin_init(&pin_sda, PA9);

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 csi_gpio_pin_mode(&pin_sda, GPIO_MODE_OPEN_DRAIN);



}



/*

************************************************************

* 函数名称: IIC_SpeedCtl

*

* 函数功能: 软件IIC速度控制

*

* 入口参数: speed:延时参数

*

* 返回参数: 无

*

* 说明: 单位:微秒

************************************************************

*/

void IIC_SpeedCtl(unsigned short speed)

{



 iicInfo.speed = speed;



}





/*

************************************************************

* 函数名称: IIC_Start

*

* 函数功能: 软件IIC开始信号

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明:

************************************************************

*/

void IIC_Start(void)

{

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 SDA_H; //拉高SDA线

 SCL_H; //拉高SCL线

 uDelay(iicInfo.speed); //延时,速度控制



 SDA_L; //当SCL线为高时,SDA线一个下降沿代表开始信号

 uDelay(iicInfo.speed); //延时,速度控制

 SCL_L; //钳住SCL线,以便发送数据



}



/*

************************************************************

* 函数名称: IIC_Stop

*

* 函数功能: 软件IIC停止信号

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明:

************************************************************

*/

void IIC_Stop(void)

{

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 SDA_L; //拉低SDA线

 SCL_L; //拉低SCL先

 uDelay(iicInfo.speed); //延时,速度控制



 SCL_H; //拉高SCL线

 SDA_H; //拉高SDA线,当SCL线为高时,SDA线一个上升沿代表停止信号

 uDelay(iicInfo.speed);



}



/*

************************************************************

* 函数名称: IIC_WaitAck

*

* 函数功能: 软件IIC等待应答

*

* 入口参数: timeOut:超时时间

*

* 返回参数: 无

*

* 说明: 单位:微秒

************************************************************

*/

bool IIC_WaitAck(unsigned int timeOut)

{

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_INPUT);

 SDA_H;uDelay(iicInfo.speed); //拉高SDA线

 SCL_H;uDelay(iicInfo.speed); //拉高SCL线

 

 while(SDA_R) //如果读到SDA线为1,则等待。应答信号应是0

 {

 if(--timeOut == 0)

 {

// UsartPrintf(USART1, "WaitAck TimeOut\r\n");



 IIC_Stop(); //超时未收到应答,则停止总线



 return IIC_Err; //返回失败

 }



 uDelay(iicInfo.speed);

 }



 SCL_L; //拉低SCL线,以便继续收发数据



 return IIC_OK; //返回成功



}



/*

************************************************************

* 函数名称: IIC_Ack

*

* 函数功能: 软件IIC产生一个应答

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明: 当SDA线为低时,SCL线一个正脉冲代表发送一个应答信号

************************************************************

*/

void IIC_Ack(void)

{

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 SCL_L; //拉低SCL线

 SDA_L; //拉低SDA线

 uDelay(iicInfo.speed);

 SCL_H; //拉高SCL线

 uDelay(iicInfo.speed);

 SCL_L; //拉低SCL线



}



/*

************************************************************

* 函数名称: IIC_NAck

*

* 函数功能: 软件IIC产生一非个应答

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明: 当SDA线为高时,SCL线一个正脉冲代表发送一个非应答信号

************************************************************

*/

void IIC_NAck(void)

{

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 SCL_L; //拉低SCL线

 SDA_H; //拉高SDA线

 uDelay(iicInfo.speed);

 SCL_H; //拉高SCL线

 uDelay(iicInfo.speed);

 SCL_L; //拉低SCL线



}



/*

************************************************************

* 函数名称: IIC_SendByte

*

* 函数功能: 软件IIC发送一个字节

*

* 入口参数: byte:需要发送的字节

*

* 返回参数: 无

*

* 说明:

************************************************************

*/

void IIC_SendByte(unsigned char byte)

{



 unsigned char count = 0;

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_OUTPUT);

 SCL_L; //拉低时钟开始数据传输



 for(; count < 8; count++) //循环8次,每次发送一个bit

 {

 if(byte & 0x80) //发送最高位

 SDA_H;

 else

 SDA_L;



 byte <<= 1; //byte左移1位



 uDelay(iicInfo.speed);

 SCL_H;

 uDelay(iicInfo.speed);

 SCL_L;

 }



}



/*

************************************************************

* 函数名称: IIC_RecvByte

*

* 函数功能: 软件IIC接收一个字节

*

* 入口参数: 无

*

* 返回参数: 接收到的字节数据

*

* 说明:

************************************************************

*/

unsigned char IIC_RecvByte(void)

{

 unsigned char count = 0, receive = 0;

 csi_gpio_pin_dir(&pin_sda, GPIO_DIRECTION_INPUT);

 SDA_H; //拉高SDA线,开漏状态下,需线拉高以便读取数据



 for(; count < 8; count++ ) //循环8次,每次发送一个bit

 {

 SCL_L;

 uDelay(iicInfo.speed);

 SCL_H;



 receive <<= 1; //左移一位





 if(SDA_R) //如果SDA线为1,则receive变量自增,每次自增都是对bit0的+1,然后下一次循环会先左移一次

 receive++;



 uDelay(iicInfo.speed);

 }



 return receive;



}



/*

************************************************************

* 函数名称: I2C_WriteByte

*

* 函数功能: 软件IIC写一个数据

*

* 入口参数: slaveAddr:从机地址

* regAddr:寄存器地址

* byte:需要写入的数据

*

* 返回参数: 0-写入成功 1-写入失败

*

* 说明: *byte是缓存写入数据的变量的地址,因为有些寄存器只需要控制下寄存器,并不需要写入值

************************************************************

*/

bool I2C_WriteByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *byte)

{



 unsigned char addr = 0;



 addr = slaveAddr << 1; //IIC地址是7bit,这里需要左移1位,bit0:1-读 0-写



 IIC_Start(); //起始信号



 IIC_SendByte(addr); //发送设备地址(写)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_SendByte(regAddr); //发送寄存器地址

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 if(byte)

 {

 IIC_SendByte(*byte); //发送数据

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;

 }



 IIC_Stop(); //停止信号



 return IIC_OK;



}



/*

************************************************************

* 函数名称: I2C_ReadByte

*

* 函数功能: 软件IIC读取一个字节

*

* 入口参数: slaveAddr:从机地址

* regAddr:寄存器地址

* val:需要读取的数据缓存

*

* 返回参数: 0-成功 1-失败

*

* 说明: val是一个缓存变量的地址

************************************************************

*/

bool I2C_ReadByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *val)

{



 unsigned char addr = 0;



 addr = slaveAddr << 1; //IIC地址是7bit,这里需要左移1位,bit0:1-读 0-写



 IIC_Start(); //起始信号



 IIC_SendByte(addr); //发送设备地址(写)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_SendByte(regAddr); //发送寄存器地址

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_Start(); //重启信号



 IIC_SendByte(addr + 1); //发送设备地址(读)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 *val = IIC_RecvByte(); //接收

 IIC_NAck(); //产生一个非应答信号,代表读取接收



 IIC_Stop(); //停止信号



 return IIC_OK;



}



/*

************************************************************

* 函数名称: I2C_WriteBytes

*

* 函数功能: 软件IIC写多个数据

*

* 入口参数: slaveAddr:从机地址

* regAddr:寄存器地址

* buf:需要写入的数据缓存

* num:数据长度

*

* 返回参数: 0-写入成功 1-写入失败

*

* 说明: *buf是一个数组或指向一个缓存区的指针

************************************************************

*/

bool I2C_WriteBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num)

{



 unsigned char addr = 0;



 addr = slaveAddr << 1; //IIC地址是7bit,这里需要左移1位,bit0:1-读 0-写



 IIC_Start(); //起始信号



 IIC_SendByte(addr); //发送设备地址(写)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_SendByte(regAddr); //发送寄存器地址

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 while(num--) //循环写入数据

 {

 IIC_SendByte(*buf); //发送数据

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 buf++; //数据指针偏移到下一个



 uDelay(10);

 }



 IIC_Stop(); //停止信号



 return IIC_OK;



}



/*

************************************************************

* 函数名称: I2C_ReadBytes

*

* 函数功能: 软件IIC读多个数据

*

* 入口参数: slaveAddr:从机地址

* regAddr:寄存器地址

* buf:需要读取的数据缓存

* num:数据长度

*

* 返回参数: 0-写入成功 1-写入失败

*

* 说明: *buf是一个数组或指向一个缓存区的指针

************************************************************

*/

bool I2C_ReadBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num)

{



 unsigned short addr = 0;



 addr = slaveAddr << 1; //IIC地址是7bit,这里需要左移1位,bit0:1-读 0-写



 IIC_Start(); //起始信号



 IIC_SendByte(addr); //发送设备地址(写)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_SendByte(regAddr); //发送寄存器地址

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 IIC_Start(); //重启信号



 IIC_SendByte(addr + 1); //发送设备地址(读)

 if(IIC_WaitAck(5000)) //等待应答

 return IIC_Err;



 while(num--)

 {

 *buf = IIC_RecvByte();

 buf++; //偏移到下一个数据存储地址



 if(num == 0)

 {

 IIC_NAck(); //最后一个数据需要回NOACK

 }

 else

 {

 IIC_Ack(); //回应ACK

 }

 }



 IIC_Stop();



 return IIC_OK;



}











/*

************************************************************

* 函数名称: SHT20_reset

*

* 函数功能: SHT20复位

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明:

************************************************************

*/

void SHT20_reset(void)

{



 I2C_WriteByte(SHT20_ADDRESS, SHT20_SOFT_RESET, (void *)0);



}



/*

************************************************************

* 函数名称: SHT20_read_user_reg

*

* 函数功能: SHT20读取用户寄存器

*

* 入口参数: 无

*

* 返回参数: 读取到的用户寄存器的值

*

* 说明:

************************************************************

*/

unsigned char SHT20_read_user_reg(void)

{



 unsigned char val = 0;



 I2C_ReadByte(SHT20_ADDRESS, SHT20_READ_REG, &val);



 return val;



}



/*

************************************************************

* 函数名称: SHT2x_CheckCrc

*

* 函数功能: 检查数据正确性

*

* 入口参数: data:读取到的数据

* nbrOfBytes:需要校验的数量

* checksum:读取到的校对比验值

*

* 返回参数: 校验结果

*

* 说明: 0-成功 1-失败

************************************************************

*/

char SHT2x_CheckCrc(char data[], char nbrOfBytes, char checksum)

{



 char crc = 0;

 char bit = 0;

 char byteCtr = 0;



 //calculates 8-Bit checksum with given polynomial

 for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)

 {

 crc ^= (data[byteCtr]);

 for ( bit = 8; bit > 0; --bit)

 {

 if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;

 else crc = (crc << 1);

 }

 }



 if(crc != checksum)

 return 1;

 else

 return 0;



}



/*

************************************************************

* 函数名称: SHT2x_CalcTemperatureC

*

* 函数功能: 温度计算

*

* 入口参数: u16sT:读取到的温度原始数据

*

* 返回参数: 计算后的温度数据

*

* 说明:

************************************************************

*/

float SHT2x_CalcTemperatureC(unsigned short u16sT)

{



 float temperatureC = 0; // variable for result



 u16sT &= ~0x0003; // clear bits [1..0] (status bits)

 //-- calculate temperature [癈] --

 temperatureC = -46.85 + 175.72 / 65536 * (float)u16sT; //T= -46.85 + 175.72 * ST/2^16



 return temperatureC;



}



/*

************************************************************

* 函数名称: SHT2x_CalcRH

*

* 函数功能: 湿度计算

*

* 入口参数: u16sRH:读取到的湿度原始数据

*

* 返回参数: 计算后的湿度数据

*

* 说明:

************************************************************

*/

float SHT2x_CalcRH(unsigned short u16sRH)

{



 float humidityRH = 0; // variable for result



 u16sRH &= ~0x0003; // clear bits [1..0] (status bits)

 //-- calculate relative humidity [%RH] --

 //humidityRH = -6.0 + 125.0/65536 * (float)u16sRH; // RH= -6 + 125 * SRH/2^16

 humidityRH = ((float)u16sRH * 0.00190735) - 6;



 return humidityRH;



}



/*

************************************************************

* 函数名称: SHT2x_MeasureHM

*

* 函数功能: 测量温湿度

*

* 入口参数: cmd:测量温度还是湿度

* pMeasurand:不为空则保存为ushort值到此地址

*

* 返回参数: 测量结果

*

* 说明:

************************************************************

*/

 char data[2]; //data array for checksum verification

float SHT2x_MeasureHM(unsigned char cmd, unsigned short *pMeasurand)

{



 char checksum = 0; //checksum



 unsigned char addr = 0;

 unsigned short tmp = 0;

 float t = 0;



 addr = SHT20_ADDRESS << 1;



 IIC_Start();



 IIC_SendByte(addr);

 if(IIC_WaitAck(50000)) //等待应答

 return 0.0;



 IIC_SendByte(cmd);

 if(IIC_WaitAck(50000)) //等待应答

 return 0.0;



 IIC_Start();



 IIC_SendByte(addr + 1);

 while(IIC_WaitAck(50000)) //等待应答

 {

 IIC_Start();

 IIC_SendByte(addr + 1);

 }



 Delay(70);



 data[0] = IIC_RecvByte();

 IIC_Ack();

 data[1] = IIC_RecvByte();

 IIC_Ack();



 checksum = IIC_RecvByte();

 IIC_NAck();



 IIC_Stop();



 SHT2x_CheckCrc(data, 2, checksum);

 tmp = (data[0] << 8) + data[1];

 if(cmd == SHT20_Measurement_T_HM)

 {

 t = SHT2x_CalcTemperatureC(tmp);

 }

 else

 {

 t = SHT2x_CalcRH(tmp);

 }



 if(pMeasurand)

 {

 *pMeasurand = (unsigned short)t;

 }



 return t;



}

void SHT20_Init(void)

{



 sht20_pinmux_init();

 sht20_gpio_init();



}

/*

************************************************************

* 函数名称: SHT20_GetValue

*

* 函数功能: 获取温湿度数据

*

* 入口参数: 无

*

* 返回参数: 无

*

* 说明: 温湿度结果保存在SHT20结构体里

************************************************************

*/

void SHT20_GetValue(void)

{



 unsigned char val = 0;







 IIC_SpeedCtl(5);



 SHT20_read_user_reg();

 uDelay(100);



 sht20Info.tempreture = SHT2x_MeasureHM(SHT20_Measurement_T_HM, (void *)0);

 Delay(70);



 sht20Info.humidity = SHT2x_MeasureHM(SHT20_Measurement_RH_HM, (void *)0);

 Delay(25);



 SHT20_read_user_reg();

 Delay(25);



 I2C_WriteByte(SHT20_ADDRESS, SHT20_WRITE_REG, &val);

 uDelay(100);



 SHT20_read_user_reg();

 uDelay(100);



 SHT20_reset();

 uDelay(100);



 printf("sht20Info.tempreture:%f\r\n",sht20Info.tempreture);

 printf("sht20Info.humidity:%f\r\n",sht20Info.humidity);

}

The code is attached here directly, and the C file is above.


#ifndef sht20_H

#define sht20_H



#include <drv/gpio_pin.h>

#include <drv/pin.h>





csi_gpio_pin_t pin_scl;

csi_gpio_pin_t pin_sda;





//SDA PB11

//SCL PB10

#define SDA_H csi_gpio_pin_write(&pin_sda, GPIO_PIN_HIGH)

#define SDA_L csi_gpio_pin_write(&pin_sda, GPIO_PIN_LOW)

#define SDA_R csi_gpio_pin_read(&pin_sda)



#define SCL_H csi_gpio_pin_write(&pin_scl, GPIO_PIN_HIGH)

#define SCL_L csi_gpio_pin_write(&pin_scl, GPIO_PIN_LOW)





#define IIC_OK 0

#define IIC_Err 1





typedef struct

{



 unsigned short speed;



} IIC_INFO;



//extern IIC_INFO iicInfo;





/*SHT20 设备操作相关宏定义,详见手册*/

#define SHT20_ADDRESS 0X40

#define SHT20_Measurement_RH_HM 0XE5

#define SHT20_Measurement_T_HM 0XE3

#define SHT20_Measurement_RH_NHM 0XF5

#define SHT20_Measurement_T_NHM 0XF3

#define SHT20_READ_REG 0XE7

#define SHT20_WRITE_REG 0XE6

#define SHT20_SOFT_RESET 0XFE







typedef struct

{



 float tempreture;

 float humidity;



} SHT20_INFO;



extern SHT20_INFO sht20Info;







void IIC_Init(void);



void IIC_SpeedCtl(unsigned short speed);



bool I2C_WriteByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *byte);



bool I2C_ReadByte(unsigned char slaveAddr, unsigned char regAddr, unsigned char *val);



bool I2C_WriteBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num);



bool I2C_ReadBytes(unsigned char slaveAddr, unsigned char regAddr, unsigned char *buf, unsigned char num);



void IIC_Start(void);



void IIC_Stop(void);



bool IIC_WaitAck(unsigned int timeOut);



void IIC_Ack(void);



void IIC_NAck(void);



void IIC_SendByte(unsigned char byte);



unsigned char IIC_RecvByte(void);













void SHT20_Init(void);



void SHT20_GetValue(void);







#endif

This is the header file.

This is an OS system, so a new task is needed to read the sensor value.

The actual effect is as shown in the figure, and the data can be read directly.

Latest reply

The following code can be pasted into the code box of the edit box, and the effect is good for everyone to see   Details Published on 2022-4-3 11:10
 
 

6593

Posts

0

Resources
2
 

The following code can be pasted into the code box of the edit box, and the effect is good for everyone to see

 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list