51小车软件手册.doc_第1页
51小车软件手册.doc_第2页
51小车软件手册.doc_第3页
51小车软件手册.doc_第4页
51小车软件手册.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

51小车作为一种入门小车,其基本原理与飞思卡尔比赛的小车相似,共分为硬件和软件两个部分。其中软件部分可分为传感器数据采集,舵机控制,速度控制等,这里现在对51小车的软件进行一个详细的介绍1.程序思路概述:首先51单片机需要通过红外传感器监测道路信息,然后将传感器得到的数据进行转换。最后将转换后的数据通过某种控制算法,计算出舵机和电机的控制量,使小车能够沿着跑道行驶。主体控制流程可以表示为如下图形:2.程序算法2.1数据采集 小车传感器为个红外对管,经过电压比较器后,每个红外对管都有和两种状态。因此,个红外对管产生的数据刚好为个字节。因此程序有两种方式将这位数据读入:1、可以将/口数据当做一个字节,直接赋给一个字符变量;2、将8位数据按位读取,分别赋给字符变量的每一位。我们的示例程序中采用的就是第二种方法。2.2数据处理 由于读入的数据并不方便直接参与控制计算,因此先将该数据集分成类,分别对应于小车不同的位置信息,由-7+7表示,其中+7表示引导线位于小车最左侧,0表示引导线位于小车中部,-7表示引导线位于小车最右侧,8表示未检测到引导线或其他错误情况。2.3控制算法上面的转换后的数据可以作为控制计算的输入,即小车与赛道的偏差信息。方向的控制算法可以采用位置型PD算法。 其中为比例环节,简单的说就是根据当前小车与赛道的偏差直接进行控制,偏离多少就转多少,偏离越多,舵机转向越多。可以通过调节比例系数改变转向的幅度。系数越大,转向幅度越大,转向越快。称为微分环节,这里的微分信息指上面偏差信息的微分,可以简单理解为小车偏离赛道的速率。可以简单的将本次的偏差信息与上一次偏差的差值算作微分项。微分项的控制方法是说,小车偏离跑道越快,方向就要转的越多,反之则转向越小。因此当小车逐渐靠近跑道时,微分项可以使小车偏转量减小,使小车不至于偏向另一边。可以通过改变微分项的系数来改变这种调节作用的程度。一般来讲,微分系数越大,小车对于弯道的响应就越灵敏,行驶时也更稳定。由于小车在不同的位置时,可能需要不同的比例系数或微分系数,因此可以考虑在不同的情况下,采用不同的系数进行运算。示例程序中采用的就是这种方法。 速度控制也可以采用算法进行控制。为了使程序简单化,示例程序中采用了匀速的控制方式。想要提高成绩的同学可以自行加入速度控制程序.生成 由于51单片机没有PWM模块,因此需要通过通用I/O口进行模拟来输出舵机和电机所需的PWM波。 可以分别使用一个定时器来作为一路PWM波的计时器。先将I/O口置位,通过高电平时间确定好定时器的初值,当定时器产生中断时,再将I/O口清零,并设定低电平时间,由此循环即可产生PWM波。其中,高电平时间由上面的控制计算得出,低电平时间由PWM周期减去高电平时间得到。#include /包括一个52标准内核的头文件#include /*定义数据类型(方便移植)*/typedef unsigned char UINT8;typedef char SINT8;typedef unsigned int UINT16;typedef int SINT16;/*/*定义布尔值(增强程序可读性)*/#define HIGH_LEVEL 1#define LOW_LEVEL 0/*/*定义相关常数(移植于不同的小车时,需根据实际情况改变该常数*/#define SERVOMID 1270/舵机中值#define SERVOMOSTLEFT 1680/舵机左值#define SERVOMOSTRIGHT 870/舵机右值#define SERVO_PERIOD 20000/舵机PWM周期:20ms,晶振12M公式:计数值=定时时间*晶振/频率/12,如20ms:计数值=0.02 s * 12 000 000 Hz/12 = 20000#define MOTOR_PERIOD 10000/电机PWM周期:10ms,晶振12M/*/*输出口定义*/sbit SevorPort = P01; sbit MotorPort = P06; sbit P20 = P20;sbit P21 = P21;sbit P22 = P22;sbit P23 = P23;sbit P24 = P24;sbit P25 = P25;sbit P26 = P26;sbit P27 = P27;/*/*定义公共变量*/UINT8 KServoD=10;/舵机D参数UINT8 KServoP5=65,40,10,40,65;/舵机分段P参数UINT8 SampleData=0;/采样数据SINT8 Offset=0;/当前赛道位置SINT8 LastOffset2=0;/上一次赛道位置UINT16 SevorPWM=0;/舵机PWM高电平时间UINT16 MotorPWM=0;/电机PWM高电平时间/*/*初始化函数*/void Init(void)TMOD=0x11;/定时器0,16位工作方式;定时器1,16位工作方式TR0=1;/启动定时器0TR1=1;/启动定时器1ET0=1;/打开定时器0中断ET1=1;/打开定时器0中断EA=1;/打开总中断/*数据采样函数*/void Sample(void)SampleData=0;if(P20=0)SampleData|=0x01;if(P22=0)SampleData|=0x02;if(P21=0)SampleData|=0x04;if(P23=0)SampleData|=0x08;if(P24=0)SampleData|=0x10;if(P26=0)SampleData|=0x20;if(P25=0)SampleData|=0x40;if(P27=0)SampleData|=0x80;/*确定赛道位置*/void ConfirmLocation(void)switch(SampleData)/根据采集到的值进行判断case 0x80:Offset=7;break;/1000 0000最左边1个光电传感器检测到黑线case 0xc0:Offset=6;break;/1100 0000最左边2个光电传感器检测到黑线case 0x40:Offset=5;break;/0100 0000依次类推case 0x60:Offset=4;break;/0110 0000case 0x20:Offset=3;break;/0010 0000case 0x30:Offset=2;break;/0011 0000case 0x10:Offset=1;break;/0001 0000case 0x18:Offset=0;break;/0001 1000case 0x08:Offset=-1;break;/0000 1000case 0x0c:Offset=-2;break;/0000 1100case 0x04:Offset=-3;break;/0000 0100case 0x06:Offset=-4;break;/0000 0110case 0x02:Offset=-5;break;/0000 0010case 0x03:Offset=-6;break;/0000 0011case 0x01:Offset=-7;break;/0000 0001default:Offset=8;break;/其余情况包括跑道丢失于检测错误/*赛道位置数据滤波(减少某次采样错误对系统的干扰)*/void Filter(void)if (Offset=8)/滤除错误信号,没有检测到黑线(是需要保持上一次测量值的)Offset=LastOffset0;else if(abs(Offset-LastOffset0)5) /滤除尖峰信号Offset=LastOffset0; /*舵机控制函数*/void ServoCtrl(void)UINT8p=0,d=0;SINT16 PID=0;if(Offset=-7&Offset=-4&Offset=-1&Offset=2&Offset=5&OffsetSERVOMOSTLEFT)SevorPWM=SERVOMOSTLEFT;/限幅if(SevorPWMSERVOMOSTRIGHT)SevorPWM=SERVOMOSTRIGHT; /限幅/*舵机测试函数*/ServoTest()/ SevorPWM=SERVOMID;/测试舵机中值SevorPWM=SERVOMOSTLEFT;/测试舵机极左值/ SevorPWM=SERVOMOSTRIGHT;/测试舵机极右值/*速度控制函数*/void MotorCtrl(void)MotorPWM=3000;/*数据存储函数*/void SaveData(void)static UINT8 TCnt2=0;if(TCnt2=20)LastOffset1=LastOffset0;TCnt2=0;TCnt2+;LastOffset0=Offset;/*主函数*/void main(void)Init();/初始化while (1)Sample();/采样ConfirmLocation();/确认黑线位置Filter();/滤波ServoCtrl();/舵机控制/ServoTest();/舵机测试MotorCtrl();/电机控制SaveData();/*舵机定时器中断函数*/void TC0Isr(void) interrupt 1static UINT8 TC20msFlag=LOW_LEVEL;/舵机输出状态标志UINT16 LowlvlTime=0;UINT16 HighlvlTime=0;if(TC20msFlag=HIGH_LEVEL)LowlvlTime=65535-(SERVO_PERIOD-SevorPWM);TH0=LowlvlTime/256;TL0=LowlvlTime%256;SevorPort=LOW_LEVEL;TC20msFlag=LOW_LEVEL;elseHighlvlTime=65535-SevorPWM;TH0=HighlvlTime/256;TL0=HighlvlTime%256;SevorPort=HIGH_LEVEL;TC20msFlag=HIGH_LEVEL;/*电机定时器中断函数*/void TC1Isr(void) interrupt 3static UINT8 TC10msFlag=LOW_LEVEL;/舵机输出状态标志UINT16 LowlvlTime=0;UINT16 HighlvlTime=0;if(TC10msFlag=HIGH_LEVEL)Low

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论