历史上的今天
返回首页

历史上的今天

今天是:2025年10月13日(星期一)

正在发生

2022年10月13日 | STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)

2022-10-13 来源:csdn

一、环境介绍

工程编译软件:  keil5


温湿度传感器: SHT30


MCU : STM32F103ZET6


程序采用模块化编程,iic时序为一个模块(iic.c 和 iic.h),SHT30为一个模块(sht30.c 和 sht30.h);IIC时序采用模拟时序方式实现,IO口都采用宏定义方式,方便快速移植到其他平台使用。


工程源码完整下载地址: https://download.csdn.net/download/xiaolong1126626497/18973724


二、SHT30介绍

特点:


1. 湿度和温度传感器

2. 完全校准、线性化和温度

3. 补偿数字输出,宽电源电压范围,从2.4 V到5.5 V

4. I2C接口,通信速度高达1MHz和两个用户可选地址

5. 典型精度 +- 2%相对湿度和+- 0.3°C

6. 启动和测量时间非常快

7. 微型8针DFN封装

这是SHT30的7位IIC设备地址:   

三、设备运行效果

这是串口打印的数据:

 

四、设备代码

4.1  main.c

#include "stm32f10x.h"

#include "led.h"

#include "delay.h"

#include "key.h"

#include "usart.h"

#include "iic.h"

#include "sht3x.h"

 

int main()

{

   float Humidity;

   float Temperature;

   USART1_Init(115200);

   USART1_Printf("设备运行正常....rn");

   IIC_Init(); 

   Init_SHT30();

   while(1)

   {

       //读取温湿度

       SHT3x_ReadData(&Humidity,&Temperature);

       USART1_Printf("温度:%0.2f,湿度:%0.2frn",Temperature,Humidity);

       delay_ms(1000);

   }

}


4.2 sht30.c

#include "sht3x.h"

 

const int16_t POLYNOMIAL = 0x131;

 

/***************************************************************

* 函数名称: SHT30_reset

* 说    明: SHT30复位

* 参    数: 无

* 返 回 值: 无

***************************************************************/

void SHT30_reset(void)

{

    u8 r_s;

    

    IIC_Start(); //发送起始信号

    

    IIC_WriteOneByteData(SHT30_AddrW); //写设备地址

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:1rn");

 

    IIC_WriteOneByteData(0x30); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:2rn");

    

    IIC_WriteOneByteData(0xA2); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:3rn");

    

    IIC_Stop(); //停止信号 

 

    delay_ms(50);    

}

 

 

/***************************************************************

* 函数名称: Init_SHT30

* 说    明: 初始化SHT30,设置测量周期

* 参    数: 无

* 返 回 值: 无

***************************************************************/

void Init_SHT30(void)

{

     u8 r_s;

    

    IIC_Start(); //发送起始信号

    

    IIC_WriteOneByteData(SHT30_AddrW); //写设备地址

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:1rn");

 

    IIC_WriteOneByteData(0x22); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:2rn");

    

    IIC_WriteOneByteData(0x36); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("Init_SHT30_error:3rn");

    

    IIC_Stop(); //停止信号  

    

    delay_ms(200);

}

 

 

/***************************************************************

* 函数名称: SHT3x_CheckCrc

* 说    明: 检查数据正确性

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

nbrOfBytes:需要校验的数量

checksum:读取到的校对比验值

* 返 回 值: 校验结果,0-成功 1-失败

***************************************************************/

u8 SHT3x_CheckCrc(char data[], char nbrOfBytes, char checksum)

{

    char crc = 0xFF;

    char bit = 0;

    char byteCtr ;

    //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;

}

 

/***************************************************************

* 函数名称: SHT3x_CalcTemperatureC

* 说    明: 温度计算

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

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

***************************************************************/

float SHT3x_CalcTemperatureC(unsigned short u16sT)

{

    float temperatureC = 0;            // variable for result

 

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

    //-- calculate temperature [℃] --

    temperatureC = (175 * (float)u16sT / 65535 - 45); //T = -45 + 175 * rawValue / (2^16-1)

    return temperatureC;

}

 

/***************************************************************

* 函数名称: SHT3x_CalcRH

* 说    明: 湿度计算

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

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

***************************************************************/

float SHT3x_CalcRH(unsigned short u16sRH)

