由瑞士Sensirion推出的 SHT20數(shù)字溫濕度傳感器,基于領先世界的CMOSens ? 數(shù)字傳感技術,具有極高的可靠性和卓越的長期穩(wěn)定性。全量程標定,兩線數(shù)字接口,可與單片機直接相連,大大縮短研發(fā)時間、簡化外圍電路并降低費用。此外,體積微小、響應迅速、低能耗、可浸沒、抗干擾能力強、溫濕一體,兼有露點測量,性價比高,使該產(chǎn)品能夠適于多種場合的應用。
一、模塊來源
模塊實物展示:
資料下載鏈接:
https://pan.baidu.com/s/1HrQkwECvGgQSHvt_RNdLdA
二 、規(guī)格參數(shù)
工作電壓:2.1~3.6V
工作電流:0.1~1000uA
溫度精度:±0.3℃
溫度范圍:-40~125℃
濕度范圍:0~100 %RH
濕度精度:±3%RH
輸出方式: IIC
管腳數(shù)量:4 Pin
以上信息見廠家資料文件
三、移植過程
我們的目標是將例程移植至CW32F030C8T6開發(fā)板上【能夠測量環(huán)境溫濕度】。首先要獲取資料,查看數(shù)據(jù)手冊應如何實現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。
3.1查看資料
開始傳輸后,隨后先傳輸首字節(jié)包括I2C設備地址(7bit)和一個SDA方向位(R:1, W:0)。
一個時鐘發(fā)送一個位,在第8個下降沿之后,通過拉低SDA引腳(ACK位 為0),只是傳感器數(shù)據(jù)接收正常。在發(fā)出測量命令之后(‘1110’‘0011’代表溫度測量,‘1110’‘0101’代表相對濕度測量 ,這種為主機模式),MCU必須等待測量完成。
主機模式:
測量過程中,SCL線被封鎖(由傳感器控制),在測量時,SHT2x將SCL拉低強制主機進入等待狀態(tài)。當釋放SCL線,表示傳感器內(nèi)部工作接收,可以繼續(xù)進行數(shù)據(jù)傳送
灰色的部分是傳感器控制的,當傳感器給MCU返回數(shù)據(jù)時,每返回一個字節(jié),MCU要返回一個ACK信號,當接收完畢之后,返回一個NACK并接著傳輸停止時序(P)。
注:校驗和可以不需要,不需要則就在數(shù)據(jù)接收完之后返回NACK
非主機模式:
測量過程中,SCL線是開發(fā)狀態(tài),可進行其他通信,可以在總線上處理其他I2C總線通信任務。
當MCU要對傳感器狀態(tài)進行查詢時,先發(fā)起一個開始信號,在發(fā)送從機地址和SDA方向位(寫),此時從機匹配地址成功,則發(fā)送ACK信號,并開始測量。如果傳感器完成了測量過程,并且發(fā)送ASK信號,那么MCU就可以讀取相關數(shù)據(jù)。如果測量沒有完成,傳感器發(fā)送NACK信號,此時MCU必須重新發(fā)送啟動傳輸時序,直至測量完成,MCU讀取數(shù)據(jù)。
注意:測量的數(shù)據(jù),溫度和濕度均為兩個字節(jié)。而且無論哪一種傳輸模式,測量的最大分辨率最大是14bit,數(shù)據(jù)的第二個字節(jié)SDA上最后兩位是用來標記相關狀態(tài)信息。其中bit1表示測量類型(0是溫度,1是濕度)
灰色的區(qū)域是傳感器控制的,如果不需要校驗和,那么在接收完兩個字節(jié)的數(shù)據(jù)之后就MCU直接發(fā)出NACK信號再接著發(fā)出停止時序(P),則結束通信。
通常測量的最長時間取決于測量類型和分辨率.
在計算MCU通信時間時,測量溫度選擇最長測量時間是85ms,而測量相對濕度選擇最長的時間是29ms。
傳感器內(nèi)部設置的默認分辨率為相對濕度12位和溫度14位。SDA的輸出數(shù)據(jù)被轉換成兩個字節(jié)的數(shù)據(jù)包,高字節(jié)MSB在前(左對齊)。每個字節(jié)后面都跟隨一個應答位。兩個狀態(tài)位,即 LSB的后兩位在進行物理計算前須置0。計算濕度:其中SRH表示我們讀取到的濕度原始數(shù)據(jù)。
計算溫度:其中ST表示我們讀取到的溫度原始數(shù)據(jù)。
3.2引腳選擇
模塊接線圖
3.3移植至工程
移植步驟中的導入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_sht20.c與bsp_sht20.h。這里不再過多講述,移植完成后面修改相關代碼。
在文件bsp_sht20.c中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #include "bsp_sht20.h" #include "board.h" #include "stdio.h" void SHT20_GPIO_INIT(void) { GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結構體 RCC_SHT20_ENABLE(); // 使能GPIO時鐘 GPIO_InitStruct.Pins = GPIO_SDA|GPIO_SCL; // GPIO引腳 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 開漏輸出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(PORT_SHT20, &GPIO_InitStruct); // 初始化 } /****************************************************************** * 函 數(shù) 名 稱:IIC_Start * 函 數(shù) 說 明:IIC起始信號 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Start(void) { SDA_OUT(); SCL(0); SDA(1); SCL(1); delay_us(5); SDA(0); delay_us(5); SCL(0); delay_us(5); } /****************************************************************** * 函 數(shù) 名 稱:IIC_Stop * 函 數(shù) 說 明:IIC停止信號 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Stop(void) { SDA_OUT(); SCL(0); SDA(0); SCL(1); delay_us(5); SDA(1); delay_us(5); } /****************************************************************** * 函 數(shù) 名 稱:IIC_Send_Ack * 函 數(shù) 說 明:主機發(fā)送應答 * 函 數(shù) 形 參:0應答 1非應答 * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Send_Ack(uint8_t ack) { SDA_OUT(); SCL(0); SDA(0); delay_us(5); if(!ack) SDA(0); else SDA(1); SCL(1); delay_us(5); SCL(0); SDA(1); } /****************************************************************** * 函 數(shù) 名 稱:IIC_Wait_Ack * 函 數(shù) 說 明:等待從機應答 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:1=無應答 0=有應答 * 作 者:LC * 備 注:無 ******************************************************************/ uint8_t IIC_Wait_Ack(void) { char ack = 0; unsigned char ack_flag = 10; SDA_IN(); SDA(1); delay_us(5); SCL(1); delay_us(5); while( (SDA_GET()==1) && ( ack_flag ) ) { ack_flag--; delay_us(5); } if( ack_flag <= 0 ) { IIC_Stop(); return 1; } else { SCL(0); SDA_OUT(); } return ack; } /****************************************************************** * 函 數(shù) 名 稱:IIC_Write * 函 數(shù) 說 明:IIC寫一個字節(jié) * 函 數(shù) 形 參:dat寫入的數(shù)據(jù) * 函 數(shù) 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void IIC_Write(uint8_t data) { int i = 0; SDA_OUT(); SCL(0);//拉低時鐘開始數(shù)據(jù)傳輸 for( i = 0; i < 8; i++ ) { SDA( (data & 0x80) >> 7 ); delay_us(2); data<=1; delay_us(6); SCL(1); delay_us(4); SCL(0); delay_us(4); } } /****************************************************************** * 函 數(shù) 名 稱:IIC_Read * 函 數(shù) 說 明:IIC讀1個字節(jié) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:讀出的1個字節(jié)數(shù)據(jù) * 作 者:LC * 備 注:無 ******************************************************************/ uint8_t IIC_Read(void) { unsigned char i,receive=0; SDA_IN();//SDA設置為輸入 for(i=0;i8;i++ ) { SCL(0); delay_us(5); SCL(1); delay_us(5); receive<=1; if( SDA_GET() ) { receive|=1; } delay_us(5); } return receive; } /****************************************************************** * 函 數(shù) 名 稱:SHT20_Read * 函 數(shù) 說 明:測量溫濕度 * 函 數(shù) 形 參:regaddr寄存器地址 regaddr=0xE3測量溫度 =0xE5測量濕度 * 函 數(shù) 返 回:regaddr=0xE3時返回溫度,regaddr=0xE5時返回濕度 * 作 者:LC * 備 注:無 ******************************************************************/ float SHT20_Read(uint8_t regaddr) { unsigned char data_H = 0; unsigned char data_L = 0; float temp = 0; IIC_Start(); IIC_Write(0x80|0); if( IIC_Wait_Ack() == 1 ) printf("error -1rn"); IIC_Write(regaddr); if( IIC_Wait_Ack() == 1 ) printf("error -2rn"); do{ delay_us(10); IIC_Start(); IIC_Write(0x80|1); }while( IIC_Wait_Ack() == 1 ); delay_us(20); data_H = IIC_Read(); IIC_Send_Ack(0); data_L = IIC_Read(); IIC_Send_Ack(1); IIC_Stop(); if( regaddr == 0xf3 ) { temp = ((data_H<8)|data_L) / 65536.0 * 175.72 - 46.85; } if( regaddr == 0xf5 ) { temp = ((data_H<8)|data_L) / 65536.0 * 125.0 - 6; } return temp; }
在文件bsp_sht20.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #ifndef __BSP_SHT20_H__ #define __BSP_SHT20_H__ #include "board.h" //端口移植 #define RCC_SHT20_ENABLE() __RCC_GPIOB_CLK_ENABLE() #define PORT_SHT20 CW_GPIOB #define GPIO_SDA GPIO_PIN_9 #define GPIO_SCL GPIO_PIN_8 //設置SDA輸出模式 #define SDA_OUT() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_SDA; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_SHT20, &GPIO_InitStruct); } //設置SDA輸入模式 #define SDA_IN() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_SDA; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(PORT_SHT20, &GPIO_InitStruct); } //獲取SDA引腳的電平變化 #define SDA_GET() GPIO_ReadPin(PORT_SHT20, GPIO_SDA) //SDA與SCL輸出 #define SDA(x) GPIO_WritePin(PORT_SHT20, GPIO_SDA, (x?GPIO_Pin_SET:GPIO_Pin_RESET) ) #define SCL(x) GPIO_WritePin(PORT_SHT20, GPIO_SCL, (x?GPIO_Pin_SET:GPIO_Pin_RESET) ) void SHT20_GPIO_INIT(void); float SHT20_Read(unsigned char regaddr); #endif
四、移植驗證
在自己工程中的main主函數(shù)中,編寫如下。
/* * Change Logs: * Date Author Notes * 2024-06-20 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "bsp_sht20.h" #define T_ADDR 0xf3 // 溫度 #define PH_ADDR 0xf5 // 濕度 int32_t main(void) { board_init(); // 開發(fā)板初始化 uart1_init(115200); // 串口1波特率115200 SHT20_GPIO_INIT(); delay_ms(1000); printf("SHT20 Start!!rn"); while(1) { printf("溫度 = %.2f ℃rn", SHT20_Read(T_ADDR) ); printf("濕度 = %.2f %%RHrn",SHT20_Read(PH_ADDR) ); printf("n"); delay_ms(1000); } }
上電現(xiàn)象:
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/13EW713tzDGwSDVUw--ouJQ?pwd=LCKF
提取碼:LCKF
審核編輯 黃宇
-
傳感器
+關注
關注
2564文章
52793瀏覽量
765432 -
溫濕度傳感器
+關注
關注
5文章
593瀏覽量
36443 -
CW32
+關注
關注
1文章
243瀏覽量
1181
發(fā)布評論請先 登錄
Sensirion 推出帶保護蓋的新型數(shù)字溫濕度傳感器

常見的溫濕度傳感器類型?
溫濕度傳感器:核心原理與跨領域應用解析

溫濕度傳感器:生活中的“小氣候?qū)<摇?/a>
CW32模塊使用案例 AHT10溫濕度傳感器

CW32模塊使用 SHT30溫濕度傳感器

基于CW32模塊的SHT30溫濕度傳感器設計

溫濕度傳感器種類及原理的優(yōu)劣分析
溫濕度傳感器是什么類型的傳感器
【RA-Eco-RA0E1-32PIN-V1.0開發(fā)板試用】sht30溫濕度傳感器
車載溫濕度傳感器有什么功能
CW32模塊使用 DHT11溫濕度傳感器

評論