#include<reg52.h> #include<intrins.h> #include<math.h> #define u8unsigned char #define u16unsigned int u8 codetable_d[]="Distance: mm"; //顯示界面 u8 codetable_v[]="Velocity: m/s"; u8 codetable1[]="Hello everyone! "; //歡迎界面 u8 codetable2[]=" D/V measurement"; u8 codetable3[]="Set max D:0000mm"; //設(shè)置界面 u8 codetable4[]="Set max V:0.0m/s"; sbittrig=P1^0; // 位定義 定義功能寄存器的位變量 超聲波模塊輸出與輸入端口 sbitecho=P1^1; sbitbeep=P2^3; // 蜂鳴器 sbitdula=P2^6; sbitwela=P2^7; sbitlcdrs=P3^5; // LCD的兩個端口 sbitlcden=P3^4; sbit rd=P3^7; sbitkey1=P3^0; //按鍵的四個口 sbitkey2=P3^1; sbitkey3=P3^2; sbitkey4=P3^3; unsigned longtime0=0; //定義變量類型 longTh0=0,Tl0=0; u8num,keynum=0,task_flag=0; bit TimeUp=0; u16measureresult=0; voiddelayms(u16 xms) //定義一個延時程序 { u16 x,y; for(x=xms;x>0;x--) for(y=80;y>0;y--); } #include"lcd1602.h" void di() //蜂鳴器報警程序 { beep=0; delayms(200); beep=1; } void init() //初始化程序 { TMOD=0x11; //設(shè)T0為方式1,GATE=1; TH0=0; TL0=0; ET0=1; //允許T0中斷 EA=1; //開啟總中斷 trig=0; echo=0; beep=1; //先設(shè)置為不響應(yīng) rd=0; } voidlcd_init1() //液晶初始化 { u8 i,j; write_com(0x80); for(i=0;i<16;i++) { write_data(table_d); delayms(5); } write_com(0x80+0x40); for(j=0;j<16;j++) { write_data(table_v[j]); delayms(5); } } void start() //觸發(fā)超聲波需要至少10us的高頻信號 { trig=1;_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); trig=0; } u16measure(void) //獲取數(shù)據(jù) { bit flag_back=1; trig=0;Th0=0;Tl0=0;TimeUp=0; TR0=0;TH0=0;TL0=0; start(); while(echo==0); TH0=0; TL0=0; TR0=1; //開定時器0 while(flag_back) { if(echo==0||TimeUp==1) { TR0=0;Th0=TH0;Tl0=TL0;TR0=1;flag_back=0; } } while(!TimeUp); time0=Th0*256+Tl0; measureresult=((unsignedlong)(344)*time0)/2000; if(measureresult<30||measureresult>5000){measureresult=0;} return measureresult; } voiddisplay_w() //歡迎界面 { u8 i,j; write_com(0x80); for(i=0;i<16;i++) { write_data(table1); delayms(5); } write_com(0x80+0x40); for(j=0;j<16;j++) { write_data(table2[j]); delayms(5); } } voiddisplay_d() //顯示距離 { u8 qian,bai,shi,ge; u16 S; S=measure(); qian=S/1000; bai=S%1000/100; shi=S%100/10; ge=S%10; write_com(0x80+9); write_data(0x30+qian); write_data(0x30+bai); write_data(0x30+shi); write_data(0x30+ge); } voiddisplay_v() //顯示速度 { u16 S1,S2,delt,v; u8 mi,fen,li; TH1=(65536-50000)/256; //設(shè)置計時 TL1=(65536-50000)%256; ET1=1; S1=measure(); TR1=1; num=10; while(num); TR1=0; S2=measure(); //計時0.5S delt=abs(S1-S2); if(delt<30||delt>4000){delt=0;} v=delt/0.5; //計算出速度 mi=v/1000; fen=v%1000/100; li=v%100/10; write_com(0x80+0x40+9); write_data(0x30+mi); write_data('.'); write_data(0x30+fen); write_data(0x30+li); } voiddisplay() //顯示設(shè)置界面 { display_d(); display_v(); } voidsetting() //進行設(shè)置 { u8 i,j; write_com(0x80); for(i=0;i<16;i++) { write_data(table3); delayms(5); } write_com(0x80+0x40); for(j=0;j<16;j++) { write_data(table4[j]); delayms(5); } } /*****************************************************************/ void task0() //歡迎界面 { display_w(); while(1) { if(key1==0) { delayms(5); if(key1==0) { task_flag=1; //跳轉(zhuǎn)到顯示界面 while(!key1); } } if(task_flag!=0)return; } } /*****************************************************************/ void task1() //顯示界面 { write_com(0x0c); lcd_init1(); while(1) { display(); if(key1==0) { delayms(5); if(key1==0) { task_flag=2; while(!key1); } } if(task_flag!=1)return; } } /*****************************************************************/ void task2() //設(shè)置界面 { u8 sq=0,sb=0,ss=0,sg=0; u16 Sa=0,Sb=0; setting(); while(1) { if(key2==0) //消抖 { delayms(5); if(key2==0) { keynum++; while(!key2); if(keynum==1) //光標(biāo)在千位 { write_com(0x80+10); write_com(0x0f); } if(keynum==2) //光標(biāo)在百位 { write_com(0x80+11); } if(keynum==3) //光標(biāo)在十位 { write_com(0x80+12); } if(keynum==4) //光標(biāo)在個位 { write_com(0x80+13); } if(keynum==5) //回零 { keynum=0; write_com(0x0c); } } } if(keynum!=0) //光標(biāo)在閃爍時 { if(key3==0) //KEY3 KEY4可以工作 { delayms(5); if(key3==0) { while(!key3); if(keynum==1) //千位時可以對千位進行編輯 進行加操作 { sq++; if(sq==10)sq=0; write_com(0x80+10); write_data(0x30+sq); write_com(0x80+10); } if(keynum==2) //對百位進行編輯 { sb++; if(sb==10)sb=0; write_com(0x80+11); write_data(0x30+sb); write_com(0x80+11); } if(keynum==3) //對十位進行編輯 { ss++; if(ss==10)ss=0; write_com(0x80+12); write_data(0x30+ss); write_com(0x80+12); } if(keynum==4) //對個位進行編輯 { sg++; if(sg==10)sg=0; write_com(0x80+13); write_data(0x30+sg); write_com(0x80+13); } } } if(key4==0) //進行減操作 { delayms(5); if(key4==0) { while(!key4); if(keynum==1) { if(sq==0)sq=10; sq--; write_com(0x80+10); write_data(0x30+sq); write_com(0x80+10); } if(keynum==2) { if(sb==0)sb=10; sb--; write_com(0x80+11); write_data(0x30+sb); write_com(0x80+11); } if(keynum==3) { if(ss==0)ss=10; ss--; write_com(0x80+12); write_data(0x30+ss); write_com(0x80+12); } if(keynum==4) { if(sg==0)sg=10; sg--; write_com(0x80+13); write_data(0x30+sg); write_com(0x80+13); } } } } if(key4==0) //檢測KEY4是否按下 { delayms(5); if(key4==0) { while(!key4); //當(dāng)KEY4按下時檢測是否報警 Sa=sq*1000+sb*100+ss*10+sg; //設(shè)定的值 while(1) { Sb=measure(); //測到的數(shù)值 if(Sa>Sb)di(); //在設(shè)置的范圍內(nèi)則報警 if(key4==0)return; } } } if(key1==0) { delayms(5); if(key1==0) { task_flag=0; //回到歡迎界面 while(!key1); } } if(task_flag!=2)return; } } /*****************************************************************/ void main() //主函數(shù) { init(); lcd_init(); //LCD初始化 while(1) { if(task_flag==0)task0(); else if(task_flag==1)task1(); else if(task_flag==2)task2(); } } /*****************************************************************/ void time_0()interrupt 1 // 定時器溢出 { TimeUp=1; } void time_1()interrupt 3 // 用來計算0.5S { TH1=(65536-50000)/256; TL1=(65536-50000)%256; num--; } void write_com(u8com) //寫指令 { lcdrs=0; P0=com; lcden=0; delayms(3); lcden=1; delayms(3); lcden=0; } voidwrite_data(u8 date) //寫數(shù)據(jù) { lcdrs=1; P0=date; lcden=0; delayms(3); lcden=1; delayms(3); lcden=0; delayms(1); } voidlcd_init() { dula=0; wela=0; lcden=0; write_com(0x38); //顯示模式 write_com(0x0c); //開顯示/不顯光標(biāo) write_com(0x06); //讀寫一個后地址指針及光標(biāo)加1 write_com(0x01); //顯示清0,指針清0 }
|