1595|1

250

帖子

5

TA的资源

纯净的硅(初级)

楼主
 

【平头哥RVB2601创意应用开发】温湿度传感器测量 [复制链接]

 

 

收到之后,我开始测试其接口功能,发现CDK方便是很方便,但是就是找调用关系还是比较麻烦的,目前也发现里面的包比较混乱。不过不影响本次测试,基本上还是和STM32开发是基本相同的。

本次体验我使用的是其IIC接口,但是使用的是软件模拟IIC的方式。如下图,我把跳帽给去掉了。

 

然后接线实物如下图:

 

同时也使用了板子上的供电。

接下来就是移植了,我使用其GUI历程,也就是里面有测试显示屏的代码了。方便后续使用。

 

就是在其基础上增加了两个文件。

#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);

}

这里直接附上代码,上面是C文件。


#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

这个是头文件。

 

本次是一个OS系统,所以要新增一个任务用来读取传感器值。

 

实际效果如图,可以直接读出数据了。

最新回复

后面的代码可以贴到编辑框的代码框内,大家看的效果好   详情 回复 发表于 2022-4-3 11:10
点赞 关注
 
 

回复
举报

6628

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

后面的代码可以贴到编辑框的代码框内,大家看的效果好

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表