SHT1x/SHT7x数字温湿度传感器驱动编写
生活随笔
收集整理的這篇文章主要介紹了
SHT1x/SHT7x数字温湿度传感器驱动编写
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
結構圖
啟動傳輸時序圖
SHT10串行通信IO初始化
其中SDA和SCL分別是數據線和時鐘線。分別對應單片機的1.1口和1.0口
由時序圖可知,一開始SDA和SCL分別高電平和低電平
/*************************************************************************************************** 函數名稱:initIO** 功能描述:SHT10串行通信IO初始化** 參 數:無** 返 回 值:無**************************************************************************************************/ void initIO(void) {IO_DIR_PORT_PIN(1, 0, IO_OUT);//DIR是方向的意思IO_DIR_PORT_PIN(1, 1, IO_OUT);P1INP |= 0x03;SDA = 1; SCL = 0; }下面這個代碼也是根據時序圖來寫的。
由此可見,驅動其實就是根據時序圖來編寫的,不按照時序圖編寫,單片機不執行這段代碼的話,傳感器就不能正常工作,不會聽從單片機的指令。
通訊復位時序圖
/*************************************************************************************************** 函數名稱:s_connectionreset** 功能描述:與SHT10通信復位** 參 數:無** 返 回 值:無**************************************************************************************************/ void s_connectionreset(void) {IO_DIR_PORT_PIN(1, 0, IO_OUT);IO_DIR_PORT_PIN(1, 1, IO_OUT);unsigned char i;SDA = 1; SCL= 0;for(i=0;i<9;i++){SCL = 1;QWait();QWait();SCL = 0;QWait();QWait();}s_transstart(); }SHTXX命令集
如何實現溫濕度讀取呢?
在void th_read(int *t,int *h )函數里:
error+=s_measure(&checksum,5); //讀取濕度數據并校驗humi = d1*256+d2;error+=s_measure(&checksum,3); //讀取溫度數據并校驗temp = d1*256+d2;可以看到讀溫度還是讀濕度唯一區別就是s_measure里第二個參數是三還是五。
再看s_measure函數:
里面有一個s_write_byte()函數,結合SHTXX命令集可知道,單片機發送3就是發送溫度讀取命令,發送5就是發送濕度讀取命令。
當傳感器收到指令,開始工作收集濕度數據信息,這個過程需要時間。
當它準備好了,他會給單片機一個低電平,一旦單片機收到了,就break了。
然后單片機開始讀取數據:
d1 = s_read_byte(ACK); //數據讀取d2 = s_read_byte(ACK);d3 = s_read_byte(noACK);如果說延時完了SDA還沒有拉低,錯誤信息加1,并返回錯誤信息。 return er;
if(SDA) //SDA沒有拉低,錯誤信息加1{er += 1;} /*************************************************************************************************** 函數名稱:s_measure** 功能描述:發送命令、讀取SHT10溫度或濕度數據** 參 數:*p_checksum -- 校驗和* mode -- 讀取數據類型(3為溫度,5為濕度)** 返 回 值:er -- 操作結果**************************************************************************************************/char s_measure( unsigned char *p_checksum, unsigned char mode) {unsigned er=0;unsigned int i,j;s_transstart(); //啟動傳輸switch(mode){case 3 :er+=s_write_byte(3);break; //發送溫度讀取命令case 5 :er+=s_write_byte(5);break; //發送濕度讀取命令default :break;}IO_DIR_PORT_PIN(1, 1, IO_IN); //將數據線設置為輸入,以準備接收SHT10的ACKfor(i=0;i<65535;i++){for(j=0;j<65535;j++){if(SDA == 0){break;}}if(SDA == 0){break;}}if(SDA) //SDA沒有拉低,錯誤信息加1{er += 1;}d1 = s_read_byte(ACK); //數據讀取d2 = s_read_byte(ACK);d3 = s_read_byte(noACK);return er; }再來看void th_read(int *t,int *h )函數,就清晰很多了
/*************************************************************************************************** 函數名稱:th_read** 功能描述:調用相應函數,讀取溫度和數據數據并校驗和計算** 參 數:*t -- 溫度值* *h -- 濕度值** 返 回 值:無**************************************************************************************************/ void th_read(int *t,int *h ) {unsigned char error,checksum;float humi,temp;int tmp;initIO();s_connectionreset(); //啟動傳輸error=0;error+=s_measure(&checksum,5); //讀取濕度數據并校驗humi = d1*256+d2;error+=s_measure(&checksum,3); //讀取溫度數據并校驗temp = d1*256+d2;if(error!=0) s_connectionreset(); //讀取失敗,通信復位else //讀取成功,計算數據{ temp = temp*0.01 - 44.0 ;humi = (temp - 25) * (0.01 + 0.00008 * humi) -0.0000028 * humi * humi + 0.0405 * humi-4;//通過溫度計算相對濕度 if(humi>100){humi = 100;}if(humi<0.1){humi = 0.1;}}tmp=(int)(temp*10)%10;if(tmp>4){temp=temp+1; }else{temp=temp;}*t=(int)temp;tmp=(int)(humi*10)%10;if(humi>4){humi=humi+1; }else{humi=humi;}*h=(int)humi;}下面這一段是四舍五入的意思。
tmp=(int)(temp*10)%10;if(tmp>4){temp=temp+1; }else{temp=temp;}*t=(int)temp;tmp=(int)(humi*10)%10;if(humi>4){humi=humi+1; }else{humi=humi;}*h=(int)humi;代碼:
/*********************************************************************************************************************************************************** * SHT10 是一款高度集成的溫濕度傳感器芯片, 提供全標定的數字輸出。它采用專利的CMOSens技術,確保產品具有極高的可靠性與卓 * 越的長期穩定性。傳感器包括一個電容性聚合體測濕敏感元件、一個用能隙材料制成的測溫元件,并在同一芯片上,與14 位的A/D 轉 * 換器以及串行接口電路實現無縫連接。 * * SHT10引腳特性如下: * 1. VDD,GND SHT10 的供電電壓為2.4~5.5V。傳感器上電后,要等待11ms 以越過“休眠”狀態。在此期間無需發送任何指令。 * 電源引腳(VDD,GND)之間可增加一個100nF 的電容,用以去耦濾波。 * 2. SCK 用于微處理器與SHT10 之間的通訊同步。由于接口包含了完全靜態邏輯,因而不存在最小SCK頻率。 * 3. DATA 三態門用于數據的讀取。DATA 在SCK 時鐘下降沿之后改變狀態,并僅在SCK 時鐘上升沿有效。數據傳輸期間, * 在SCK 時鐘高電平時,DATA必須保持穩定。為避免信號沖突,微處理器應驅動DATA 在低電平。需要一個外部的上拉電阻 * (例如:10kΩ)將信號提拉至高電平。上拉電阻通常已包含在微處理器的I/O 電路中。 * * 向SHT10發送命令: * 用一組“ 啟動傳輸”時序,來表示數據傳輸的初始化。它包括:當SCK 時鐘高電平時DATA 翻轉為低電平,緊接著SCK變為低電平, * 隨后是在SCK 時鐘高電平時DATA 翻轉為高電平。后續命令包含三個地址位(目前只支持“000”),和五個命令位。SHT10會以下 * 述方式表示已正確地接收到指令:在第8 個SCK 時鐘的下降沿之后,將DATA 拉為低電平(ACK 位)。在第9 個SCK 時鐘的下降沿 * 之后,釋放DATA(恢復高電平)。 * * 測量時序(RH 和 T): * 發布一組測量命令(‘00000101’表示相對濕度RH,‘00000011’表示溫度T)后,控制器要等待測量結束。這個過程需要大約 * 11/55/210ms,分別對應8/12/14bit 測量。確切的時間隨內部晶振速度,最多有±15%變化。SHTxx 通過下拉DATA 至低電平并 * 進入空閑模式,表示測量的結束??刂破髟谠俅斡|發SCK 時鐘前,必須等待這個“數據備妥”信號來讀出數據。檢測數據可以 * 先被存儲,這樣控制器可以繼續執行其它任務在需要時再讀出數據。 * 接著傳輸2 個字節的測量數據和1 個字節的CRC 奇偶校驗。uC 需要通過下拉DATA 為低電平,以確認每個字節。所有的數據從 * MSB 開始,右值有效(例如:對于12bit 數據,從第5 個SCK 時鐘起算作MSB; 而對于 8bit 數據, 首字節則無意義)。用 * CRC 數據的確認位,表明通訊結束。如果不使用CRC-8 校驗,控制器可以在測量值LSB 后,通過保持確認位ack 高電平, 來中 * 止通訊。在測量和通訊結束后,SHTxx 自動轉入休眠模式。 * * 通訊復位時序: * 如果與 SHTxx 通訊中斷,下列信號時序可以復位串口:當DATA 保持高電平時,觸發SCK 時鐘9 次或更多。在下一次指令前,發送 * 一個“傳輸啟動”時序。這些時序只復位串口,狀態寄存器內容仍然保留。 * * 更多SHT10信息,請參考相應文檔。 * * 光照強度采集: * 光照采集主要是通過用CC2530內部的ADC來得到OURS-CC2530開發板上的光照傳感器輸出電壓。傳感器輸出電壓(連接到CC2530的AIN0) * * 本實驗將使用CC2530讀取溫濕度傳感器SHT10的溫度和濕度數據,并通過ADC得到光照傳感器的數據。最后將采樣到的數據轉換然后在LCD上顯示。 * * 在\include\hal.h文件中包含了和ADC相關的一些宏,用戶使用這些宏 * 可以簡化對ADC的操作,提高代碼的可讀性,本實驗中就使用了其中的一些宏。 * * 注 意:本實驗所需硬件資源: * OURS-CC2530RF板 * 帶LCD的智能主板 * 溫濕度+光照傳感器板 * ***********************************************************************************************************************************************************/ #include "hal.h" #include "LCD.h" #include "stdio.h"#define noACK 0 #define ACK 1#define STATUS_REG_W 0x06 #define STATUS_REG_R 0x07 #define MEASURE_TEMP 0x03 #define MEASURE_HUMI 0x05 #define RESET 0x1e#define SCL P1_0 //SHT10時鐘 #define SDA P1_1 //SHT10數據線unsigned char d1,d2,d3,d4,d5,d6,d7;void Wait(unsigned int ms); void QWait(void) ; char s_write_byte(unsigned char value); char s_read_byte(unsigned char ack); void s_transstart(void); void s_connectionreset(void); char s_measure( unsigned char *p_checksum, unsigned char mode); void initIO(void);/*************************************************************************************************** 函數名稱:Wait** 功能描述:延時函數(不精確延時)** 參 數:ms -- 延時時間** 返 回 值:無**************************************************************************************************/ void Wait(unsigned int ms) {unsigned char g,k;while(ms){for(g=0;g<=167;g++){for(k=0;k<=48;k++);}ms--; } } /*************************************************************************************************** 函數名稱:QWait** 功能描述:延時函數(大約1us的延時)** 參 數:無** 返 回 值:無**************************************************************************************************/ void QWait() {asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");}/*************************************************************************************************** 函數名稱:initIO** 功能描述:SHT10串行通信IO初始化** 參 數:無** 返 回 值:無**************************************************************************************************/ void initIO(void) {IO_DIR_PORT_PIN(1, 0, IO_OUT);IO_DIR_PORT_PIN(1, 1, IO_OUT);P1INP |= 0x03;SDA = 1; SCL = 0; }/*************************************************************************************************** 函數名稱:s_write_byte** 功能描述:從SHT10寫一個字節** 參 數:value -- 需寫入的字節值** 返 回 值:error -- 操作是否成功**************************************************************************************************/ char s_write_byte(unsigned char value) { unsigned char i,error=0; IO_DIR_PORT_PIN(1, 0, IO_OUT); //時鐘和數據IO設置為輸出IO_DIR_PORT_PIN(1, 1, IO_OUT);for (i=0x80;i>0;i/=2) //將一個字節的8位逐一輸出 {if (i & value)SDA=1; elseSDA=0; SCL = 1; QWait();QWait();QWait();QWait();QWait();SCL = 0;asm("NOP"); asm("NOP");}SDA = 1; IO_DIR_PORT_PIN(1, 1, IO_IN); //將數據線設置為輸入,以準備接收SHT10的ACKSCL = 1; asm("NOP"); error = SDA; QWait();QWait();QWait();IO_DIR_PORT_PIN(1, 1, IO_OUT); //將數據線恢復為輸出狀態SDA = 1; SCL = 0; return error; }/*************************************************************************************************** 函數名稱:s_read_byte** 功能描述:從SHT10讀取一個字節** 參 數:ack -- 讀取數據后,向SHT10發送ACK** 返 回 值:val -- 讀取的字節值**************************************************************************************************/ char s_read_byte(unsigned char ack) {IO_DIR_PORT_PIN(1, 0, IO_OUT); //時鐘和數據IO設置為輸出IO_DIR_PORT_PIN(1, 1, IO_OUT);unsigned char i,val=0;SDA= 1;IO_DIR_PORT_PIN(1, 1, IO_IN); //將數據線設置為輸入,以準備接收SHT10的數據for (i=0x80;i>0;i/=2) {SCL = 1;if (SDA)val = (val | i);elseval = (val | 0x00);SCL = 0;QWait();QWait();QWait();QWait();QWait();}IO_DIR_PORT_PIN(1, 1, IO_OUT); //將數據線恢復為輸出狀態SDA = !ack;SCL = 1;QWait();QWait();QWait();QWait();QWait();SCL = 0;SDA = 1;return val; //返回讀取的值 }/*************************************************************************************************** 函數名稱:s_transstart** 功能描述:啟動SHT10,開始與SHT10通信** 參 數:無** 返 回 值:無**************************************************************************************************/ void s_transstart(void) {IO_DIR_PORT_PIN(1, 0, IO_OUT);IO_DIR_PORT_PIN(1, 1, IO_OUT);SDA = 1; SCL = 0;QWait();QWait();SCL = 1;QWait();QWait();SDA = 0;QWait();QWait(); SCL = 0;QWait();QWait();QWait();QWait();QWait();SCL = 1;QWait();QWait();SDA = 1;QWait();QWait();SCL = 0;QWait();QWait(); }/*************************************************************************************************** 函數名稱:s_connectionreset** 功能描述:與SHT10通信復位** 參 數:無** 返 回 值:無**************************************************************************************************/ void s_connectionreset(void) {IO_DIR_PORT_PIN(1, 0, IO_OUT);IO_DIR_PORT_PIN(1, 1, IO_OUT);unsigned char i;SDA = 1; SCL= 0;for(i=0;i<9;i++){SCL = 1;QWait();QWait();SCL = 0;QWait();QWait();}s_transstart(); }/*************************************************************************************************** 函數名稱:s_measure** 功能描述:發送命令、讀取SHT10溫度或濕度數據** 參 數:*p_checksum -- 校驗和* mode -- 讀取數據類型(3為溫度,5為濕度)** 返 回 值:er -- 操作結果**************************************************************************************************/ char s_measure( unsigned char *p_checksum, unsigned char mode) {unsigned er=0;unsigned int i,j;s_transstart(); //啟動傳輸switch(mode){case 3 :er+=s_write_byte(3);break; //發送溫度讀取命令case 5 :er+=s_write_byte(5);break; //發送濕度讀取命令default :break;}IO_DIR_PORT_PIN(1, 1, IO_IN); //將數據線設置為輸入,以準備接收SHT10的ACKfor(i=0;i<65535;i++){for(j=0;j<65535;j++){if(SDA == 0){break;}}if(SDA == 0){break;}}if(SDA) //SDA沒有拉低,錯誤信息加1{er += 1;}d1 = s_read_byte(ACK); //數據讀取d2 = s_read_byte(ACK);d3 = s_read_byte(noACK);return er; }/*************************************************************************************************** 函數名稱:th_read** 功能描述:調用相應函數,讀取溫度和數據數據并校驗和計算** 參 數:*t -- 溫度值* *h -- 濕度值** 返 回 值:無**************************************************************************************************/ void th_read(int *t,int *h ) {unsigned char error,checksum;float humi,temp;int tmp;initIO();s_connectionreset(); //啟動傳輸error=0;error+=s_measure(&checksum,5); //讀取濕度數據并校驗humi = d1*256+d2;error+=s_measure(&checksum,3); //讀取溫度數據并校驗temp = d1*256+d2;if(error!=0) s_connectionreset(); //讀取失敗,通信復位else //讀取成功,計算數據{ temp = temp*0.01 - 44.0 ;humi = (temp - 25) * (0.01 + 0.00008 * humi) -0.0000028 * humi * humi + 0.0405 * humi-4;//通過溫度計算相對濕度 if(humi>100){humi = 100;}if(humi<0.1){humi = 0.1;}}tmp=(int)(temp*10)%10;if(tmp>4){temp=temp+1; }else{temp=temp;}*t=(int)temp;tmp=(int)(humi*10)%10;if(humi>4){humi=humi+1; }else{humi=humi;}*h=(int)humi;}/*************************************************************************************************** 函數名稱:main** 功能描述:讀取溫度、濕度和光照強度數據,并同過LCD顯示** 參 數:無** 返 回 值:無**************************************************************************************************/ void main() {int tempera;int humidity;char s[16];UINT8 adc0_value[2];float num = 0;SET_MAIN_CLOCK_SOURCE(CRYSTAL); // 設置系統時鐘源為32MHz晶體振蕩器GUI_Init(); // GUI初始化GUI_SetColor(1,0); // 顯示色為亮點,背景色為暗點GUI_PutString5_7(25,6,"OURS-CC2530"); //顯示 OURS-CC2530GUI_PutString5_7(10,22,"Temp:"); GUI_PutString5_7(10,35,"Humi:");GUI_PutString5_7(10,48,"Light:");LCM_Refresh();while(1){th_read(&tempera,&humidity); //讀取溫度和濕度sprintf(s, (char*)"%d%d C", ((INT16)((int)tempera / 10)), ((INT16)((int)tempera % 10))); //將溫度結果轉換為字符串GUI_PutString5_7(48,22,(char *)s); //顯示結果LCM_Refresh();sprintf(s, (char*)"%d%d %%", ((INT16)((int)humidity / 10)), ((INT16)((int)humidity % 10)));//將濕度結果轉換為字符串GUI_PutString5_7(48,35,(char *)s); //顯示結果LCM_Refresh();/* AIN0通道采樣 */ADC_ENABLE_CHANNEL(ADC_AIN0); // 使能AIN0為ADC輸入通道/* 配置ADCCON3寄存器以便在ADCCON1.STSEL = 11(復位默認值)且ADCCON1.ST = 1時進行單一轉換 *//* 參考電壓:AVDD_SOC引腳上的電壓 *//* 抽取率:512 *//* ADC輸入通道:AIN0 */ADC_SINGLE_CONVERSION(ADC_REF_AVDD | ADC_14_BIT | ADC_AIN0);ADC_SAMPLE_SINGLE(); // 啟動一個單一轉換while(!ADC_SAMPLE_READY()); // 等待轉換完成ADC_ENABLE_CHANNEL(ADC_AIN0); // 禁止AIN0adc0_value[0] = ADCL; // 讀取ADC值adc0_value[1] = ADCH; // 讀取ADC值adc0_value[0] = adc0_value[0]>>2;num = (adc0_value[1]*256+adc0_value[0])*3.3/8192; //有一位符號位,取2^13;num /= 4; num=num*913; //轉換為Lxsprintf(s, (char*)"%d%d%d%d lx", ((INT16)((int)num/1000)), ((INT16)((int)num%1000/100)),((INT16)((int)num%100/10)),((INT16)((int)num%10))); //將光照結果轉換為字符串GUI_PutString5_7(48,48,(char *)s); //顯示結果LCM_Refresh();} }總結
以上是生活随笔為你收集整理的SHT1x/SHT7x数字温湿度传感器驱动编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础 系统注解 @Overrid
- 下一篇: matlab sar 斑马图,星载合成孔