#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"; //设置界面 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; //设T0为方式1,GATE=1; TH0=0; TL0=0; ET0=1; //允许T0中断 EA=1; //开启总中断 trig=0; echo=0; beep=1; //先设置为不响应 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() //触发超声波需要至少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) //获取数据 { 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; //设置计时 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() //显示设置界面 { display_d(); display_v(); } voidsetting() //进行设置 { 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; //跳转到显示界面 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() //设置界面 { 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) //光标在千位 { write_com(0x80+10); write_com(0x0f); } if(keynum==2) //光标在百位 { write_com(0x80+11); } if(keynum==3) //光标在十位 { write_com(0x80+12); } if(keynum==4) //光标在个位 { write_com(0x80+13); } if(keynum==5) //回零 { keynum=0; write_com(0x0c); } } } if(keynum!=0) //光标在闪烁时 { 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); //当KEY4按下时检测是否报警 Sa=sq*1000+sb*100+ss*10+sg; //设定的值 while(1) { Sb=measure(); //测到的数值 if(Sa>Sb)di(); //在设置的范围内则报警 if(key4==0)return; } } } if(key1==0) { delayms(5); if(key1==0) { task_flag=0; //回到欢迎界面 while(!key1); } } if(task_flag!=2)return; } } /*****************************************************************/ void main() //主函数 { 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) //写数据 { 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); //开显示/不显光标 write_com(0x06); //读写一个后地址指针及光标加1 write_com(0x01); //显示清0,指针清0 }
|