天天看點

STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)

一、環境介紹

工程編譯軟體:  keil5

溫濕度傳感器: SHT30

MCU : STM32F103ZET6

程式采用子產品化程式設計,iic時序為一個子產品(iic.c 和 iic.h),SHT30為一個子產品(sht30.c 和 sht30.h);IIC時序采用模拟時序方式實作,IO口都采用宏定義方式,友善快速移植到其他平台使用。

工程源碼完整下載下傳位址:

https://download.csdn.net/download/xiaolong1126626497/18973724 二、SHT30介紹
STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)
STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)

特點:

1. 濕度和溫度傳感器

2. 完全校準、線性化和溫度

3. 補償數字輸出,寬電源電壓範圍,從2.4 V到5.5 V

4. I2C接口,通信速度高達1MHz和兩個使用者可選位址

5. 典型精度 +- 2%相對濕度和+- 0.3°C

6. 啟動和測量時間非常快

7. 微型8針DFN封裝

STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)
STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)
這是SHT30的7位IIC裝置位址:   
STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)

三、裝置運作效果

這是序列槽列印的資料:

STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)
STM32F103ZE+SHT30檢測環境溫度與濕度(IIC模拟時序)
STM32F103ZE+SHT30檢測環境溫度與濕度(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("裝置運作正常....\r\n");
   IIC_Init(); 
   Init_SHT30();
   while(1)
   {
       //讀取溫濕度
       SHT3x_ReadData(&Humidity,&Temperature);
       USART1_Printf("溫度:%0.2f,濕度:%0.2f\r\n",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:1\r\n");
 
    IIC_WriteOneByteData(0x30); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("Init_SHT30_error:2\r\n");
    
    IIC_WriteOneByteData(0xA2); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("Init_SHT30_error:3\r\n");
    
    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:1\r\n");
 
    IIC_WriteOneByteData(0x22); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("Init_SHT30_error:2\r\n");
    
    IIC_WriteOneByteData(0x36); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("Init_SHT30_error:3\r\n");
    
    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:1\r\n");
 
    IIC_WriteOneByteData(0xE0); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("SHT3X_error:2\r\n");
    
    IIC_WriteOneByteData(0x00); //寫資料
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("SHT3X_error:3\r\n");
    
    //IIC_Stop(); //停止信号 
    
   // DelayMs(30); //等待
    
    //讀取sht30傳感器資料
    IIC_Start(); //發送起始信号
    IIC_WriteOneByteData(SHT30_AddrR);
    r_s=IIC_GetACK();//擷取應答
    if(r_s)printf("SHT3X_error:7\r\n");
    
    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;               //時鐘線拉高,告訴從機,主機資料發送完畢
        DelayUs(2);            //電平保持時間,等待從機接收資料
        IIC_SCL=0;               //時鐘線拉低,告訴從機,主機需要資料
}
 
 
/*
函數功能:IIC發送1個位元組資料
函數形參:将要發送的資料
*/
void IIC_WriteOneByteData(u8 data)
{
        u8 i;
        IIC_SDA_OUTMODE(); //初始化SDA為輸出模式
        IIC_SCL=0;           //時鐘線拉低,告訴從機,主機需要發送資料
        for(i=0;i<8;i++)
        {
                if(data&0x80)IIC_SDA_OUT=1; //資料線拉高,發送1
                else IIC_SDA_OUT=0;      //資料線拉低,發送0
                IIC_SCL=1;               //時鐘線拉高,告訴從機,主機資料發送完畢
                DelayUs(2);            //電平保持時間,等待從機接收資料
                IIC_SCL=0;                   //時鐘線拉低,告訴從機,主機需要發送資料
                DelayUs(2);            //電平保持時間,等待時鐘線穩定
                data<<=1;              //先發高位
        }
}
 
 
/*
函數功能:IIC接收1個位元組資料
返 回 值:收到的資料
*/
u8 IIC_ReadOneByteData(void)
{
        u8 i,data;
        IIC_SDA_INPUTMODE();//初始化SDA為輸入模式
      for(i=0;i<8;i++)
      {
                IIC_SCL=0;            //時鐘線拉低,告訴從機,主機需要資料
                DelayUs(2);         //電平保持時間,等待從機發送資料
                IIC_SCL=1;            //時鐘線拉高,告訴從機,主機現在正在讀取資料
                data<<=1;           
                if(IIC_SDA_IN)data|=0x01;
                DelayUs(2);         //電平保持時間,等待時鐘線穩定
      }
        IIC_SCL=0;                  //時鐘線拉低,告訴從機,主機需要資料 (必須拉低,否則将會識别為停止信号)
        return data;
}
 
       

繼續閱讀