|
避障智能小车电路原理图如下:
单片机
单片机源程序如下:
- 附录B
- 按照预定的功能,系统实现预定的功能的程序如下所示:
- #include <intrins.h>
- #include <AT89X52.h>
- /********************************************************************************\
- ** 宏定义区 **
- \********************************************************************************/
- /*------------------------------- LCD模块 ------------------------------------*/
- #define LCD_RW P2_6 //读写控制端
- #define LCD_RS P2_7 //数据命令选择端
- #define LCD_E P2_5 //执行使能端
- #define LCD_Data P1 //P1口
- #define Write 0x00 //低电平写入
- #define Read 0x01 //高电平读出
- #define Data 0x01 //高电平选择数据
- #define Cmd 0x00 //低电平选择命令
- #define Enable 0x00 //跃变到低电平时执行命令
- #define Disable 0x01
- #define True 0x01
- #define False 0x00
- #define LCD_Init 0x38 //初始化模式
- #define LCD_DispCtr 0x0C //开显示及光标设置
- #define LCD_CloseCtr 0x08 //关显示
- #define LCD_CLS 0x01 //清屏幕
- #define LCD_EnterSet 0x06 //显示光标
- #define Busy P1_7 //忙信号
- /*-------------------------- 测速/测距/测时模块 -------------------------------*/
- #define CircleLength 0.132 //小车转一轮的长度为.132m
- /*-------------------------------- 控速模块 -----------------------------------*/
- #define P03 P0_3 //后电机
- #define P04 P0_4 //后电机
- #define P01 P0_1 //前电机
- #define P02 P0_2 //前电机
- #define P31 P0_5 //控制液晶背光
- #define P33 P3_3
- /*------------------------------ 菜单选择模块 ---------------------------------*/
- #define Line 0x00 //0代表直线模式
- #define Curve 0x01 //1代表S型模式
- #define Normal 0x00 //0 代表正常速度
- #define Low 0x01 //1 代表低速
- #define High 0x02 //2 代表高速
- /*********************************************************************************\
- ** 全局函数声明区 **
- \*********************************************************************************/
- /*------------------------------- LCD模块 -------------------------------------*/
- void LCDInit(void); //LCD初始化
- void SetWriteCmd(void); //设置写命令模式
- void SetReadCmd(void); //设置读命令模式
- void SetWriteData(void); //设置写数据模式
- void WriteCmd(char cmd); //写命令
- void WriteData(char ddata); //写数据
- void ExecuteCmd(void); //执行命令
- void SetXY(char x,char y); //定位显示地址
- void DisplaySingleChar(char x,char y,char cchar); //显示单个字符
- void DisplayString(char x,char y,char *str); //显示一段字符串
- void Delay(unsigned int time); //延时主程序
- void DelayUs(unsigned int time); //延时子程序
- bit IsBusy(void); //判断忙标志函数
- void DisplayTime(void); //显示时间
- void DisplayAVGSpeed(void); //显示平均速度
- void DisplayDistance(void); //显示路程
- /*-------------------------- 测速/测距/测时模块 -------------------------------*/
- void INTInit(void); //所有中断初始化
- void SpeedINT(void); //测速中断
- void ComputeTime(void);
- void ComputeSpeedANDDistance(void); //计算速度和距离
- /*-------------------------------- 控速模块 -----------------------------------*/
- void CtrSpeedINT(void); //控速中断
- void Time0INT(void);
- void Time1INT(void); //控速单位时间中断
- void Clock0_Init(void); //时钟中断初始化
- void Clock1_Init(void); //时钟中断初始化
- void CtrSpeed(void);
- /********************************************************************************\
- ** 全局变量区 **
- \********************************************************************************/
- float SpeedCount = 0; //测速计数脉冲
- float Speed = 0.0;
- float Distance = 0.0;
- char Time1INTCount=0; //T1中断时间计时
- float PassTime=0.00; //小车行走的时间
- short IsT0INT=1;
- bit IsT1INT; //判断T1是否已经响应中断
- short IsT0INT2=1;
- char Thx[5]={0xf4,0xf4,0xc5,0xf4,0xff}; //3ms,3ms,15ms,3ms
- char Tlx[5]={0x48,0x48,0x68,0x48,0xff};
- char Thx0=0xd8;
- char Tlx0=0xf0;
- char Thx1=0xb1; //20ms
- char Tlx1=0xe0;
- short Round=0;
- short Back=0;
- short Back0=0;
- bit Backid;
- bit Stop=0;
- char Area0=0;
- char Area1=0; //区域变量
- char LowSpeedArea1StartTime;
- char LowSpeedArea1EndTime;
- char HighSpeedAreaEndTime;
- char LowSpeedArea2EndTime;
- char LowSpeedArea1PassTime=0; //第一个低速区通过时间
- char HighSpeedAreaPassTime=0; //高速区通过时间
- char LowSpeedArea2PassTime=0; //第二个低速区通过时间
- char ReadyToGo=4; //倒计时
- char flag;
- bit Roundid=0;
- char Nocurve=0;
- char ChangeFlag;
- char Mode;
- bit Running;
- bit SelectedAll; //模式和速度是否选择完毕标志
- bit IsSelectingMode; //模式选择标志
- bit IsSelectingSpeed; //速度选择标志
- bit ModeSelected; //已经被选择的模式标志
- char SelectedMode=10; //模式选择是否完毕标志
- bit Next; //Next键标志
- bit SpeedSelected; //已经被选中的速度方案标志
- char SelectedSpeed; //速度选择是否完毕标志
- bit ChoosingDisplay; //人工选择菜单开始标志
- bit SelectedShow; //显示选择标志
- bit SelectedReturn; //返回选择标志
- bit Selected; //确定/返回键选择标志
- bit ReturnSelection; //返回键启用标志
- bit AVGSpeedShow; //平均速度显示标志
- bit TotalDistanceShow; //总路程显示标志
- bit ReturnMain; //返回主菜单标志
- bit AutoDisplay; //自动显示标志
- bit GoToChoosingDisplay; //人工选择标志
- bit AutoMode=0;
- char PassLineID=0;
- char PassLine=0;
- float PrepareDistance;
- float FirstDistance;
- float SecondDistance;
- float ThirdDistance;
- int FirstHigh;
- int SecondHigh;
- int ThirdHigh;
- float Rate=1.25; //5ms时的速度
- float Count=4; //时间的倍数
- /********************************************************************************\
- ** 全局函数实现区 **
- \********************************************************************************/
- /*-------------------------------- 主函数 ------------------------------------*/
- void main()
- {
- P01=0;
- P02=0;
- P03=0;
- P04=0;
- P31=1; //单片机复位,背光开
- Delay(40); //延时等待LCD启动
- LCDInit(); //初始化LCD
- DisplayString(0x0,0," Starting... ");
- DisplayString(0x0,1,"Designed By 202");
- Delay(300);
- WriteCmd(LCD_CLS);
-
- EA=1; //开总中断
- EX0=1; //开INT0中断
- IT0=1; //INTO边沿触发
- EX1=1; //开INT1中断
- IT1=1; //INT1边沿触发
- SelectedAll=False; //开始模式和速度选择
-
- /*------------------------------ 模式选择 ---------------------------------*/
- DisplayString(0x0,0,"Choose The Mode ");
- DisplayString(0x0,1,"you want. ");
- Delay(50);
- WriteCmd(LCD_CLS);
-
- IsSelectingMode=True;
- while(1)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Line Mode ");
- DisplayString(0x0,1,"Next Yes");
- Delay(300); //延时消除抖动
- while (1) //不断检测中断,直到按确定键或是NEXT键
- {
- if (Next==True) //如果按Next键则直接跳出
- break;
- if (ModeSelected==True) //如果按确定键则设置模式为Line并跳出
- {
- SelectedMode=Line;
- break;
- } //如果什么键都没有按下,那么一直显示等待
- }
- if (ModeSelected==True) //按下了确定键,退出模式选择
- {
- IsSelectingMode=False;
- break;
- }
- if (Next==True) //按下了Next键,显示下一个菜单项
- {
- Next=False;
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Curve Mode ");
- DisplayString(0x0,1,"Next Yes");
-
- Delay(300); //延时消除抖动
- while(1) //不断检测中断,直到按确定键或是Next键
- {
- if (Next==True) //如果再一次按下Next键,则跳出
- break;
- if (ModeSelected==True) //如果按下确定键,则设置模式为Curve,并跳出
- {
- SelectedMode=Curve;
- break;
- }
- }
- }
-
- if (ModeSelected==True) //按下了确定键,退出模式选择
- {
- IsSelectingMode=False;
- break;
- }
- if (Next==True) //再一次按下了Next键,则循环模式选择
- {
- Next=False;
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," AutoMode ");
- DisplayString(0x0,1,"Next Yes");
- Delay(300); //延时消除抖动
- while(1)
- {
- if (Next==True)
- break;
- if (ModeSelected==True)
- {
- AutoMode=1;
- break;
- }
- }
- }
- if (ModeSelected==True)
- {
- IsSelectingMode=False;
- break;
- }
- if (Next==True)
- {
- Next=False;
- continue;
- }
- }
-
- Delay(50);
- WriteCmd(LCD_CLS);
-
- /*------------------------------ 速度选择 ---------------------------------*/
- if (SelectedMode==Line && AutoMode==0)
- {
- DisplayString(0x0,0," Now Choose a ");
- DisplayString(0x0,1," kind of Speed ");
- Delay(50);
- WriteCmd(LCD_CLS);
-
- IsSelectingSpeed=True;
- while(1)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Normal Speed ");
- DisplayString(0x0,1,"Next Yes");
- Delay(300); //延时消除抖动
-
- while(1)
- {
- if (Next==True) //如果按Next键则直接跳出
- break;
- if (SpeedSelected==True) //如果按确定键则设置速度为Normal并跳出
- {
- Thx[0]=0xec;Tlx[0]=0x78; //5ms
- Thx[1]=0xf0;Tlx[1]=0x60; //4ms
- Thx[2]=0x8a;Tlx[2]=0xd0; //30ms
- Thx[3]=0xf4;Tlx[3]=0x48; //3ms
- SelectedSpeed=Normal;
- break;
- } //如果什么键都没有按下,那么一直显示等待
- }
-
- if (SpeedSelected==True) //按下了确定键,退出速度选择
- {
- IsSelectingSpeed=False;
- break;
- }
-
- if (Next==True)
- {
- Next=False;
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Low Speed ");
- DisplayString(0x0,1,"Next Yes");
-
- Delay(300); //延时消除抖动
- while(1)
- {
- if (Next==True) //如果再一次按下Next键,则跳出
- break;
- if (SpeedSelected==True) //如果按下确定键,则设置速度为Low,并跳出
- {
- SelectedSpeed=Low; //这里没有速度设置,因为默认速度就是Low
- break;
- }
- }
- }
-
- if (SpeedSelected==True) //按下了确定键,退出速度选择
- {
- IsSelectingSpeed=False;
- break;
- }
-
- if (Next==True)
- {
- Next=False;
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," High Speed ");
- DisplayString(0x0,1,"Next Yes");
- Delay(300); //延时消除抖动
-
- while(1)
- {
- if (Next==True) //如果再一次按下Next键,则跳出
- break;
- if (SpeedSelected==True) //如果按下确定键,则设置速度为High,并跳出
- {
- Thx[0]=0xe0;Tlx[0]=0xc0; //8ms
- Thx[1]=0xe0;Tlx[1]=0xc0; //8ms
- Thx[2]=0x63;Tlx[2]=0xc0; //40ms
- Thx[3]=0xec;Tlx[3]=0x78; //5ms
- SelectedSpeed=High;
- break;
- }
- }
- }
-
- if (SpeedSelected==True) //按下了确定键,退出速度选择
- {
- IsSelectingSpeed=False;
- break;
- }
-
- if (Next==True) //再一次按下了Next键,则循环速度选择
- {
- Next=False;
- continue;
- }
-
- }
- }
- SelectedAll=True; //标志模式选择和速度选择完毕
-
- Running=True;
- Delay(50);
- WriteCmd(LCD_CLS);
-
- /*------------------------- 显示所选择的模式和速度方案 -------------------------*/
- if (SelectedMode==Line)
- {
- DisplayString(0x0,0,"Choosen Mode is ");
- DisplayString(0x0,1," Line ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
- if (SelectedMode==Curve)
- {
-
- DisplayString(0x0,0,"Choosen Mode is ");
- DisplayString(0x0,1," Curve ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
- if (AutoMode==1)
- {
- DisplayString(0x0,0,"Choosen Mode is ");
- DisplayString(0x0,1," AutoMode ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
- if (SelectedMode==Line)
- {
- if (SelectedSpeed==Normal)
- {
- DisplayString(0x0,0,"Choosen Speed is");
- DisplayString(0x0,1," Normal ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
-
- if (SelectedSpeed==Low)
- {
- DisplayString(0x0,0,"Choosen Speed is");
- DisplayString(0x0,1," Low ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
-
- if (SelectedSpeed==High)
- {
- DisplayString(0x0,0,"Choosen Speed is");
- DisplayString(0x0,1," High ");
- Delay(50);
- WriteCmd(LCD_CLS);
- }
- }
- INTInit(); //初始化所有中断
- DisplayString(0x0,0,"Left Times To Go");
- while (ReadyToGo--)
- {
- DisplaySingleChar(0x7,1,ReadyToGo+0x30);
- DisplaySingleChar(0x09,1,'s');
- Delay(300);
- }
- WriteCmd(LCD_CLS);
- DisplayString(0x05,0,"Go!!!");
- Delay(100);
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Living... ");
- DisplayString(0x0,1,"Designed by 202");
-
- if (SelectedMode==Line&&AutoMode==0)
- flag=Area0;
- else
- flag=1;
-
- while(flag<5)
- {
- if(AutoMode==1) //自动模式
- {
- switch(PassLineID)
- {
- case 0 :{
- if(IsT0INT==1)
- {P01=P02=P04=0;P03=1;}
- else
- {P01=P02=P03=P04=0;}
- }break;
- case 1 :{
- P01=P02=P03=0;P04=1;
- }break;
- case 2 :{
- P01=P02=P04=0;P03=1;
- }break;
- default :break;
- }
- }
- else
- {
- if(SelectedMode==Line) //直线模式
- {
- flag=Area0;
- if(IsT0INT==1)
- {P03=1;P04=0;P01=P02=0;}
- else
- {P03=0;P04=0;P01=P02=0;}
- }
- else
- { //S型模式
- if((Nocurve<2)&&Round!=0&&(Back0>0)&&Back!=0)
- {
- if(Backid==1)
- {P01=1;P02=0;P03=0;P04=1;}
- else
- {P01=0;P02=1;P03=0;P04=1;}
- Back=1;
- }
- else
- {
- if(Round==0)
- {
- if(IsT0INT2==1)
- {P01=0;P02=0;P03=1;P04=0;}
- else
- {P01=0;P02=0;P03=0;P04=0;}
- }
- else
- {
- if(P33==0)
- {
- if(IsT0INT2==1)
- {P01=0;P02=0;P03=1;P04=0;}
- else
- {P01=0;P02=0;P03=0;P04=0;}
- }
- else
- {
- EX1=1;
- if(Round%2)
- {
- if(IsT0INT2==1)
- {P01=1;P02=0;P03=1;P04=0;Backid=1;}
- else
- {P01=1;P02=0;P03=0;P04=0;}
- }
- else
- {
- if(IsT0INT2==1)
- {P01=0;P02=1;P03=1;P04=0;Backid=0;}
- else
- {P01=0;P02=1;P03=0;P04=0;}
- }
- }
- }
- }
- }
- }
-
- if (IsT1INT==1)
- {
- IsT1INT=0;
- ComputeTime();
- ComputeSpeedANDDistance();
- }
- }
-
- //补中断路程,加上最后一次中断缺失的路程
- ComputeSpeedANDDistance();
- P04=1;P03=0;P01=P02=0;Delay(90);
- P03=0;P04=0; //行程结束,小车停止
- P31=1; //行程结束,背光开
- ET0=0x0; //关T0中断
- ET1=0x0; //关T1中断
- EX1=0x01; //开INT1中断
- Running=False;
-
-
- AutoDisplay=True; //默认情况下直线模式会自动显示各个区域经过的时间
- WriteCmd(LCD_CLS);
-
- if (SelectedMode==Line) //直线模式才显示
- {
- while(1)
- {
- if (GoToChoosingDisplay==True)
- break;
- Delay(200);
- WriteCmd(LCD_CLS);
- Delay(200);
- DisplayString(0,0," LowSpeedArea1");
- DisplayString(0,1," Costed ");
- DisplaySingleChar(0x0C,1,'s');
- LowSpeedArea1PassTime=LowSpeedArea1EndTime-LowSpeedArea1StartTime;
- DisplaySingleChar(0x0A,1,LowSpeedArea1PassTime%10+0x30);
- if (LowSpeedArea1PassTime > 9) //通过第一个低速区的时间超过s
- DisplaySingleChar(0x0B,1,LowSpeedArea1PassTime/10+0x30);
-
- if (GoToChoosingDisplay==True)
- break;
- Delay(200);
- WriteCmd(LCD_CLS);
- Delay(200);
- DisplayString(0,0," HighSpeedArea ");
- DisplayString(0,1," Costed ");
- DisplaySingleChar(0x0C,1,'s');
- HighSpeedAreaPassTime=HighSpeedAreaEndTime-LowSpeedArea1EndTime;
- DisplaySingleChar(0x0A,1,HighSpeedAreaPassTime%10+0x30);
- if ( HighSpeedAreaPassTime> 9) //通过高速区的时间超过s
- DisplaySingleChar(0x0B,1,HighSpeedAreaPassTime/10+0x30);
-
- if (GoToChoosingDisplay==True)
- break;
- Delay(200);
- WriteCmd(LCD_CLS);
- Delay(200);
- DisplayString(0,0," LowSpeedArea2 ");
- DisplayString(0,1," Costed ");
- DisplaySingleChar(0x0C,1,'s');
- LowSpeedArea2PassTime=LowSpeedArea2EndTime-HighSpeedAreaEndTime;
- DisplaySingleChar(0x0A,1,LowSpeedArea2PassTime%10+0x30);
- if ( LowSpeedArea2PassTime> 9) //通过第二个低速区的时间超过s
- DisplaySingleChar(0x0B,1,LowSpeedArea2PassTime/10+0x30);
- }
- }
-
- AutoDisplay=False;
- /*---------------- 菜单选择你想要看的内容--总时间、总路程以及平均速度 --------------*/
- ChoosingDisplay=True;
- WriteCmd(LCD_CLS);
- /*首先显示主菜单,然后显示第一个选项*/
- DisplayString(0x0,0,"Now Choose what ");
- DisplayString(0x0,1,"you want to see ");
- Delay(100);
- while(1)
- {
-
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Costed Time ");
- DisplayString(0x0,1,"Next Show");
- Delay(250); //延时消除抖动
- /*------------------------------------第一次按键--------------------------------------*/
-
- /*不断检测确定键和Next键*/
- while(1)
- {
- if (Next==True)
- break;
- if (SelectedShow==True)
- break;
- }
- /*按下了确定键,显示第一个选项的内容*/
- if (SelectedShow==True)
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"Costed Time is");
- DisplayTime();
- DisplayString(0x0A,1,"s");
- ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能
- AVGSpeedShow=False;
- Delay(250); //延时消除抖动
- }
- /**按下了Next键,则显示第二个选项*/
- if (Next==True) //按下Next键,显示AVGSpeed菜单项
- {
- Next=False;
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," AVGSpeed ");
- DisplayString(0x0,1,"Next Show");
- ReturnMain=False;
- ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能
- AVGSpeedShow=True; //表明AVGSpeed选项已经显示过了
- Delay(250); //延时消除抖动
- }
- /*------------------------------------第二次按键--------------------------------------*/
- /*显示第一个选项的内容后又不断检测返回键(确定键)和Next键*/
- while(1)
- {
- if (Next==True)
- break;
- if (Selected==True)
- break;
- }
-
- if (Next==True)
- {
- Next=False;
- ReturnMain=False;
- ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能
- if (AVGSpeedShow==False) //还没有显示AVGSpeed选项,显示它
- { //即第一次选择了确定键
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," AVGSpeed ");
- DisplayString(0x0,1,"Next Show");
- TotalDistanceShow=False; //显示了AVGSpeed,则表明TotalDistance还没有显示
-
- Delay(250); //延时消除抖动
- }
- if (AVGSpeedShow==True) //已经显示过AVGSpeed选项了,则显示下一个选项
- { //即第一次选择了Next键
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Total Distance ");
- DisplayString(0x0,1,"Next Show");
- TotalDistanceShow=True; //表明显示了TotalDistance选项
- Delay(250); //延时消除抖动
- }
- }
- if (Selected==True) //按下了确定键或返回键
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- if (ReturnSelection==True) //第一次选择了确定键,故这次按下的是返回键
- ReturnMain=True;
- if (ReturnSelection==False)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"The AVGSpeed is");
- DisplayAVGSpeed();
- DisplayString(0x0A,1,"m/s");
- ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能
-
- Delay(250); //延时消除抖动
- }
- TotalDistanceShow=False;
- }
- if (ReturnMain==True) //按下了返回键,返回主菜单
- {
- ReturnMain=False;
- continue;
- }
- /*------------------------------------第三次按键--------------------------------------*/
- /*如果没有返回主菜单,则继续检测Next键和确定键*/
-
- while(1)
- {
- if (Next==True)
- break;
- if (SelectedShow==True)
- break;
- }
-
- /*按下Next键,显示下一个选项*/
- if (Next==True)
- {
- Next=False;
- ReturnMain=False;
- ReturnSelection=False; //按下了Next键,那么这个时候关闭返回键的功能
- if (TotalDistanceShow==True)
- ReturnMain=True;
- if (TotalDistanceShow==False) //还没有显示TotalDistance选项,显示它
- {
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Total Distance ");
- DisplayString(0x0,1,"Next Show");
- TotalDistanceShow=True;
-
- Delay(250); //延时消除抖动
- }
- }
- if (Selected==True) //按下了确定键或返回键
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- if (ReturnSelection==True) //按下的是返回键
- ReturnMain=True;
- if (ReturnSelection==False)
- {
- if (TotalDistanceShow==False) //表明AVGSpeed选项的内容还没有显示
- {
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"The AVGSpeed is");
- DisplayAVGSpeed();
- DisplayString(0x0A,1,"m/s");
- ReturnSelection=True;
- Delay(250); //延时消除抖动
- }
- if (TotalDistanceShow==True)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"Total Distance");
- DisplayDistance();
- DisplayString(0x0A,1,"m");
- ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能
- Delay(250); //延时消除抖动
- }
- }
- }
- if (ReturnMain==True) //按下了返回键,返回主菜单
- {
- ReturnMain=False;
- continue;
- }
- /*------------------------------------第四次按键--------------------------------------*/
- while(1)
- {
- if (Next==True)
- break;
- if (SelectedShow==True)
- break;
- }
-
- if (Next==True) //所有菜单项已经显示完毕,返回主菜单
- {
- Next=False;
- ReturnMain=False;
- ReturnSelection=False;
- if (TotalDistanceShow==False)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0x0,0," Total Distance ");
- DisplayString(0x0,1,"Next Show");
- TotalDistanceShow=True;
-
- Delay(250); //延时消除抖动
- }
- }
- if (SelectedShow==True)
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- if (ReturnSelection==True) //按下的是返回键
- ReturnMain=True;
- if (ReturnSelection==False)
- {
- if (TotalDistanceShow==True)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"Total Distance");
- DisplayDistance();
- DisplayString(0x0A,1,"m");
- ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能
- Delay(250); //延时消除抖动
- }
- }
- }
-
- if (ReturnMain==True) //按下了返回键,返回主菜单
- {
- ReturnMain=False;
- continue;
- }
- /*------------------------------------第五次按键--------------------------------------*/
- while(1)
- {
- if (Next==True)
- break;
- if (SelectedShow==True)
- break;
- }
- if (Next==True) //所有菜单项已经显示完毕,返回主菜单
- {
- Next=False;
- ReturnMain=False;
- ReturnSelection=False;
- if (TotalDistanceShow==True) //最后一个选项已经显示完毕,返回主菜单
- {
- ReturnMain=True;
- }
- }
-
- if (SelectedShow==True)
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- if (ReturnSelection==True) //按下的是返回键
- ReturnMain=True;
- if (ReturnSelection==False)
- {
- if (TotalDistanceShow==True)
- {
- WriteCmd(LCD_CLS);
- DisplayString(0,0,"Total Distance");
- DisplayDistance();
- DisplayString(0x0A,1,"m");
- ReturnSelection=True; //按下了确定键,那么这个时候开启返回键的功能
- Delay(250); //延时消除抖动
- }
- }
- }
- /*------------------------------------第六次按键--------------------------------------*/
- while(1)
- {
- if (Next==True)
- break;
- if (SelectedShow==True)
- break;
- }
- if (Next==True)
- {
- Next=False;
- ReturnMain=False;
- ReturnSelection=False;
- }
- if (SelectedShow==True)
- {
- SelectedShow=False;
- SelectedReturn=False;
- Selected=False;
- }
- continue;
- }
- while(1);
- }
- /****************************************************************************************\
- ** LCD驱动模块 **
- \****************************************************************************************/
- /*--------------------------------- LCD初始化函数--------------------------------------*/
- void LCDInit(void)
- {
- //三次显示模式设置
- LCD_Data=0;
- LCD_E=Disable;
- Delay(5);
- WriteCmd(LCD_Init);
- Delay(5);
- WriteCmd(LCD_Init);
- Delay(5);
- WriteCmd(LCD_Init);
- WriteCmd(LCD_Init); //初始化
- WriteCmd(LCD_CloseCtr); //关显示
- WriteCmd(LCD_CLS); //清屏幕
- WriteCmd(LCD_EnterSet); //光标移动设置
- WriteCmd(LCD_DispCtr); //显示开以及光标设置
-
- }
- /*--------------------------------- LCD模式设置函数--------------------------------------*\
-
- SetWriteCmd() 设置LCD为写命令模式
- SetReadCmd() 设置LCD为读命令模式
- SetWriteData() 设置LCD为写数据模式
-
- \*----------------------------------------------------------------------------------------*/
- void SetWriteCmd(void)
- {
- LCD_RW=Write;
- LCD_RS=Cmd;
- }
- void SetReadCmd(void)
- {
- LCD_RW=Read;
- LCD_RS=Cmd;
- }
- void SetWriteData(void)
- {
- LCD_RW=Write;
- LCD_RS=Data;
- }
- /*--------------------------------- LCD功能执行函数--------------------------------------*\
-
- WriteCmd() 写命令
- WriteData() 写数据
- ExecuteCmd() 执行命令
- SetXY() 显示定位
- DisplaySingleChar() 显示单个字符
- DisplayString() 显示一串字符
- IsBusy() 忙标志检测
- \*----------------------------------------------------------------------------------------*/
- void WriteCmd(char cmd)
- {
- while(IsBusy());
- LCD_Data=cmd;
- SetWriteCmd();
- ExecuteCmd();
- }
- void WriteData(char ddata)
- {
- while(IsBusy());
- LCD_Data=ddata;
- SetWriteData();
- ExecuteCmd();
- }
- void ExecuteCmd(void)
- {
- LCD_E=Enable;
- LCD_E=Disable;
- }
- void SetXY(char x,char y)
- {
- if (y)
- x|=0x40;
- x|=0x80;
- Delay(5);
- WriteCmd(x);
- }
- void DisplaySingleChar(char x,char y,char cchar)
- {
- SetXY(x,y);
- WriteData(cchar);
- }
- void DisplayString(char x,char y,char *str)
- {
- while(*str)
- {
- Delay(5);
- DisplaySingleChar(x++,y,*str);
- str++;
- }
- }
- bit IsBusy(void)
- {
- LCD_Data=0xFF;
- SetReadCmd();
- ExecuteCmd();
- return (bit)(P1 & 0x80);
- }
- /*------------------------------------- 延时函数 -------------------------------------*/
- void Delay(unsigned int time)
- {
- unsigned int timeCounter = 0;
- for (timeCounter = time;timeCounter > 0 ;timeCounter --)
- DelayUs(255);
- }
- void DelayUs(unsigned int time)
- {
- unsigned int timeCounter = 0;
- for (timeCounter = 0;timeCounter < time;timeCounter ++)
- _nop_();
- }
- /*******************************************************************************************\
- ** LCD显示模块 **
- \*******************************************************************************************/
- void ComputeTime(void)
- {
- if (Area0 < 5)
- PassTime+=0.5;
- }
- void ComputeSpeedANDDistance(void)
- {
- Speed=SpeedCount/4*CircleLength; //计算瞬时速度
- Distance+=Speed; //计算距离
- SpeedCount=0;
-
- }
- /*------------------------------------- 显示时间 ----------------------------------------*/
- void DisplayTime(void)
- {
- char PassTime1=0x30;
- char PassTime2=0x30;
- char PassTime3=0x30;
- char PassTime4=0x30;
-
- if ((int)PassTime*100<100) //时间未够1s
- {
- PassTime1+=0;
- PassTime2+=(int)(PassTime*100)/10;
- PassTime3+=(int)(PassTime*100)%10;
- }
- else if ((int)(PassTime*100) > 100 && (int)(PassTime*100) < 1000) //够1s而未够10s
- {
- PassTime1+=(int)(PassTime*100)/100;
- PassTime2+=(int)(PassTime*100)/10%10;
- PassTime3+=(int)(PassTime*100)%10;
- }
- else
- {
- PassTime1+=(int)(PassTime*100)/1000;
- PassTime2+=(int)(PassTime*100)/100%10;
- PassTime3+=(int)(PassTime*100)/10%10;
- PassTime4+=(int)(PassTime*100)%10;
- }
- if ((int)(PassTime*100) < 1000)
- {
- DisplaySingleChar(0x05,1,PassTime1);
- DisplaySingleChar(0x06,1,'.');
- DisplaySingleChar(0x07,1,PassTime2);
- DisplaySingleChar(0x08,1,PassTime3);
- }
- else
- {
- DisplaySingleChar(0x04,1,PassTime1);
- DisplaySingleChar(0x05,1,PassTime2);
- DisplaySingleChar(0x06,1,'.');
- DisplaySingleChar(0x07,1,PassTime3);
- DisplaySingleChar(0x08,1,PassTime4);
- }
-
-
- }
- /*------------------------------------ 显示平均速度----------------------------------------*/
- void DisplayAVGSpeed(void)
- {
- int Speed1=0x30; //初始化为0的ASCII码
- int Speed2=0x30;
- int Speed3=0x30;
- if ((int)(Distance/PassTime*100)< 100)
- {
- Speed1+=0;
- Speed2+=(int)(Distance/PassTime*100)/10;
- Speed3+=(int)(Distance/PassTime*100)%10;
- }
- else
- {
- Speed1+=(int)(Distance/PassTime*100)/100;
- Speed2+=(int)(Distance/PassTime*100)/10%10;
- Speed3+=(int)(Distance/PassTime*100)%10;
- }
- DisplaySingleChar(0x05,1,Speed1);
- DisplaySingleChar(0x06,1,'.');
- DisplaySingleChar(0x07,1,Speed2);
- DisplaySingleChar(0x08,1,Speed3);
- }
- /*------------------------------------- 显示路程 ----------------------------------------*/
- void DisplayDistance(void)
- {
- int Distance1=0x30;
- int Distance2=0x30;
- int Distance3=0x30;
- int Distance4=0x30;
- if ((int)(Distance*100) < 100)
- {
- Distance1+=0;
- Distance2+=(int)(Distance*100)/10;
- Distance3+=(int)(Distance*100)%10;
- }
- else if ((int)(Distance*100) > 100 && (int)(Distance*100) < 1000)
- {
- Distance1+=(int)(Distance*100)/100;
- Distance2+=(int)(Distance*100)/10%10;
- Distance3+=(int)(Distance*100)%10;
- }
- else
- {
- Distance1+=(int)(Distance*100)/1000;
- Distance2+=(int)(Distance*100)/100%10;
- Distance3+=(int)(Distance*100)/10%10;
- Distance4+=(int)(Distance*100)%10;
- }
-
- if ((int)(Distance*100) < 1000)
- {
- DisplaySingleChar(0x05,1,Distance1);
- DisplaySingleChar(0x06,1,'.');
- DisplaySingleChar(0x07,1,Distance2);
- DisplaySingleChar(0x08,1,Distance3);
- }
- else
- {
- DisplaySingleChar(0x04,1,Distance1);
- DisplaySingleChar(0x05,1,Distance2);
- DisplaySingleChar(0x06,1,'.');
- DisplaySingleChar(0x07,1,Distance3);
- DisplaySingleChar(0x08,1,Distance4);
- }
- }
- /*------------------------------------- 中断初始化 -------------------------------------*/
- void INTInit(void)
- {
- EA=1; //开总中断
- IT0=1; //INTO边沿触发
- PX0=1; //INTO优先级为高级
- EX1=1; //开INT1中断
- IT1=1; //INT1边沿触发
- PX1=1; //INT1优先级为高级
- Clock0_Init(); //初始化时钟中断
- TMOD=0x11; //T0/T1定时方式1
- ET0=0x01; //开T0中断
- ET1=0x01; //开T1中断
- }
- void Clock0_Init(void)
- {
- TR0=0x01; //启动T0
- TH0=Thx0; //定时初值
- TL0=Tlx0;
- }
- void Clock1_Init(void)
- {
- TR1=0x01; //启动T1
- TH1=0x3C; //定时初值-50ms中断一次
- TL1=0x0B0;
- }
- /*******************************************************************************************\
- ** 中断处理程序 **
- \*******************************************************************************************/
- /*----------------------------------- 外部中断0 ----------------------------------------*\
- 外部中断0有两个功能
- (1)作为菜单选择的Next键
- (2)作为测速的计数器
- \*-----------------------------------------------------------------------------------------*/
- void SpeedINT(void) interrupt 0 //中断INT0
- {
- if (SelectedAll==False) //如果模式和速度还没有选择完毕,则此中断作为Next键
- Next=True;
- if (Running==True) //如果模式和速度已经选择完毕,则此中断作为测速中断
- SpeedCount++;
- if (ChoosingDisplay==True) //如果是在选择要显示的内容
- Next=True;
- }
- /*----------------------------------- 外部中断1 ----------------------------------------*\
- 外部中断1有两个功能
- (1)作为菜单选择的确定键/返回键
- (2)控速
- \*-----------------------------------------------------------------------------------------*/
- void CtrSpeedINT(void) interrupt 2 //中断INT1
- {
-
- if (SelectedAll==False) //如果模式和速度还没有选择完毕,则此中断作为确定键
- {
- if (IsSelectingMode==True) //模式选择标志
- ModeSelected=True;
- if (IsSelectingSpeed==True) //速度选择标志
- SpeedSelected=True;
- }
- if (Running==True) //如果模式和速度选择已经完毕,则此中断作为控速中断
- {
- if (Area0==0) //经过第一条铁线(即起跑线),开始计时,开始测速
- {
- EX0=1;
- Clock1_Init();
- P31=0; //过起跑线,背光灭
- }
- if (Area0==1)
- LowSpeedArea1StartTime=PassTime; //读取进入第一个低速区的时刻
- if (Area0==2)
- LowSpeedArea1EndTime=PassTime;//读取离开第一个低速区的时刻,也就是进入高速区的时刻
- if (Area0==3)
- HighSpeedAreaEndTime=PassTime;//读取离开高速区的时刻,也就是进入第二个低速区的时刻
- if (Area0==4)
- LowSpeedArea2EndTime=PassTime; //读取离开第二个低速去的时刻
-
- if(AutoMode==1) //自动模式
- {
- PassLine++;
- switch(PassLine)
- {
- case 5 :PassLineID=1;break;
- case 10 :PassLineID=2;break;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
chengxu.docx
(38.44 KB, 下载次数: 130)
|
|