|
51單片機(jī)溫濕度、光強(qiáng)、二氧化碳模塊仿真
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (39.47 KB, 下載次數(shù): 118)
下載附件
2021-4-4 02:33 上傳
51hei.png (33.14 KB, 下載次數(shù): 94)
下載附件
2021-4-4 02:33 上傳
單片機(jī)源程序如下:
- #include <reg51.h>
- #include "lcd.h"
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #define NACK 0
- #define ACK 1
- #define MEASURE_TEMP 0x03 //000 0001 1
- #define MEASURE_HUMI 0x05 //000 0010 1
- #define STATUS_REG_W 0x06 //000 0011 0
- #define STATUS_REG_R 0x07 //000 0011 1
- #define RESET 0x1E //000 1111 0
- ulong volt;//測(cè)量的電壓值
- sbit Data=P2^3; //定義數(shù)據(jù)線
- sbit CLK=P3^3;//定義時(shí)鐘信號(hào)口
- sbit DIN=P3^1;//定義2543數(shù)據(jù)寫入口
- sbit DOUT=P3^0;//定義2543數(shù)據(jù)讀取口
- sbit CS=P3^2;//定義2543片選信號(hào)口
- sbit Data_P = P2^4; // SHT11傳感器的數(shù)據(jù)管腳
- sbit Sck_P = P2^3; // SHT11傳感器的時(shí)鐘管腳
- sbit BEEP =P2^5;
- uchar tmpe,h;
- uchar rec_dat[9]; //用于顯示的接收數(shù)據(jù)數(shù)組
- uchar temp_max = 30;
- uchar humi_min = 60;
- ulong C2_max = 3500000;
- ulong LUX_max = 3500000;
- ulong C2_now = 0;
- ulong LUX_now = 0;
- unsigned char temp; // 保存溫度
- unsigned char humi; // 保存濕度
- enum { TEMP,HUMI };
- typedef union //定義共用同類型
- {
- unsigned int i;
- float f;
- }value;
- int display = 0;
- void delay(uchar ms)
- { // 延時(shí)子程序
- uchar i;
- while(ms--)
- {
- for(i = 0;i<250;i++);
- }
- }
- char ShtWriteByte(unsigned char value)
- {
- unsigned char i,error=0;
- for(i=128;i>0;i>>=1) // 高位為1,循環(huán)右移
- {
- if (i&value)
- Data_P=1; // 和要發(fā)送的數(shù)相與,結(jié)果為發(fā)送的位
- else
- Data_P=0;
- Sck_P=1;
- _nop_(); // 延時(shí)3us
- _nop_();
- _nop_();
- Sck_P=0;
- }
- Data_P=1; // 釋放數(shù)據(jù)線
- Sck_P=1;
- error=Data_P; // 檢查應(yīng)答信號(hào),確認(rèn)通訊正常
- _nop_();
- _nop_();
- _nop_();
- Sck_P=0;
- Data_P=1;
- return error; // error=1 通訊錯(cuò)誤
- }
- char ShtReadByte(unsigned char ack)
- {
- unsigned char i,val=0;
- Data_P=1; // 釋放數(shù)據(jù)線
- for(i=0x80;i>0;i>>=1) // 高位為1,循環(huán)右移
- {
- Sck_P=1;
- if(Data_P)
- val=(val|i); // 讀一位數(shù)據(jù)線的值
- Sck_P=0;
- }
- Data_P=!ack; // 如果是校驗(yàn),讀取完后結(jié)束通訊
- Sck_P=1;
- _nop_(); // 延時(shí)3us
- _nop_();
- _nop_();
- Sck_P=0;
- _nop_();
- _nop_();
- _nop_();
- Data_P=1; // 釋放數(shù)據(jù)線
- return val;
- }
- void ShtTransStart(void)
- {
- Data_P=1;
- Sck_P=0;
- _nop_();
- Sck_P=1;
- _nop_();
- Data_P=0;
- _nop_();
- Sck_P=0;
- _nop_();
- _nop_();
- _nop_();
- Sck_P=1;
- _nop_();
- Data_P=1;
- _nop_();
- Sck_P=0;
- }
- void ShtConnectReset(void)
- {
- unsigned char i;
- Data_P=1; //準(zhǔn)備
- Sck_P=0;
- for(i=0;i<9;i++) //DATA保持高,SCK時(shí)鐘觸發(fā)9次,發(fā)送啟動(dòng)傳輸,通迅即復(fù)位
- {
- Sck_P=1;
- Sck_P=0;
- }
- ShtTransStart(); //啟動(dòng)傳輸
- }
- char ShtMeasure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
- {
- unsigned error=0;
- unsigned int i;
- ShtTransStart(); // 啟動(dòng)傳輸
- switch(mode) // 選擇發(fā)送命令
- {
- case 1 : // 測(cè)量溫度
- error+=ShtWriteByte(0x03);
- break;
- case 2 : // 測(cè)量濕度
- error+=ShtWriteByte(0x05);
- break;
- default:
- break;
- }
- for(i=0;i<65535;i++)
- if(Data_P==0)
- break; // 等待測(cè)量結(jié)束
- if(Data_P)
- error+=1; // 如果長(zhǎng)時(shí)間數(shù)據(jù)線沒有拉低,說明測(cè)量錯(cuò)誤
- *(p_value) =ShtReadByte(1); // 讀第一個(gè)字節(jié),高字節(jié) (MSB)
- *(p_value+1)=ShtReadByte(1); // 讀第二個(gè)字節(jié),低字節(jié) (LSB)
- *p_checksum =ShtReadByte(0); // read CRC校驗(yàn)碼
- return error; // error=1 通訊錯(cuò)誤
- }
- void CalcSHT11(float *p_humidity ,float *p_temperature)
- {
- const float C1=-4.0; // 12位濕度精度 修正公式
- const float C2=+0.0405; // 12位濕度精度 修正公式
- const float C3=-0.0000028; // 12位濕度精度 修正公式
- const float T1=+0.01; // 14位溫度精度 5V條件 修正公式
- const float T2=+0.00008; // 14位溫度精度 5V條件 修正公式
- float rh=*p_humidity; // rh: 12位 濕度
- float t=*p_temperature; // t: 14位 溫度
- float rh_lin; // rh_lin: 濕度 linear值
- float rh_true; // rh_true: 濕度 ture值
- float t_C; // t_C : 溫度 ℃
- t_C=t*0.01 - 40; //補(bǔ)償溫度
- rh_lin=C3*rh*rh + C2*rh + C1; //相對(duì)濕度非線性補(bǔ)償
- rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相對(duì)濕度對(duì)于溫度依賴性補(bǔ)償
- *p_temperature=t_C; //返回溫度結(jié)果
- *p_humidity=rh_true; //返回濕度結(jié)果
- }
- unsigned char TempCorrect(int temp)
- {
- if(temp<0) temp=0;
- if(temp>970) temp=970;
- if(temp>235) temp=temp+10;
- if(temp>555) temp=temp+10;
- if(temp>875) temp=temp+10;
- temp=(temp%1000)/10;
- return temp;
- }
- unsigned char HumiCorrect(unsigned int humi)
- {
- if(humi>999) humi=999;
- if((humi>490)&&(humi<951)) humi=humi-10;
- humi=(humi%1000)/10;
- return humi+4;
- }
- void ReadShtData()
- {
- value humi_val,temp_val; // 定義兩個(gè)共同體,一個(gè)用于濕度,一個(gè)用于溫度
- unsigned char error; // 用于檢驗(yàn)是否出現(xiàn)錯(cuò)誤
- unsigned char checksum; // CRC
- unsigned int temp1,humi1; // 臨時(shí)讀取到的溫濕度數(shù)據(jù)
- error=0; //初始化error=0,即沒有錯(cuò)誤
- error+=ShtMeasure((unsigned char*)&temp_val.i,&checksum,1); //溫度測(cè)量
- error+=ShtMeasure((unsigned char*)&humi_val.i,&checksum,2); //濕度測(cè)量
- if(error!=0) //如果發(fā)生錯(cuò)誤,系統(tǒng)復(fù)位
- ShtConnectReset();
- else
- {
- humi_val.f=(float)humi_val.i; //轉(zhuǎn)換為浮點(diǎn)數(shù)
- temp_val.f=(float)temp_val.i; //轉(zhuǎn)換為浮點(diǎn)數(shù)
- CalcSHT11(&humi_val.f,&temp_val.f); //修正相對(duì)濕度及溫度
- temp1=temp_val.f*10;
- temp=TempCorrect(temp1);
- humi1=humi_val.f*10-50;
- humi=HumiCorrect(humi1);
- humi1=humi1-1;
- }
- }
- void read2543(uchar addr)
- {
- uint ad=0;
- uchar i;
- CLK=0;
- CS=0;//片選段,啟動(dòng)2543
- addr<<=4;//對(duì)地址位預(yù)處理
- for(i=0;i<12;i++) //12個(gè)時(shí)鐘走完,完成一次讀取測(cè)量
- {
- if(DOUT==1)
- ad=ad|0x01;//單片機(jī)讀取ad數(shù)據(jù)
- DIN=addr&0x80;//2543讀取測(cè)量地址位
- CLK=1;
- ;;;//很短的延時(shí)
- CLK=0;//產(chǎn)生下降沿,產(chǎn)生時(shí)鐘信號(hào)
- ;;;
- addr<<=1;
- ad<<=1;//將數(shù)據(jù)移位準(zhǔn)備下一位的讀寫
- }
- CS=1;//關(guān)2543
- ad>>=1;
- volt=ad;//取走轉(zhuǎn)換結(jié)果
- volt=volt*1221;//例子的滿量程為5V,轉(zhuǎn)換分辯率為12位(2的12次方=4096) 。即最大值是255,5/4096=1221mV,即例子中的1V代表實(shí)際1221mV
- }
- void main(void)
- {
- LcdInit();
- ShtConnectReset();
- DisplayListChar(0,0,"tmpe:");
- DisplayListChar(8,0,"HR:");
- DisplayListChar(0,1,"LUX:");
- DisplayOneChar(5,1,'.');
- DisplayListChar(9,1,"C2:");
- DisplayOneChar(13,1,'.');
- while(1)
- {
- ReadShtData();
- DisplayOneChar(11,0,(char)(humi/10+'0'));
- DisplayOneChar(12,0,(char)(humi%10+'0'));
- DisplayOneChar(5,0,(char)(temp/10+'0'));
- DisplayOneChar(6,0,(char)(temp%10+'0'));
-
- read2543(0);//調(diào)用2543驅(qū)動(dòng)程序測(cè)量地址為
- LUX_now=volt;
- DisplayOneChar(4,1,(char)(volt/1000000+'0'));
- DisplayOneChar(6,1,(char)((volt/100000)%10+'0'));
- DisplayOneChar(7,1,(char)((volt/10000)%10+'0'));
- read2543(1);//調(diào)用2543驅(qū)動(dòng)程序測(cè)量地址為
- C2_now=volt;
- DisplayOneChar(12,1,(char)(volt/1000000+'0'));
- DisplayOneChar(14,1,(char)((volt/100000)%10+'0'));
- DisplayOneChar(15,1,(char)((volt/10000)%10+'0'));
-
- if(LUX_now>LUX_max || C2_now>C2_max || humi<humi_min || temp>temp_max)
- {
-
- BEEP=0;
- }else
- {
- BEEP=1;
- }
- }
- }
復(fù)制代碼
51hei.png (9.44 KB, 下載次數(shù): 79)
下載附件
2021-4-4 02:34 上傳
所有資料51hei提供下載:
溫濕度光強(qiáng)二氧化碳.zip
(142.1 KB, 下載次數(shù): 207)
2021-4-3 15:54 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|