1、基于单片机89c51循迹小车原理与程序分解基于单片机89c51循迹小车原理与程序分解自循迹小车 第一章 引言1.1 设计目的通过设计进一步掌握单片机的应用,特别是在嵌入式系统中的应用。进一步学习单片机在系统中的控制功能,能够合理设计单片机的外围电路,并使之与单片机构成整个系统。1.2 设计方案介绍该智能车采用红外对管方案进行道路检测,单片机根据采集到的红外对管的不同状态判断小车当前状态,通过控制发出控制命令,控电机的工作状态以实现对小车姿态的控制。1.3 技术报告内容安排本技术报告主要分为三个部分。第一部分是对整个系统实现方法的一个概要说明,主要内容是对整个技术方案的概述;第二部分是对硬件电路
2、设计的说明,主要介绍系统传感器的设计及其他硬件电路的设计原理等;第三部分是对系统软件设计部分的说明,主要内容是智能模型车设计中主要用到的控制理论、算法说明及代码设计介绍等。第三章 硬件电路的设计3.1 单片机最小系统小车采用STC公司的STC89C52RC单片机作为控制芯片,图3-1是其最小系统电路。主要包括:时钟电路、电源电路、复位电路。其中各个部分的功能如下:1、时钟电路:给单片机提供一个外接的12MHz的石英晶振。2、电源电路:给单片机提供5V电源。3、复位电路:在电压达到正常值时给单片机一个复位信号。图3-1 单片机最小系统原理图3.2 传感器电路光电寻线方案一般由多对红外收发管组成,
3、通过检测接收到的反射光强,判断黑白线。原理图由红外对管和电压比较器两部分组成,红外对管输出的模拟电压通过电压比较器转换成数字电平输出到单片机。芯片使用LM339具有4路电压比较器3-2赛道检测原理图3.3 电机驱动采用L293驱动芯片,该芯片支持2路电机驱动同时支持PWM调速 L293驱动3.3 电源电路设计模型车通过自身系统,采集赛道信息,获取自身速度信息,加以处理,由芯片给出指令控制其前进转向等动作,各部分都需要由电路支持,电源管理尤为重要。在本设计中,51单片机使用5V电源,电机使用6V电源。考虑到电源为充电电池组,额定电压为7.2V,实际充满电后电压则为6.5-6.8V,所以单片机及传
4、感器模块采用LM1117-5稳压后的5V电源供电,电机直接由电池供电。*程序说明:本附录:源程序主代码*/#include reg52.h#define uint unsigned int #define uchar unsigned char sbit K1=P20; sbit K2=P21; sbit K3=P22; sbit K4=P23; sbit LED1=P10; sbit LED2=P11; sbit LED3=P12; sbit LED4=P13; sbit PWM1=P32; sbit PWM2=P33;uchar PWM1_Cycle=0,PWM2_Cycle=0;/PWM
5、占空比 void delay(uint z) uint x,y; for(x=z;x0;x-) for(y=110;y0;y-); void PWM_Init() TMOD = 0x11 ; TH0=(65535-100)/256;/定时5us TL0=(65535-100)%256; TH1=(65535-100)/256;/定时10us TL1=(65535-100)%256; ET0=1; ET1=1; TR0=1; TR1=0; EA=1;/开中断 /* *函数功能:小车前进 *时间:2013、3、29 */ void Advance() P0=0x50; /* *函数功能:小车后退
6、*时间: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) Ad
7、vance(); else if(K4=1) Turn_left1(); else Advance(); /* *函数功能:产生占空比可调的PWM波 *参数:PWM1_Cycle */ void PWM1_Produce() interrupt 1 static unsigned int t1 ; /tt用来保存当前时间在一秒中的比例位置 t1+; TH0=(65535-100)/256;/定时100us TL0=(65535-100)%256; if(t1=100) t1=0; PWM1=1; if(PWM1_Cycle=t1) PWM1=0; /* *函数功能:产生占空比可调的PWM波 *
8、参数:PWM1_Cycle */ void PWM2_Produce() interrupt 3 static unsigned int t2 ; /tt用来保存当前时间在一秒中的比例位置 t2+; TH1=(65535-100)/256;/定时100us TL1=(65535-100)%256; if(t2=100) t2=0; PWM2=1; if(PWM2_Cycle=t2) PWM2=0; 元件清单附录:源程序主代码#include #include #include #define uchar unsigned char #define uint unsigned int#defin
9、e MIDDLE 1390/舵机中心位置#define LEFT 1600 #define RIGHT 1000#define T 20000#define HIGH 7300 /电机基准速度sbit rudder=P10; /定义舵机PWM波输出端口为P1.0口sbit pulse=P11; /定义后轮PWM波输出端口为P1.1口char flag1=0,flag2=0; /定义全局变量(flag1用于控制舵机/PWM标志位,flag2用于控制电机PWM)uint b=0,a=0; /b用来装载电机所需的高电平时间,a用于保存电机所需高电平时间void main()uchar receive
10、,ek4=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:ek3=0;break; /0111 1111 最左边(或右边)1个光电传感器检测到黑线 case 0x3f:ek3=1;break; /0011 1111 最左边(或右边)2个光电传感器检测到黑线
11、 case 0xbf:ek3=2;break; /1011 1111 依次类推 case 0x9f:ek3=3;break; /1001 1111 case 0xdf:ek3=4;break; /1101 1111 case 0xcf:ek3=5;break; /1100 1111 case 0xef:ek3=6;break; /1110 1111 case 0xe7:ek3=7;break; /1110 0111 case 0xf7:ek3=8;break; /1111 0111 case 0xf3:ek3=9;break; /1111 0011 case 0xfb:ek3=10;break
12、; /1111 1011 case 0xf9:ek3=11;break; /1111 1001 case 0xfd:ek3=12;break; /1111 1101 case 0xfc:ek3=13;break; /1111 1100 case 0xfe:ek3=14;break; /1111 1110default: ek3=15;break; /1111 1111 没有检测到黑线(是需要保持上一次测量值的) /*-switch-*/ if(ek3= =15) pidr = pidlr; else pidr=0.2*pidlr+0.8*(23*(ek3-7)+2*(ek3+ek2+ek1+e
13、k0-28)+7*(ek3-ek2);if(ek2!=ek3)ppid=-160*(cabs(ek3-7)+220*(cabs(ek1-7)-cabs(ek3-7); a=HIGH+ppid; /a是电机高电平时间b=pidr+MIDDLE; /b就是舵机PWM波高电平时间 if(bLEFT) b=LEFT; if(bRIGHT) b=RIGHT; char i; for(i=0;i3;i+) eki=eki+1; pidlr=pidr;void zhongduan_t0(void) interrupt 1 /产生舵机PWM波中断子程序(T0中断)if(flag1=0) TH0=(uchar)
14、(65536-b)/256); TL0=(uchar)(65536-b)%256);flag1=1;rudder=1; elseTH0=(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;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1