|
通過(guò)DS18b20來(lái)測(cè)溫度,在lcd1602上顯示溫度和時(shí)間,時(shí)間初始值設(shè)為18:30,當(dāng)溫度超過(guò)26度時(shí),直流電機(jī)打開(kāi),蜂鳴器報(bào)警,低于26關(guān)閉。也可遙控打開(kāi)或關(guān)閉電機(jī),沒(méi)有使用舵機(jī),此時(shí)直流電機(jī)不能改變方向。
當(dāng)遙控器按下時(shí),lcd1602顯示turn off,無(wú)法顯示溫度,定時(shí)器1初始化,舵機(jī)可以使用,利用舵機(jī)對(duì)直流電機(jī)來(lái)控制方向,只有0,45,90,135,180,五個(gè)角度可以選。
將ds18b20和舵機(jī)分開(kāi)使用的原因,ds18b20對(duì)時(shí)序的要求很高,如果用舵機(jī)的話就會(huì)使溫度無(wú)法正常顯示,
遇到的問(wèn)題:
剛開(kāi)始是直接在main函數(shù)里面使用舵機(jī)和溫度傳感器,發(fā)現(xiàn)溫度顯示不了,然后我想的在main函數(shù)用舵機(jī),然后再用一個(gè)定時(shí)器,每隔一定時(shí)間顯示溫度,這樣用到兩個(gè)定時(shí)器,需要考慮優(yōu)先級(jí),舵機(jī)用定時(shí)器1,溫度用定時(shí)器0,這樣才能每隔一定時(shí)間刷新溫度,但是這樣發(fā)現(xiàn)舵機(jī)和溫度都不能正常工作,我認(rèn)為,因?yàn)槎鏅C(jī)要保持一個(gè)角度話,必須持續(xù)給他該角度下的脈沖,兩個(gè)定時(shí)器可能沖突了,
然后我就將兩個(gè)東西分開(kāi)用,在兩者之間來(lái)回切換,在用完舵機(jī),準(zhǔn)備用18b20的時(shí)候,就令TR1=0;可是這樣做溫度還是顯示不了,而且在關(guān)定時(shí)器的同時(shí),我還重新初始化18b20和lcd1602,還是沒(méi)用,但是如果按下復(fù)位鍵的話,就可以顯示,在網(wǎng)上找了很久也提問(wèn)了沒(méi)有結(jié)果,我試過(guò)用串口打印ds18b20i/o的值,發(fā)現(xiàn)如果沒(méi)切換,可以打印溫度,切換后就沒(méi)有值打印出來(lái),于是我就想能不能在按下遙控上的鍵就執(zhí)行軟件復(fù)位,但是有人說(shuō),51不能軟件復(fù)位,我最后居然想的是,(我看開(kāi)發(fā)板原理圖,發(fā)現(xiàn)復(fù)位鍵按下時(shí),RST管腳就為高電平,RST管腳默認(rèn)為低電平),我用一根杜邦線,一端接在RST上,另一端就隨便接在一個(gè)管腳上P1^1,通過(guò)改變P1^1的電平,來(lái)改變RST的電壓,但是給P1^1高電平的時(shí)候,并沒(méi)有復(fù)位,有人說(shuō),可能是電壓不夠。我分別測(cè)了一下,它的對(duì)地電壓只有2.4v的樣子。
復(fù)位按鍵下兩端的電壓大約4.8v左右,確實(shí)是電壓不不夠,我想升壓,我想起來(lái)有些管腳它是本身開(kāi)發(fā)板就給他加了上拉電阻,看了原理圖,測(cè)了一下其中一個(gè)電壓,果然有4.4v,我把它接到RST的時(shí)候,就復(fù)位了,但是我這樣做發(fā)現(xiàn),在程序中一但執(zhí)行復(fù)位后,它會(huì)一直復(fù)位,比如P3^6=1;//復(fù)位delay(1000);P3^6=0;//P3^6管腳有上拉電阻。在它復(fù)位后,P1^1=0;根本沒(méi)機(jī)會(huì)執(zhí)行;而P3^6默認(rèn)為高電平。這種方法就不行。
我最后就打算手動(dòng)復(fù)位,我準(zhǔn)備加上ds1302,讓1302和溫度同時(shí)顯示,發(fā)現(xiàn)溫度又用不了,我在網(wǎng)上看到有一些人也是同樣的問(wèn)題,但是在一個(gè)論壇里面,有人說(shuō)在1302讀溫度的時(shí)候,在最后,讓CE=1;就可以了,不過(guò)他也不知道原因,百度上顯示ds1302有些是CE,有些是RST,RST是CE的舊稱,我試了一下,發(fā)現(xiàn)可以,而且把之前切換后不能顯示的問(wèn)題也解決了,就是不知道原因。到這里我要做的就基本完成了。
待改進(jìn):
最需要改進(jìn)兩個(gè)地方
1.直流電機(jī)的速度沒(méi)能實(shí)現(xiàn)調(diào)節(jié)
2.舵機(jī)的角度不能為任意角度轉(zhuǎn)動(dòng)
單片機(jī)源程序如下:
- #include "reg52.h"
- #include"temp.h"
- #include"1302.h"
- sbit IRIN=P3^2; //紅外
- sbit duoji=P3^5;
- uchar IrValue[6];//溫度數(shù)組
- uchar zxc,count=0,flag1=1,flag2,k,m;
- uchar Disp[16]="trun off ";
- uchar push_val_left=14,pwm_val_left;
- uint timer=0,flex;
- uchar DisplayData[14]={'t'-0x30,'e'-0x30,'m'-0x30,'p'-0x30,':'-0x30,' '-0x30};
- uchar code smgduan[10]={0,1,2,3,4,5,6,7,8,9};
- void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time)
- {
- push_val_left=5+angle*20/180; //舵機(jī)向左轉(zhuǎn)90度
- // timer=0;
- while(timer<=Servo_time); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置 4000
- delay(flex);
- }
- void pwm_Servomoto(void)
- {
-
- if(pwm_val_left<=push_val_left)
- duoji=1;
- else
- duoji=0;
- if(pwm_val_left>=200)
- pwm_val_left=0;
-
- }
- void datapros(int temp)
- {
- float tp; uint h=4000;
- if(temp< 0) //當(dāng)溫度值為負(fù)數(shù)
- {
- DisplayData[0] = 0x40; // -
- //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5;
-
-
- }
- else
- {
- DisplayData[6] = 0x00;
- tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
- //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
- temp=tp*0.0625*100+0.5;
-
- }
- if(flag2==0)
- if(temp>2600)
- {dj=1;
- while(h)
- {beep=~beep;
- delay(10);
- h--;
- }
- }
- else
- dj=0;
- DisplayData[7] = smgduan[temp / 10000];
- DisplayData[8] = smgduan[temp % 10000 / 1000];
- DisplayData[9] = smgduan[temp % 1000 / 100] ;
- DisplayData[10] = -2;
- DisplayData[11] = smgduan[temp % 100 / 10];
- DisplayData[12] = smgduan[temp % 10];
- DisplayData[13] =51;
-
- }
- void test_servo(void)
- {
- int pos;
- for(pos=0;pos<180;pos+=3)
- {
-
-
- pwm_Servomoto_angle(pos,100) ;
- delay(300);
- }
- for(pos = 180; pos>=0; pos-=3) // goes from 180 degrees to 0 degrees
- {
-
- pwm_Servomoto_angle(pos,100) ;
- delay(300);
- }
- }
-
- void LcdDisplay()
- {
- lcdwrc(0x80+0X40);
- lcdwrd('t');
- lcdwrd('i');
- lcdwrd('m');
- lcdwrd('e');
- lcdwrd(':');
- lcdwrd(' ');
- lcdwrd('0'+hsp[2]/16); //時(shí)
- lcdwrd('0'+(hsp[2]&0x0f));
- lcdwrd('-');
- lcdwrd('0'+hsp[1]/16); //分
- lcdwrd('0'+(hsp[1]&0x0f));
- lcdwrd('-');
- lcdwrd('0'+hsp[0]/16); //秒
- lcdwrd('0'+(hsp[0]&0x0f));
- }
- //外部中斷0初始化
- void IrInit()
- {
- IT0=1;//下降沿觸發(fā)
- EX0=1;//打開(kāi)中斷0允許
- EA=1; //打開(kāi)總中斷
- IRIN=1;//初始化端口
- }
- //定時(shí)器1初始化
- void timeinit()
- {TMOD=0X10;
- TH1=(65536-100)/256; //100US定時(shí)
- TL1=(65536-100)%256;
- TR1= 1;
- ET1= 1;
- EA = 1;
- }
- //main函數(shù)
- void main()
- {uchar i,n=0;
- IrInit(); //紅外初始化
- lcdinit();
- Ds1302Init();
- dj=0;
- while(1)
- {
- if(flag1==1) //關(guān)閉定時(shí)器,實(shí)現(xiàn)功能為超過(guò)設(shè)定溫度打開(kāi)電機(jī)
- {
- Ds1302ReadTime();
- datapros(Ds18b20ReadTemp()); //數(shù)據(jù)處理函數(shù)
- for(i=0;i<14;i++)
- {
- lcdwrd(DisplayData[i]+0x30);
- }
- LcdDisplay();
- lcdwrc(0x80);
- }
- else //打開(kāi)定時(shí)器,(電機(jī)舵機(jī))關(guān)閉溫度傳感器,和lcd1602
- { if(m==0)
- { timeinit();
- m=1;
- dj=0;
- }
- test_servo();
- for(n=0;n<16;n++)
- {
- lcdwrd(Disp[n]);
- }
- lcdwrc(0x80+0x40);
- for(n=0;n<16;n++)
- { lcdwrd(' ');
- }
-
- lcdwrc(0x80);
- }
-
- }
- }
- void ReadIr() interrupt 0
- {
- uchar j,k;
- uchar err;
- zxc=0;
- delay(700); //7ms
- if(IRIN==0) //確認(rèn)是否真的接收到正確的信號(hào)
- {
-
- err=1000; //1000*10us=10ms,超過(guò)說(shuō)明接收到錯(cuò)誤的信號(hào)
-
- while((IRIN==0)&&(err>0)) //等待前面9ms的低電平過(guò)去
- {
- delay(1);
- err--;
- }
- if(IRIN==1) //如果正確等到9ms低電平
- {
- err=500;
- while((IRIN==1)&&(err>0)) //等待4.5ms的起始高電平過(guò)去
- {
- delay(1);
- err--;
- }
- for(k=0;k<4;k++) //共有4組數(shù)據(jù)
- {
- for(j=0;j<8;j++) //接收一組數(shù)據(jù)
- {
- err=60;
- while((IRIN==0)&&(err>0))//等待信號(hào)前面的560us低電平過(guò)去
- {
- delay(1);
- err--;
- }
- err=500;
- while((IRIN==1)&&(err>0)) //計(jì)算高電平的時(shí)間長(zhǎng)度。
- {
- delay(10); //0.1ms
- zxc++;
- err--;
- if(zxc>30)
- {
- return;
- }
- }
- IrValue[k]>>=1; //k表示第幾組數(shù)據(jù)
- if(zxc>=8) //如果高電平出現(xiàn)大于565us,那么是1
- {
- IrValue[k]|=0x80;
- }
- zxc=0; //用完時(shí)間要重新賦值
- }
- }
- }
- if(IrValue[2]!=~IrValue[3])
- {
- return;
- }
- }
- if(flag1==0)
- {
- if(IrValue[2]==0x45) //電源鍵 模式一 過(guò)溫
- {
- flag1=1;
- TR1=0;
- }
- }
-
- if(flag1==1)
- {
- if(IrValue[2]==0x46) //mode 模式二 調(diào)整舵機(jī)
- {
- flag1=0;
- m=0;
- }
- if(IrValue[2]==0x47)
- {dj=1; // 打開(kāi)電機(jī) 注意flag2的作用為設(shè)置為了控制優(yōu)先級(jí)大于if(temp>25)
- flag2=1;
- }
- if(IrValue[2]==0x44) // 關(guān)閉電機(jī)
- {dj=0;
- flag2=0;
- }
- if(IrValue[2]==0x16) //按鍵0 舵機(jī)0度
- flex=550;
- if(IrValue[2]==0x0c) //按鍵1 舵機(jī)45度
- flex=1100;
- if(IrValue[2]==0x18) //按鍵2 舵機(jī)90度
- ;
- if(IrValue[2]==0x5e) //按鍵3 舵機(jī)135度
- ;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
溫控紅外遙控風(fēng)扇.zip
(2.55 MB, 下載次數(shù): 22)
2020-11-26 22:00 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|