{

    float humidityRH = 0;              // variable for result

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

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

    humidityRH = (100 * (float)u16sRH / 65535);  // RH = rawValue / (2^16-1) * 10

    return humidityRH;

}

 

 

//读取温湿度数据

void SHT3x_ReadData(float *Humidity,float *Temperature)

{

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

    u8 SHT3X_Data_Buffer[6]; //byte 0,1 is temperature byte 4,5 is humidity

    u8 r_s=0;

    u8 i;

    unsigned short tmp = 0;

    uint16_t dat;

    

    IIC_Start(); //发送起始信号

    

    IIC_WriteOneByteData(SHT30_AddrW); //写设备地址

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("SHT3X_error:1rn");

 

    IIC_WriteOneByteData(0xE0); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("SHT3X_error:2rn");

    

    IIC_WriteOneByteData(0x00); //写数据

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("SHT3X_error:3rn");

    

    //IIC_Stop(); //停止信号 

    

   // DelayMs(30); //等待

    

    //读取sht30传感器数据

    IIC_Start(); //发送起始信号

    IIC_WriteOneByteData(SHT30_AddrR);

    r_s=IIC_GetACK();//获取应答

    if(r_s)printf("SHT3X_error:7rn");

    

    for(i=0;i<6;i++)

    {

        SHT3X_Data_Buffer[i]=IIC_ReadOneByteData(); //接收数据

        if(i==5)

        {

             IIC_SendACK(1); //发送非应答信号

            break;

        }

        IIC_SendACK(0); //发送应答信号

    }

    IIC_Stop(); //停止信号

    

    //    /* check tem */

    data[0] = SHT3X_Data_Buffer[0];

    data[1] = SHT3X_Data_Buffer[1];

    data[2] = SHT3X_Data_Buffer[2];

 

    tmp=SHT3x_CheckCrc(data, 2, data[2]);

    if( !tmp ) /* value is ture */

    {

        dat = ((uint16_t)data[0] << 8) | data[1];

        *Temperature = SHT3x_CalcTemperatureC( dat );    

    }

 

    //    /* check humidity */

    data[0] = SHT3X_Data_Buffer[3];

    data[1] = SHT3X_Data_Buffer[4];

    data[2] = SHT3X_Data_Buffer[5];

 

    tmp=SHT3x_CheckCrc(data, 2, data[2]);

    if( !tmp ) /* value is ture */

    {

        dat = ((uint16_t)data[0] << 8) | data[1];

        *Humidity = SHT3x_CalcRH( dat );    

    }

}

 


4.3 iic.c

#include "iic.h"

 

/*

函数功能:IIC接口初始化

硬件连接:

SDA:PB7

SCL:PB6

*/

void IIC_Init(void)

{

RCC->APB2ENR|=1<<3;//PB

GPIOB->CRL&=0x00FFFFFF;

GPIOB->CRL|=0x33000000;

GPIOB->ODR|=0x3<<6;

}

 

/*

函数功能:IIC总线起始信号

*/

void IIC_Start(void)

{

    IIC_SDA_OUTMODE(); //初始化SDA为输出模式

    IIC_SDA_OUT=1; //数据线拉高

    IIC_SCL=1;      //时钟线拉高

    DelayUs(4);        //电平保持时间

    IIC_SDA_OUT=0; //数据线拉低

    DelayUs(4);        //电平保持时间

    IIC_SCL=0;      //时钟线拉低

}

 

 

/*

函数功能:IIC总线停止信号

*/

void IIC_Stop(void)

{

IIC_SDA_OUTMODE(); //初始化SDA为输出模式

IIC_SDA_OUT=0; //数据线拉低

IIC_SCL=0;      //时钟线拉低

DelayUs(4);        //电平保持时间

IIC_SCL=1;      //时钟线拉高

DelayUs(4);        //电平保持时间

IIC_SDA_OUT=1; //数据线拉高

}

 

/*

函数功能:获取应答信号

返 回 值:1表示失败,0表示成功

*/

u8 IIC_GetACK(void)

{

u8 cnt=0;

IIC_SDA_INPUTMODE();//初始化SDA为输入模式

IIC_SDA_OUT=1;   //数据线上拉

  DelayUs(2);         //电平保持时间

IIC_SCL=0;        //时钟线拉低,告诉从机,主机需要数据

DelayUs(2);         //电平保持时间,等待从机发送数据

  IIC_SCL=1;        //时钟线拉高,告诉从机,主机现在开始读取数据

while(IIC_SDA_IN)   //等待从机应答信号

{

cnt++;

if(cnt>250)return 1;

}

IIC_SCL=0;        //时钟线拉低,告诉从机,主机需要数据

return 0;

}

 

