首页 基于单片机的多功能智能小车设计论文(电路+程序+论文)

基于单片机的多功能智能小车设计论文(电路+程序+论文)

举报
开通vip

基于单片机的多功能智能小车设计论文(电路+程序+论文)基于单片机的多功能智能小车设计论文(电路+程序+论文) 摘 要 (关键词:智能车 AT89S52 单片机 金属感应器 霍尔元件 1602LCD) 智能作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能电动车就是其中的一个体现。本次设计的简易智能电动车,采用AT89S52单片机作为小车的检测和控制核心;采用金属感应器TL-Q5MC来检测路上感应到的铁片,从而把反馈到的信号送单片机,使单片机按照预定的工作模式控制小车在各区域按预定...

基于单片机的多功能智能小车设计论文(电路+程序+论文)
基于单片机的多功能智能小车设计论文(电路+程序+论文) 摘 要 (关键词:智能车 AT89S52 单片机 金属感应器 霍尔元件 1602LCD) 智能作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能电动车就是其中的一个体现。本次设计的简易智能电动车,采用AT89S52单片机作为小车的检测和控制核心;采用金属感应器TL-Q5MC来检测路上感应到的铁片,从而把反馈到的信号送单片机,使单片机按照预定的工作模式控制小车在各区域按预定的速度行驶,并且单片 霍尔元件A44E检测小车机选择的工作模式不同也可控制小车顺着S形铁片行驶;采用 行驶速度;采用1602LCD实时显示小车行驶的时间,小车停止行驶后,轮流显示小车行驶时间、行驶距离、平均速度以及各速度区行驶的时间。本设计结构简单,较容易实现,但具有高度的智能化、人性化,一定程度体现了智能。 1 目 录 1 设计任务………………………………………………………………………………3 1.1 要求………………………………………………………………………………3 2 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 比较与选择………………………………………………………………………4 2.1路面检测模块………………………………………………………………………4 2.2 LCD显示模块………………………………………………………………………5 2.3测速模块……………………………………………………………………………5 2.4控速模块……………………………………………………………………………6 2.5模式选择模块………………………………………………………………………7 3 程序框图………………………………………………………………………………7 4 系统的具体设计与实现………………………………………………………………9 4.1路面检测模块………………………………………………………………………9 4.2 LCD显示模块………………………………………………………………………9 4.3测速模块……………………………………………………………………………9 4.4控速模块……………………………………………………………………………9 4.5复位电路模块………………………………………………………………………9 4.6模式选择模块………………………………………………………………………9 5 最小系统图……………………………………………………………………………10 6 最终PCB板图…………………………………………………………………………12 7 系统程序………………………………………………………………………………13 8 致谢……………………………………………………………………………………46 9 参考文献……………………………………………………………………………47 10 附录…………………………………………………………………………………48 2 1. 设计任务: 设计并制作了一个智能电动车,其行驶路线满足所需的要求。 1.1 要求: 1.1.1 基本要求: (1)分区控制: 如(图1)所示: (图1) 车辆从起跑线出发(出发前,车体不得超出起跑线)。在第一个路程C~D区(3,6米)以低速行驶,通过时间不低于10s;第二个路程D,E区(2米)以高速行驶,通过时间不得多于4秒;第三个路程E~F区(3,6米)以低速行驶,通过时间不低于10s。 (2)小车能自动记录、显示行驶时间、行驶距离以及行驶速度,还能记录每段所走的时间,从而判断是否符合课程设计要求。(记录显示装置要求安装在车上)。 1.1.2 发挥部分: S型控制:如(图2)所示: (图2) 3 车辆沿着S形铁片行驶,自动转弯,自动寻找正确方向和铁片。当离开S型铁片跑道或者感应不到铁片一段时间的时候,小车自动停止,并记录行驶时间,路程,平均速度并通过LCD显示出来。 2. 方案比较与选择: 根据设计任务要求,并且根据我们自己的需要而附加的功能,该电路的总体框图可分为几个基本的模块,框图如(图3)所示: (图3) 2.1 路面检测模块: 采用铁片感应器TL-Q5MC来检测路面上的铁片从而给单片机中断脉冲。原理图接线如(图4)所示: (图4) 4 2.2 LCD显示模块: 采用1602LCD,由单片机的总线模式连接。为节约电源电量并且不影响LCD的功能,LCD的背光用单片机进行控制,使LCD的背光在小车行驶的过程中不亮,因为我们不必看其显示;在其它我们需要看显示的内容的时候LCD背光亮。 2.3 测速模块: 2.3.1 方案1: 采用采用霍尔开关元器件A44E检测轮子上的小磁铁从而给单片机中断脉冲,达到测量速度的作用。霍尔元件具有体积小,频率响应宽度大,动态特性好,对外围电路要求简单,使用寿命长,价格低廉等特点,电源要求不高,安装也较为方便。霍尔开关只对一定强度的磁场起作用,抗干扰能力强,因此可以在车轮上安装小磁铁,而将霍尔器件安装在固定轴上,通过对脉冲的计数进行车速测量。 2.3.2 方案2: 采用红外传感器进行测速。但无论是反射式红外传感器还是对射式红外传感器,他们对都对外围环境要求较高,易受外部环境的影响,稳定性不高,且价格较为昂贵。 通过对方案1、方案2的比较其优缺点,综合多方面因素决定选用方案1,其原理图接线如(图5)所示: (图5) 2.4 控速模块: 2.4.1 方案1: 使用功率三极管作为功率放大器的输出控制直流电机。线性型驱动的电路结构和原理简单,成本低,加速能力强,但功率损耗大,特别是低速大转距运行时,通过电阻R的电流大,发热厉害,损耗大,对于小车的长时间运行不利。 2.4.2 方案2: 采用继电器对电动机的开或关进行控制,通过开关的切换对小车的速度进行调整.此 5 方案的优点是电路较为简单,缺点是继电器的响应时间慢,易损坏,寿命较短,可靠性不高。 2.4.3 方案3: 采用由双极性管组成的H桥电路。用单片机控制晶体管使之工作在占空比可调的开关状态,精确调整电机转速。这种电路由于工作在管子的饱和截止模式下,效率非常高;H桥电路保证了可以简单地实现转速和方向的控制;电子开关的速度很快,稳定性也很高,是一种广泛采用的调速技术。 综合3种方案的优缺点,决定选择方案3,其电路原理图如(图6)所示: (图6) 2.5 模式选择模块: 模式选择模块通过一个74LS00与非门和两个不带锁按钮来控制单片机单片机的两个中断口,从而按动按钮来选择小车走动的路型、来选择小车的速度是快速、中速、慢速;走完路程小车停止后还可以通过按钮选择想要在LCD上想看的信息,比如总时间、走过各段路程的时间、平均速度、总路程等。 小车走动的模式选择有: (1) 直线型:满足设计任务的基本要求,能稳定的走完全程。之后按顺序循环不 6 断的显示走完全程所用的时间、走完高速区所用的时间和走完低速区所用的时间这三个时间;或者可以通过两个按钮以及LCD显示的菜单选择所要看的内容如平均速度、全程距离以及那三个时间。 (2) S型:满足设计任务的发挥部分的要求,小车能自动的感应到在前面或在后面铁片,即第一次转弯后若感应到的是错误的方向,则小车会后退自动调整方向,沿着S型的铁片走。当走完S型铁片后的一定时间里,小车自动停止。之后自动进入菜单由我们自己选择要看的内容时间、平均速度和所走的距离。 (3)自动型:小车先以一定的速度走完全程,之后再以一定的速度倒退回起点,再调整速度在一定的时间内走完全程。走完后LCD显示的内容与直线型显示的内容一样。 3. 程序框图: 单片机主程序框图、速度感应程序框图和铁片感应程序框图分别如(图7)所示。 7 (图7) 8 4(系统的具体设计与实现: 4.1 路面检测模块: 应用一个金属感应器,安装在车盘下,离地略小于或约四毫米。当金属传感器检测到铁片时将对单片机发送中断信号,单片机运行中断,改变输给电机驱动信号的电压占空比来控制小车的速度。 4.2 LCD显示模块: 采用1602LCD,由单片机的总线模式连接。为节约电源,LCD的背光用单片机进行控制。 4.3 测速模块: 通过霍尔元件感应磁铁来产生脉冲(当霍尔元件在离磁场较近时输出会是高电平,其它时候是低电平),一个车轮均匀放四个小磁铁,计算一秒所得的脉冲数,从而计算出一秒小车轮子转动圈数,再测量出小车车轮周长即可计算出小车当前速度,累加可得到当前路程。 4.4 控速模块: 考虑到元器件的缺少以及我们所用的电路的驱动电机的电路原理图和和小车自带的电路的电机驱动原理图一样,所以暂时使用小车自带的电机驱动电路图。 4.5 复位电路模块: 单片机的复位电路通过手动来实现,复位电路图如(图8)所示。 S22uTR VCC (图8) 4.6 模式选择模块: 9 200 1K 两个中断口使用和感应铁片、感应速度所使用的中断口一样,通过一个与非门和按钮控制。原理图如(图9)所示: (图9) 5(最小系统图: 该系统主要用到的是单片机,所以主要的部分是最小系统图,该最小系统图如(图10)所示: 10 (图12) 11 6. 最终PCB板图: 该最小系统的最终PCB板图(包括LCD接口以及其他的外部扩展电路部分,考虑到最小系统的简洁以及容易看懂,外部扩展电路不在最小系统图上显示。)分别如(图11)、(图12)所示: (图11) 12 (图12) 7(系统程序: 按照预定的功能,系统实现预定的功能的程序如下所示: #include #include /********************************************************************************\ ** 宏定义区 ** \********************************************************************************/ /*------------------------------- 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 //低电平选择命令 13 #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); //显示一段字符串 14 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; 15 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; 16 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 "); 17 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键 { (Next==True) //如果按Next键则直接跳出 if 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; 18 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; } } 19 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); 0," Normal Speed "); DisplayString(0x0, 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; 20 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; 21 } } } 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 "); 22 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... "); 23 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;} 24 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;} } } } } } } 25 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 "); 26 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); //延时消除抖动 /*------------------------------------第一次按键--------------------------------------*/ 27 /*不断检测确定键和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) 28 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; //按下了确定键,那么这个时候开启返回键的功能 29 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) //按下了确定键或返回键 { 30 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; } 31 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; } 32 /*------------------------------------第五次按键--------------------------------------*/ 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) 33 { 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); //关显示 34 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; 35 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) 36 { 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); } int time) void DelayUs(unsigned { 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; 37 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码 38 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; 39 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; } 40 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; 41 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; default :PassLineID=PassLineID;break; } } else { if (SelectedMode==Line) //直线模式 { Thx0=Thx[Area0++]; Tlx0=Tlx[Area1++]; if (Area0==5) EX1=0; } else //S型模式 { Nocurve++; Round++; if(Roundid==1&&Round==2) 42 {Round++;Roundid=0;} Back=0; Back0=0; EX1=0; } } IE1=0; } if (AutoDisplay==True) { GoToChoosingDisplay=True; } if (ChoosingDisplay==True) { SelectedShow=True; SelectedReturn=True; Selected=True; } } /*-------------------------------------- T0中断 ----------------------------------------*\ T0中断用来输出方波以控制速度 \*-----------------------------------------------------------------------------------------*/ void Time0INT(void) interrupt 1 //T0中断 { if(AutoMode==1) { IsT0INT*=-1; switch(PassLine) { case 2 :PrepareDistance=Distance;break; case 3 :FirstDistance=Distance-PrepareDistance;break; case 4 :SecondDistance=Distance-PrepareDistance-FirstDistance;break; case 5 :ThirdDistance=Distance-PrepareDistance-FirstDistance-SecondDistance;break; default :break; } switch(PassLineID) { case 0 :{ if(IsT0INT==1) {TR0=0x01;TH0=0xec;TL0=0x78;} //5ms else {TR0=0x01;TH0=0xb1;TL0=0xe0;} //20ms }break; case 1 :{ 43 if(PassLine==5) { FirstHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000); SecondHigh=(int)(65536-20*SecondDistance/(15*Rate-SecondDistance)*1000); ThirdHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000); TR0=0x01;TH0=0xf4;TL0=0x48; } }break; case 2 :{ AutoMode=0;SelectedMode=Line;Area0=Area1=0;PassTime=0;Distance=0; TR0=0x01;TH0=0xf4;TL0=0x48; Thx[0]=Thx[1]=((FirstHigh & 0xf0)>>8);Tlx[0]=Tlx[1]=(FirstHigh & 0x0f); Thx[2]=Thx[2]=((SecondHigh & 0xf0)>>8);Tlx[2]=Tlx[2]=(SecondHigh & 0x0f); Thx[3]=Thx[3]=((ThirdHigh & 0xf0)>>8);Tlx[3]=Tlx[3]=(ThirdHigh & 0x0f); Thx[4]=Thx[4]=0xff;Tlx[4]=Tlx[4]=0xff; }break; default :break; } } else { if (SelectedMode==Line) { IsT0INT*=-1; if (Area0<5) { if(IsT0INT==1) Clock0_Init(); else { TR0=0x01; //启动T0 TH0=Thx1; //定时初值 TL0=Tlx1; } } else IsT0INT=-1; } else { IsT0INT2*=-1; if(IsT0INT2==1) 44 {TR0=0x01;TH0=0xd8;TL0=0xf0;} //10ms else {TR0=0x01;TH0=0xb1;TL0=0xe0;} //20ms Back++; if(Back>=90) Back0=70; if((Nocurve<2)&&(Back0>0)&&Back!=0) { if(Back0<=65) Roundid=1; Back0--; } if((Nocurve>2)&&Back>=450) {Stop=1;IsT0INT2=-1;} if(Stop==1) flag=6; } } TF0=0; } /*----------------------------------- T1中断 ----------------------------------------*\ T1中断用来定时 \*-----------------------------------------------------------------------------------------*/ void Time1INT(void) interrupt 3 //T1中断 { Clock1_Init(); Time1INTCount++; if (Time1INTCount == 10) //500ms扫描一次 { IsT1INT=1; if (Area0>5) P03=0; Time1INTCount=0; } TF1=0; } 45 致 谢 在本次设计中感谢俞龙老师、邓小玲老师以及实验室的老师在设计中对我们的指导和帮助~ 46 参 考 文 献 吴黎明 第一版 《单片机原理及应用技术》 谭浩强 第二版 《C程序设计》 《LAB2000系列单片机实验系统实验指导 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 》 《单片机C语言入门教程》 47 附 录: 元件清单: 元件 数量 AT89S52 单片机 1片 霍尔元件A44E 1个 铁片感应器TL-Q5MC 1个 1602LCD 1片 小车 1部 小磁铁片 4片 发光二极管 2个 带锁按钮 2个 不带锁按钮 3个 12MHz晶振 1个 排阻510 1个 74ls00 2个 16位排线 1条 排针 若干 电阻 若干 电容 若干 导线 若干 48
本文档为【基于单片机的多功能智能小车设计论文(电路+程序+论文)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_624976
暂无简介~
格式:doc
大小:361KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-18
浏览量:19