|
12864顯示;
adc采集bandgap電壓顯示;
使用100K NTC測(cè)溫顯示;
家里的新房交付,自帶簡(jiǎn)單裝修,添置了些家具草草入住,同時(shí)考慮室外空氣質(zhì)量也比較差勁,更換了凈化器的濾芯、添置了壁掛新風(fēng),考慮囊中羞澀,決定自己買傳感器,拿51和12864來(lái)DIY個(gè)檢測(cè)器;說(shuō)在前面:
這個(gè)東西個(gè)人感覺(jué)沒(méi)法定性也沒(méi)必要,有個(gè)參考就可以了。
傳感器: 淘寶找得基本最便宜的:國(guó)產(chǎn)達(dá)特WZ-S-K,帶引腳的;PMS5003,不帶溫濕度、不帶甲醛款;
其他配置:
玩蘿麗控陸續(xù)攢的STC15w408AS、IIC接口的12864白色OLED屏;
原理:
兩個(gè)傳感器都是串口,均支持主動(dòng)、被動(dòng)通信;收發(fā)地一連,MCU接收傳感器發(fā)來(lái)的數(shù)據(jù),做個(gè)數(shù)據(jù)解析并給12864顯示就完工了。
遇到的問(wèn)題:
STC15W408AS自帶1個(gè)串口,要與2個(gè)設(shè)備通信;
解決方法1:
按照網(wǎng)上的方法直連,經(jīng)測(cè)試,估計(jì)引腳的輸出能力偏弱,攀藤就被干掉了;失;
解決方法2:
翻看STC的手冊(cè),這貨可以分時(shí)的方式切換串口到第二、第三組引腳;16pin的stc15引腳比較少,但也有2組可用,滿足要求。
程序主要思路:
通過(guò)設(shè)定flag的0、1狀態(tài),同時(shí)配合切換串口位置,分時(shí)發(fā)送命令給傳感器,分時(shí)接收數(shù)據(jù)并做簡(jiǎn)單判斷、解析并在12864上作出顯示。
存在的問(wèn)題:
未做數(shù)據(jù)的校驗(yàn)及錯(cuò)誤情況的判斷及軟件重置。反正跑死了,手動(dòng)重啟就好啦。。。
補(bǔ)充說(shuō)明:
1,PMS5003默認(rèn)主動(dòng)發(fā)送數(shù)據(jù),掉電會(huì)自動(dòng)恢復(fù)默認(rèn)主動(dòng)的發(fā)送情形,因此程序在每次上電時(shí)主動(dòng)發(fā)送命令,使其工作在被動(dòng)模式;
甲醛傳感器貌似沒(méi)啥影響,串口切到被動(dòng)后,沒(méi)注意掉電會(huì)不會(huì)恢復(fù)主動(dòng),測(cè)試顯示數(shù)據(jù)沒(méi)發(fā)現(xiàn)異常就沒(méi)管它。發(fā)帖此時(shí)傳感器沒(méi)在手上,因此就不做測(cè)試,后續(xù)再議了。
2,PMS5003的官網(wǎng)手冊(cè),最后一些關(guān)于校驗(yàn)的協(xié)議,像是沒(méi)寫完,沒(méi)有句號(hào),也沒(méi)明確2個(gè)校驗(yàn)字節(jié)的具體內(nèi)容,因此通過(guò)官方要來(lái)了基本協(xié)議的解釋,再次感謝熱情的攀藤小姐姐。分享以下:
0x42 0x4D 0xE1 0x00 0x00 0x01 0x70 - passive mode return:42 4D 00 04 E1 00 01 74 0x42 0x4D 0xE1 0x00 0x01 0x01 0x71 - active mode. return:42 4D 00 04 E1 01 01 750x42 0x4D 0xE2 0x00 0x00 0x01 0x71 - Passive mode read instruction 0x42 0x4D 0xE4 0x00 0x00 0x01 0x73 - standby mode return::42 4D 00 04 E4 00 01 77 0x42 0x4D 0xE4 0x00 0x01 0x01 0x74 -Standby wakeup
傳感器真身:
檢測(cè)顯示:
雜亂的全家福:
單片機(jī)源程序如下:
- #include <stc15.h>
- #include <12864.h>
- #include <delay.h>
- #include <character.h>
- unsigned char a[32],b[4];
- unsigned char n=0;
- unsigned char m=0;
- unsigned char numb=6;
- unsigned int numb2=0x2c;
- bit flag;
- unsigned int zong,pm10i,pm25i,pm100i;
- void UartInit(void) //9600bps@11.0592MHz
- {
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x01; //串口1選擇定時(shí)器2為波特率發(fā)生器
- AUXR &= 0xFB; //定時(shí)器2時(shí)鐘為Fosc/12,即12T
- T2L = 0xE8; //設(shè)定定時(shí)初值
- T2H = 0xFF; //設(shè)定定時(shí)初值
-
- AUXR |= 0x10; //啟動(dòng)定時(shí)器2
- EA=1;
- ES=1;
- }
- //發(fā)送一個(gè)byte;
- void sendonebyte(unsigned char udat)
- {
- SBUF=udat;
- while(!TI);
- TI=0;
- }
- //發(fā)送字符串;
- void sendstrings(unsigned char *upstr)
- {
- while(*upstr)
- {
- sendonebyte(*upstr++);
-
-
- }
- }
- void Delay05s()
- {
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- Delay50ms();
- }
- unsigned char receivedat()
- {
- unsigned char redatbuf;
-
- if(RI == 1)
- {
-
- redatbuf=SBUF;
- RI=0;
- }
- return redatbuf;
- }
- void countnum(unsigned int num) //int 65536;
- {
- //b[4]=(num/10000)%10; //萬(wàn)位;
- b[3]=(num/1000)%10; //千位;
- b[2]=(num/100)%10; //百位;
- b[1]=(num/10)%10; //十位;
- b[0]=(num/1)%10; //個(gè)位;
- }
- void hcho_T() //flag=1,計(jì)算甲醛
- {
-
- Delay05s();
- AUXR1 |= 0x40; //串口切換到 P3.6Rxd P3.7Txd;
- Delay50ms();
- flag=1;
- sendonebyte(0xff); //FF 01 86 00 00 00 00 00 79 dart wz-s 請(qǐng)求數(shù)據(jù)命令;
- sendonebyte(0x01);
- sendonebyte(0x86);
- sendonebyte(0x00);
- sendonebyte(0x00);
- sendonebyte(0x00);
- sendonebyte(0x00);
- sendonebyte(0x00);
- sendonebyte(0x79);
- //
- }
- void pm25_T()
- {
-
- Delay05s();
- AUXR1 &= 0xbf; //串口切換到 P3.0Rxd P3.1Txd;
- Delay50ms();
- flag=0;
- sendonebyte(0x42);
- _nop_();
- sendonebyte(0x4d);
- _nop_();
- sendonebyte(0xe2);
- _nop_();
- sendonebyte(0x00);
- _nop_();
- sendonebyte(0x00);
- _nop_();
- sendonebyte(0x01);
- _nop_();
- sendonebyte(0x71);
- _nop_();
- }
- void pm25_init()
- {
-
- Delay05s();
- flag=0;
- sendonebyte(0x42);
- _nop_();
- sendonebyte(0x4d);
- _nop_();
- sendonebyte(0xe1);
- _nop_();
- sendonebyte(0x00);
- _nop_();
- sendonebyte(0x00);
- _nop_();
- sendonebyte(0x01);
- _nop_();
- sendonebyte(0x70);
- _nop_();
- }
-
- void hcho_R()
- {
- if((a[0]==0xff)&&(a[1]==0x86))
- {
- zong=((a[2]>>4)*16+(a[2]&0x0f))*256+a[3];
- countnum(zong);
- dxzm(b[3]+0x30,48,0);
- dxzm('.',56,0);
- dxzm(b[2]+0x30,64,0);
- dxzm(b[1]+0x30,72,0);
- dxzm(b[0]+0x30,80,0);
- dxzm('m',88,0);
- dxzm('g',96,0);
- dxzm('/',104,0);
- dxzm('m',112,0);
- location(120,0);
- dis_num86('3');
- }
- }
- void pm25_R()
- {
- if((a[0]==0x42)&&(a[1]==0x4d))
- {
-
- if(a[3]==0x1c)
- {
- pm10i=((a[10]>>4)*16+(a[10]&0x0f))*256+a[11];
- countnum(pm10i);
- if(b[3]==0)
- ;else
- dxzm(b[3]+0x30,48,2);
- if(b[2]==0)
- ;else
- dxzm(b[2]+0x30,56,2);
- if(b[1]==0)
- ;else
- dxzm(b[1]+0x30,64,2);
- dxzm(b[0]+0x30,72,2);
- dxzm('u',80,2);
- dxzm('g',88,2);
- dxzm('/',96,2);
- dxzm('m',104,2);
- location(112,2);
- dis_num86('3');
-
- pm25i=((a[12]>>4)*16+(a[12]&0x0f))*256+a[13];
- countnum(pm25i);
- if(b[3]==0)
- ;else
- dxzm(b[3]+0x30,48,4);
- if(b[2]==0)
- ;else
- dxzm(b[2]+0x30,56,4);
- if(b[1]==0)
- ;else
- dxzm(b[1]+0x30,64,4);
- dxzm(b[0]+0x30,72,4);
- dxzm('u',80,4);
- dxzm('g',88,4);
- dxzm('/',96,4);
- dxzm('m',104,4);
- location(112,4);
- dis_num86('3');
-
-
- pm100i=((a[14]>>4)*16+(a[14]&0x0f))*256+a[15];
- countnum(pm100i);
- if(b[3]==0)
- ;else
- dxzm(b[3]+0x30,48,6);
- if(b[2]==0)
- ;else
- dxzm(b[2]+0x30,56,6);
- if(b[1]==0)
- ;else
- dxzm(b[1]+0x30,64,6);
- dxzm(b[0]+0x30,72,6);
- dxzm('u',80,6);
- dxzm('g',88,6);
- dxzm('/',96,6);
- dxzm('m',104,6);
- location(112,6);
- dis_num86('3');
- }
- }
- }
- void dis_init()
- {
- dxzm('H',8,0);
- dxzm('C',16,0);
- dxzm('H',24,0);
- dxzm('O',32,0);
- dxzm(':',40,0);
-
- dxzm('P',0,2);
- dxzm('M',8,2);
- dxzm('1',16,2);
- dxzm('.',24,2);
- dxzm('0',32,2);
- dxzm(':',40,2);
-
- dxzm('P',0,4);
- dxzm('M',8,4);
- dxzm('2',16,4);
- dxzm('.',24,4);
- dxzm('5',32,4);
- dxzm(':',40,4);
-
-
- dxzm('P',0,6);
- dxzm('M',8,6);
- dxzm('1',16,6);
- dxzm('0',24,6);
- dxzm('.',32,6);
- dxzm(':',40,6);
- }
- void main()
- {
- u8 x;
- Initial_12864();
- clear_12864();
- UartInit();
- dis_init();
-
- Delay05s();
- Delay05s();
-
- pm25_init();
- Delay50ms();
- m=0;
-
-
- while(1)
- {
-
- hcho_T();
- Delay50ms();
- hcho_R();
-
- Delay05s();
-
- pm25_T();
- Delay50ms();
- pm25_R();
-
-
- }
- }
- void Serial_interrupt() interrupt 4
- {
- if((RI==1)&&(flag==1))
- {
- if(n==9)
- n=0;
- a[n]=SBUF; // a為事先定義的接收緩存,可以持續(xù)接收,直到你需要串口數(shù)據(jù)時(shí)來(lái)取為止
- RI=0;//接收中斷信號(hào)清零,表示將繼續(xù)接收
- n++;
- }
-
- if((RI==1)&&(flag==0))
- {
-
- a[m]=SBUF; // a為事先定義的接收緩存,可以持續(xù)接收,直到你需要串口數(shù)據(jù)時(shí)來(lái)取為止
- RI=0;//接收中斷信號(hào)清零,表示將繼續(xù)接收
- m++;
- if(m==32)
- m=0;
- }
-
- }
-
復(fù)制代碼
所有資料51hei提供下載:
12864_ser2019pm.zip
(155.89 KB, 下載次數(shù): 138)
2019-1-18 11:34 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|