/*

函数功能:主机向从机发送应答信号

函数形参:0表示应答,1表示非应答

*/

void IIC_SendACK(u8 stat)

{

IIC_SDA_OUTMODE(); //初始化SDA为输出模式

IIC_SCL=0;      //时钟线拉低,告诉从机,主机需要发送数据

if(stat)IIC_SDA_OUT=1; //数据线拉高,发送非应答信号

else IIC_SDA_OUT=0; //数据线拉低,发送应答信号

DelayUs(2);            //电平保持时间,等待时钟线稳定

IIC_SCL=1;           //时钟线拉高,告诉从机,主机数据发送完毕

推荐阅读

史海拾趣

绿索超容(GreenSource)公司的发展小趣事

汇顶科技(GOODiX)公司发展的五个故事

故事一:初创与转型

汇顶科技的故事始于2002年,当时它作为一家初创企业,在电子产业中崭露头角。公司最初专注于固定电话芯片业务,但随着国内固话市场的饱和和竞争加剧,公司迅速调整方向,切入小家电触控面板芯片领域。这一转型为公司后续的发展奠定了基础。2010年,汇顶科技获得联发科技的战略投资,其触控芯片集成至联发科技的安卓系统解决方案中,广泛应用于智能手机和平板电脑等电子产品,进一步提升了公司的市场地位。

故事二:指纹识别技术的突破

2013年,随着苹果iPhone 5s发布并搭载电容式指纹识别技术,全球范围内掀起了一股指纹识别风潮。汇顶科技敏锐地捕捉到了这一市场趋势,开始研发指纹识别芯片。经过一年的努力,公司在2014年成功推出电容式指纹识别芯片,并凭借创新技术迅速获得国内主流智能机厂商的订单。此后,汇顶科技在指纹识别领域不断取得突破,逐步成为全球最大的指纹识别芯片厂商之一。

故事三:屏下指纹识别技术的开拓者

在指纹识别技术取得成功后,汇顶科技并未满足现状,而是继续探索新技术。2016年,公司开始以屏下指纹识别技术(光学式指纹芯片)为新的主攻方向。经过一年的研发,2017年汇顶科技率先展出全球首款屏下指纹识别技术,成为该领域的开拓者。随着全面屏手机的兴起,屏下指纹识别技术迅速得到市场认可,汇顶科技也借此迎来了新一轮的增长。

故事四:多元化布局与并购

为了进一步提升竞争力,汇顶科技通过并购等方式不断拓展业务领域。2018年,公司收购德国蜂窝半导体IP企业CommSoild,进军窄带物联网领域(NB-IoT)。2020年,汇顶科技又收购恩智浦半导体的语音及音频业务单元(NXP Voice & Audio Solutions)和德国汽车电子公司Dream Chip Technologies,分别增强智能终端音频解决方案能力和进入车规级芯片领域。这些并购不仅丰富了公司的产品线,也提升了公司在各领域的综合竞争力。

故事五:持续创新与合作

汇顶科技一直致力于技术创新和市场拓展。近年来,公司与多家知名手机厂商建立了合作关系,为其提供创新的指纹识别和触控芯片解决方案。例如,汇顶科技的创新方案组合助力小米、荣耀、iQOO等品牌的旗舰新品打造极致体验。同时,公司还不断拓展物联网领域的应用,通过构建芯片设计和软硬件产品技术综合物联网平台,推动智能化生活的实现。这些合作和创新不仅提升了公司的市场影响力,也为全球亿万消费者带来了更便捷、智能的体验。

柯爱亚(ceaiya)公司的发展小趣事

柯爱亚一直秉承“持续改进,满足客户要求,不断创新,超越客户期望”的品质方针。公司严格把控产品质量,从原材料采购到生产流程,再到产品检测,每一个环节都力求精益求精。这种对品质的坚持赢得了客户的信任,柯爱亚的产品逐渐在市场上树立了良好的口碑。

Block USA Inc.公司的发展小趣事

在成功推出线下支付业务后,Block USA Inc.进一步拓展至线上支付领域,并推出了集成了多种功能的手机软件Cash App。这款应用不仅提供了便捷的支付功能,还整合了robinhood、paypal和venmo等金融服务的特色,为用户提供了更加丰富的金融体验。Cash App的成功推出,使得Block在支付与金融服务领域的影响力进一步增强。

Global Communications公司的发展小趣事
温度传感器的输出与温度之间的线性关系可能不理想,导致补偿效果不准确。此时,可以采用非线性补偿技术或选择具有更好线性度的温度传感器来解决问题。
静芯微电子(ElecSuper)公司的发展小趣事

静芯微电子深知产品质量对于企业的重要性,因此建立了完善的质量管理体系。公司从原材料采购、生产制造到产品检测等各个环节都实行严格的质量控制和管理,确保每一款产品都符合高标准的质量要求。同时,静芯微电子还引进了先进的检测设备和技术手段,对产品质量进行全面检测和评估。这些措施保证了静芯微电子产品的稳定性和可靠性,赢得了客户的信任和好评。

AIC [Analog Intergrations Corporation]公司的发展小趣事

静芯微电子(ElecSuper)成立于XXXX年,由一群富有远见和热情的电子工程师共同创立。公司从一开始就专注于ESD(静电放电)/TVS(瞬态电压抑制器)系列器件的研发,致力于为客户提供高质量的静电保护和电压稳定解决方案。通过不断的技术创新和产品优化,静芯微电子逐渐在ESD/TVS领域取得了突破,并积累了大量的客户基础。

问答坊 | AI 解惑

[#_#]你也能拿高薪!

非常有参考价值的一本书啊!…

查看全部问答>

年薪10万男难寻嵌入式软件开发人才

2007年9月1日,在南京召开的“2007中国软件产业发展暨企业创新高峰会”上传出信息,今年上半年全国软件产业实现销售收入2601亿元,增长23%,高于电子信息产业18%的增长水平,而其中嵌入式软件增长24%,高于软件产业的增长水平。同时据赛迪顾问研究 ...…

查看全部问答>

请教通讯线上的高压问题

在监控线路上通讯线了时常被高压损坏是什么原因阿,主要损坏通讯芯片,基本上芯片会被击穿…

查看全部问答>

请各位大侠们帮助,新装的WIN CE 5.0编译出现Invalid parameters passed to Wince.bat问题,怎么解决呀!急死人了,帮帮

小弟刚接触WIN CE ,刚装的WIN CE5.0安装后,新建工程编译出现Invalid parameters passed to Wince.bat问题,而且左边没有 OSDesign View标签.开始安装时因为有文件有2部分,WIN CE文件没有放在同一目录下,之后我将文件移动到了同一目录下,开始以 ...…

查看全部问答>

位置传感器有人用过不?

目前有哪些类型的位置传感器啊? 有人有实践经验不?…

查看全部问答>

to版主,STM32F107的以太网PHY能使用DM9161AEP吗?

                                 to 版主,STM32F107的以太网PHY能使用DM9161AEP吗?…

查看全部问答>

烂C-SPY,设不了断点...

在C-SPY,中设断点时, 总出现: Error[130]:"some breakpoint could not be set", 不论在那条语句上设都设不了。 ???????????????? 比其它51系列或者96系列的仿真器来说,C-SPY 的调试简直就是地狱!!!…

查看全部问答>

ulink2 如何给板子供电啊?需要怎么设置啊

本帖最后由 paulhyde 于 2014-9-15 03:48 编辑 ulink2 如何给arm板子供电啊?需要怎么设置啊 请问有人知道吗?求教啊  …

查看全部问答>

关于LM3S8962的I2C读取honeywell传感器实验

honeywell新一代的传感器很多是I2C输出。 手头有两个气体流量传感器,于是想在EK-LM3S8962开发板上测试一下。   程序参考周立功的I2C读取LM75A例程,以及本版面的经验贴:https://bbs.eeworld.com.cn/viewthread.php?tid=231364 honeywell ...…

查看全部问答>

codewarrior 警告C1420

codewarrior 在编译时提示警告信息如下:Warning : C1420: Result of function-call is ignored 哪位大哥告诉我一下这是什么意思,怎么解决? 芯片为MC9S08DZ60 [ 本帖最后由 kwq498901 于 2012-3-31 09:29 编辑 ]…

查看全部问答>