自循迹小车第一章引言1.1 设计目的通过设计进一步掌握51单片机的应用,特别是在嵌入式系统中的应用。
进一步学习51单片机在系统中的控制功能,能够合理设计单片机的外围电路,并使之与单片机构成整个系统。
1.2 设计方案介绍该智能车采用红外对管方案进行道路检测,单片机根据采集到的红外对管的不同状态判断小车当前状态,通过pid控制发出控制命令,控电机的工作状态以实现对小车姿态的控制。
1.3 技术报告内容安排本技术报告主要分为三个部分。
第一部分是对整个系统实现方法的一个概要说明,主要内容是对整个技术方案的概述;第二部分是对硬件电路设计的说明,主要介绍系统传感器的设计及其他硬件电路的设计原理等;第三部分是对系统软件设计部分的说明,主要内容是智能模型车设计中主要用到的控制理论、算法说明及代码设计介绍等。
第二章技术方案概要说明本模型车的电路系统包括电源管理模块、单片机模块、传感器模块、电机驱动模块.在整个系统中,由电源管理模块实现对其他各模块的电源管理。
其中,对单片机、光电管提供5V电压,对电机提供6V电压路径识别电路由3对光电发送与接收管组成。
由于路面存在黑色引导线,落在黑线区域内的光电接收管接收到反射的光线的强度与白色的路面不同,进而在光电接收管两端产生不同的电压值,由此判断路线的走向。
传感器模块将当前采集到的一组电压值传递给单片机,进而根据一定得算法对舵机进行控制,使小车自动寻线行走。
单片机模块是智能车的核心部分,主要完成对外围各个模块的管理,实现对外围模块的信号发送,以及对传感器模块的信号采集,并根据软件算法对所采集的信号进行处理,发送信号给执行模块进行任务执行,还对各种突发事件进行监控和处理,保证整个系统的正常运作。
电机驱动采用L293驱动芯片,该芯片支持2路电机驱动同时支持PWM 调速第三章硬件电路的设计3.1 单片机最小系统小车采用STC公司的STC89C52RC单片机作为控制芯片,图3-1是其最小系统电路。
主要包括:时钟电路、电源电路、复位电路。
其中各个部分的功能如下:1、时钟电路:给单片机提供一个外接的12MHz的石英晶振。
2、电源电路:给单片机提供5V电源。
3、复位电路:在电压达到正常值时给单片机一个复位信号。
图3-1 单片机最小系统原理图3.2 传感器电路光电寻线方案一般由多对红外收发管组成,通过检测接收到的反射光强,判断黑白线。
原理图由红外对管和电压比较器两部分组成,红外对管输出的模拟电压通过电压比较器转换成数字电平输出到单片机。
芯片使用LM339具有4路电压比较器3-2赛道检测原理图3.3 电机驱动采用L293驱动芯片,该芯片支持2路电机驱动同时支持PWM调速L293驱动3.3 电源电路设计模型车通过自身系统,采集赛道信息,获取自身速度信息,加以处理,由芯片给出指令控制其前进转向等动作,各部分都需要由电路支持,电源管理尤为重要。
在本设计中,51单片机使用5V电源,电机使用6V电源。
考虑到电源为充电电池组,额定电压为7.2V,实际充满电后电压则为6.5-6.8V,所以单片机及传感器模块采用LM1117-5稳压后的5V电源供电,电机直接由电池供电。
***********************************程序说明:本附录:源程序主代码****************************************/ #include "reg52.h"#define uint unsigned int#define uchar unsigned charsbit K1=P2^0;sbit K2=P2^1;sbit K3=P2^2;sbit K4=P2^3;sbit LED1=P1^0;sbit LED2=P1^1;sbit LED3=P1^2;sbit LED4=P1^3;sbit PWM1=P3^2;sbit PWM2=P3^3;uchar PWM1_Cycle=0,PWM2_Cycle=0;//PWM占空比void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void PWM_Init(){TMOD = 0x11 ;TH0=(65535-100)/256;//定时5usTL0=(65535-100)%256;TH1=(65535-100)/256;//定时10usTL1=(65535-100)%256;ET0=1;ET1=1;TR0=1;TR1=0;EA=1;//开中断}/******************************************************************** ***函数功能:小车前进*时间:2013、3、29********************************************************************* */void Advance(){P0=0x50;}/******************************************************************** ***函数功能:小车后退*时间:2013、3、29********************************************************************* */void Retreat(){P0=0xa0;}/******************************************************************** ***函数功能:小车左转*时间:2013、3、29********************************************************************* */void Turn_left1(){P0=0x10;delay(500);P0=0;}/***********************************************************************函数功能:小车右转*时间:2013、3、29********************************************************************* */void Turn_right1(){P0=0x40;delay(500);P0=0;}void main(){PWM_Init();PWM1_Cycle=30;//初始速度,可改变其大小是速度使变化while(1){if(K1==1){Turn_right1();}else if(K2==1){Advance();}else if(K4==1){Turn_left1();}elseAdvance();}}/******************************************************************** ******函数功能:产生占空比可调的PWM波*参数:PWM1_Cycle********************************************************************* *****/void PWM1_Produce() interrupt 1static unsigned int t1 ; //tt用来保存当前时间在一秒中的比例位置t1++;TH0=(65535-100)/256;//定时100usTL0=(65535-100)%256;if(t1==100){t1=0;PWM1=1;}if(PWM1_Cycle==t1){PWM1=0;}}/******************************************************************** ******函数功能:产生占空比可调的PWM波*参数:PWM1_Cycle********************************************************************* *****/void PWM2_Produce() interrupt 3{static unsigned int t2 ; //tt用来保存当前时间在一秒中的比例位置t2++;TH1=(65535-100)/256;//定时100usTL1=(65535-100)%256;if(t2==100){t2=0;PWM2=1;}if(PWM2_Cycle==t2){PWM2=0;}}元件清单附录:源程序主代码#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned int#define MIDDLE 1390//舵机中心位置#define LEFT 1600#define RIGHT 1000#define T 20000#define HIGH 7300 //电机基准速度sbit rudder=P1^0; //定义舵机PWM波输出端口为P1.0口sbit pulse=P1^1; //定义后轮PWM波输出端口为P1.1口char flag1=0,flag2=0; //定义全局变量(flag1用于控制舵机//PWM标志位,flag2用于控制电机PWM)uint b=0,a=0; //b用来装载电机所需的高电平时间,a用于保存电机所需高电平时间void main(){uchar receive,ek[4]={7,7,7,7};uint pidr=0;uint pidlr=0;uint ppid=0;IE=0x8a;TMOD=0x11;TH0=0x00;TL0=0x00;TR0=1;TH1=0x00;TL1=0x00;TR1=1;while(1){ receive=P2; //采集光电传感器的值/*--------------switch----------------*/switch(receive) //根据采集到的值进行判断{case 0x7f:ek[3]=0;break; //0111 1111 最左边(或右边)1个光电传感器检测到黑线case 0x3f:ek[3]=1;break; //0011 1111 最左边(或右边)2个光电传感器检测到黑线case 0xbf:ek[3]=2;break; //1011 1111 依次类推case 0x9f:ek[3]=3;break; //1001 1111case 0xdf:ek[3]=4;break; //1101 1111case 0xcf:ek[3]=5;break; //1100 1111case 0xef:ek[3]=6;break; //1110 1111case 0xe7:ek[3]=7;break; //1110 0111case 0xf7:ek[3]=8;break; //1111 0111case 0xf3:ek[3]=9;break; //1111 0011case 0xfb:ek[3]=10;break; //1111 1011case 0xf9:ek[3]=11;break; //1111 1001case 0xfd:ek[3]=12;break; //1111 1101case 0xfc:ek[3]=13;break; //1111 1100case 0xfe:ek[3]=14;break; //1111 1110default: ek[3]=15;break; //1111 1111 没有检测到黑线(是需要保持上一次测量值的)}/*--------------switch----------------*/if(ek[3]= =15){pidr = pidlr;}else{pidr=0.2*pidlr+0.8*(23*(ek[3]-7)+2*(ek[3]+ek[2]+ek[1]+ek[0]-28)+7*(ek[3]-ek[2]));if(ek[2]!=ek[3])ppid=-160*(cabs(ek[3]-7))+220*(cabs(ek[1]-7)-cabs(ek[3]-7));}a=HIGH+ppid; //a是电机高电平时间b=pidr+MIDDLE; //b就是舵机PWM波高电平时间if(b>LEFT)b=LEFT;if(b<RIGHT)b=RIGHT;{char i;for(i=0;i<3;i++)ek[i]=ek[i+1];}pidlr=pidr;}}void zhongduan_t0(void) interrupt 1 //产生舵机PWM波中断子程序(T0中断){if(flag1==0){TH0=(uchar)((65536-b)/256);TL0=(uchar)((65536-b)%256);flag1=1;rudder=1;}else{TH0=(uchar)((38869+b)/256);TL0=(uchar)((38869+b)%256);flag1=0;rudder=0;}}void zhongduan_t1(void) interrupt 3{if(flag2==0){TH1=(uchar)((65536-HIGH)/256);TL1=(uchar)((65536-HIGH)%256);flag2=1;pulse=0;}else{TH1=(65536-T+HIGH)/256;TL1=(65536-T+HIGH)%256;flag2=0;pulse=1;}}。