资源:
1、红外光电发射接纳管
2、
电压比较器3、HCS12的IO口
4、HCS12的ATD模块
5、HCS12的ECT模块
原理:
1、红外发射管,将红外线信号发射出去,当遇到遮挡物是,会反射回来。假如当部分为黑色时,则不会发射回来(黑色能吸收光线,红外线在遇到黑色遮挡物时,被吸收)。接纳管在接纳到反射的红外线时,其两头的电阻发生变化,然后能够输出不同的电压值,终究依据这些电压值来辨认途径。
2、电压
比较器能将接连量转变成开关量,在大于设定的阈值时,输出高电平,小于设定的阈值时,则输出低电平。
3、ADC能将模拟量转化成计算机能够辨认的数字量,但是自己对这些数字信号进行处理,对途径信息进行辨认。
计划:
1、
离散型途径辨认算法。
将红外接纳管输出的电压信号经过电压比较器进行电压比较,输出一个开关量,HCS12的IO读取电压比较器输出的开关量。装置若干个光电管排成一排,并且一起读取信息,当与发射管衔接的IO口输入一个0值时,则判别黑色轨迹在该光电接纳管下,经过必定的算法即可求出黑色轨迹和小车的偏移视点。
长处:简略易行。
缺点:
a.存在检测盲区,即在接纳管之间的区域。
b.路途信息为离散值,经过路途信息经过操控算法得到的操控信息为阶跃的而非接连的操控量,这对小车的安稳影响。
2、接连型途径辨认算法。
将红外接纳管输出的电压信号经过AD转化,比及数字量的的电压信号。经过对这些数字亮的处理能够得到近似于接连的路途信息。
长处:途径信息为接连,途径信息愈加准确。
缺点:
a.数据处理算法完结较为困难。
b.由于光电接纳管自身参数的不同,在相同条件下,输出的电压或许有所不同,这对数字信号的处理带来难度。
计划挑选:由所以初度触摸途径辨认算法,为了小车能安稳的行进,所以挑选了较为简略完结的离散途径辨认算法。
阐明:
1、光电接纳管为16个,在离前轮Hmm的距离排成一排,一起检测路途信息,每个光电管之间的距离为15mm。
2、16个光电管别离和HCS12的PORTB口和PORTE口衔接。
3、检测时刻距离为10MS。
车轮和接纳管的车子垂直距离为500mm。
4、变量iRoutPlace寄存途径信息。
5、数组iPLace寄存途径方位。
6、数组iplaceAngle寄存方向视点。
7、方位信息数据:
当某位红外接纳管检测到黑线时,则经过比较器,该位输出为0,未检测到的则为1。
iPLace[28]={0x7fff,0x3fff,0xbfff,0x9fff,0xdfff,0xcfff,0xefff,
0xf7ff,0xf3ff,0xfbff,0xf9ff,0xfdff,0xfcff,0xfeff,
0xff7f,0xff3f,0xffbf,0xff9f,0xffdf,0xffcf,0xffef,
0xfff7,0xfff3,0xfffb,0xfff9,0xfffd,0xfffc,0xfffe}
8、方位与偏移角的联系。
经过C程序计算出来。程序如下:
#include
#include
void main()
{
int i;
long double h,n;
n=0.0;
h=500.0;
for(i=0;i<16;i++)
{
printf(“%d–%lf–“,i,atan((15.0*n)/h));
printf(“%lfn”,((atan((15.0*n)/h))*180.0)/3.14);
n++;
}
}
运转成果:
方位-弧度角–视点
0–0.000000–0.000000
1–0.029991–1.719230
2–0.059928–3.435372
3–0.089758–5.145373
4–0.119429–6.846244
5–0.148890–8.535093
6–0.178093–10.209149
7–0.206992–11.865795
8–0.235545–13.502579
9–0.263712–15.117239
10–0.291457–16.707714
11–0.318748–18.272153
12–0.345556–19.808919
13–0.371856–21.316590
14–0.397628–22.793961
15–0.422854–24.240034
经过上表能够近似为,每偏移一个方位,视点添加1°。
9、视点信息:
iplaceAngle[]={-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,5,5,6,7,8,9,10,11,12,13}
CODE:
#include
#include
#pragma LINK_INFO DERIVATIVE “mc9s12xs128”
//===========================================================//
//光电管离散途径辨认算法
//PORTB和PORTE接电压比较器的输出端
//16位模数递减计数器进行计数
//author: Yangtze
//time:2009/4/19/15:15:45
//===========================================================//
#define iSampling 10//途径采样时刻设置
int iRoutPlace; //途径方位暂时变量
int Angle; //视点
int iPLace[28]={0x7fff,0x3fff,0xbfff,0x9fff,0xdfff,0xcfff,0xefff, //途径方位数组
0xf7ff,0xf3ff,0xfbff,0xf9ff,0xfdff,0xfcff,0xfeff,
0xff7f,0xff3f,0xffbf,0xff9f,0xffdf,0xffcf,0xffef,
0xfff7,0xfff3,0xfffb,0xfff9,0xfffd,0xfffc,0xfffe};
int iplaceAngle[]={-13,-12,-11,-10,-9,-8,//轨迹偏移视点
-7,-6,-5,-4,-3,-2,
-1,0,1,2,3,5,5,6,
7,8,9,10,11,12,13};
void Init_MDC(void)
{
MCCTL=0xDF;//设定模数计数器工作办法,中止使能,计数器使能
//分频系数为16
MCCNT=1000;//定时器赋初值 (1/16M)*16*1000= 1ms
}
void pllclk(void) //16MHz
{
SYNR=0x01;//PLLCLK =2*OSCCLK*(SYNR + 1)/(REFDV + 1)
REFDV=0x01;
CLKSEL=0x80;//选定PLL时钟
}
void IO_Init()//PORTB和PORTE设置为输进口
{
DDRB=0X00;
DDRE=0X00;
}
void main(void)
{
pllclk();
Init_PT0_ICapture();
IO_Init();
EnableInterrupts;
for(;;) {}
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 26 MDC_ISR(void)
{
static unsigned int count=0;
count++;
if(count==iSampling)//100MS读取一次
{
iRoutPlace=PORTB; //将IO口读取到的信息存入变量iRoutPlace中,B口在高8为,E口在底8位
iRoutPlace=iRoutPlace<<8;
iRoutPlace|=PORTE;
for(i=0;i<28;i++)//经过循环比较,获得黑色轨迹与中轴的偏移视点
{
if(iPLace==iRoutPlace)
{
Angle=iplaceAngle;
}
}
}
MCFLG = 0x80;//清中止标志位
}
跋文:
该程序仅仅为黑色轨迹的途径辨认程序,经过红外接纳管检测黑色途径,然后,输出方位偏移的视点,并没有操控程序。不过假如得到了偏移视点,操控程序就很优点理了。直接将视点和相应的PWM占空比进行比较,输出对应视点的占空比,以操控舵机。
假如加上舵机操控程序,就能形成了以个开环的自控操控体系,操控算法为含糊操控算法。许多人都说含糊操控算法很难了解,很不好用,但是从这个程序上看来,含糊操控算法仍是挺简略的.只需依据自己的经历来规划一些操控量的表格,经过检测到途径信息然后和操控量的表格进行比照,输出对应的操控量。这便是含糊操控算法的思路。当然这也仅仅只是含糊操控算法的一点思路,有许多缺乏。
以上程序仅仅只是一个前期的运用版别,还有许多缺点有待改善。缺点如下:
1、没有发射管的驱动程序,默以为发射管一直在发射。这样的成果红外接纳管在检测信息的时分,会遭到很大的搅扰,并且功耗很大,对整个体系的电流供应和功率输出有很大影响。
改善办法:在用从必定方向逐一发动的办法进行检测。假如有4对红外发射接纳管ABCD。先将D管的发射管敞开,ABC发射管均封闭,读取D接纳管的信息。然后在开去C发射管,封闭ABD发射管,读取C接纳管的信息。顺次读取每一个接纳管的信息。以ns级的速度读取,能够近似的以为接纳管是一起读取信息的。
2、没有进行滤波处理。在读取路途信息的时分,或许会遭到多方面的搅扰,为了获得愈加挨近实在值的信息,有必要进行滤波处理,将搅扰噪声除掉。
改善办法:在用屡次读取,取平均值的办法能够在必定程度上减小噪声搅扰。
3、方位处理和视点输出的时分没有依照经历进行恰当的处理,比如说,在偏移视点很小的时分,能够近似的以为是在直线上行进,直接输出0°角,让小车能快速的行进。
4、上述程序中的采样周期是随意设定的,没有科学依据,在设定采样周期的时分,必定要经过计算出最优的周期,这样才干确保小车行进的安稳性和前瞻性。
暂时找到这么多缺点,更多的缺点以及改善还得在实践运用中去发现,去寻求处理的办法。
完结这个程序,让我也学到了许多。现总结如下:
1、注重源代码的保存。C言语具有很强的移植性,在不同的平台上姑且能进行移植,在同一个平台上就更简略移植了。我上边写的这写程序,其实很大部分都是之前ECT_SPEED程序里面写过,而我这次在编写程序的时分,底子不必从头编写,直接调用ECT_SPEED里面的程序就能够完结任务。
我这个程序调用ECT_SPEED文件里的函数有:Init_MDC(), pllclk(),假如在大型的软件开发项目中,这样将会大大缩短程序的开发周期,下降程序的开发本钱。
2、注重程序阐明文档的编写。这几天的编程操练中,在编程之前,认真思考,将整个程序的算法,流程都考虑清楚之后,然后将其经过阐明文档的方式写出来。这样的优点是,使我在程序的编写的过程中,能趁热打铁,不再像曾经那样,一个略微大一点的程序编写下来,还没编写结束,就现已本来的思路忘记了。他的另一个优点便是便利今后阅读程序。
3、编写程序的时分,必定要多想,并且从不同的视点去寻觅处理问题的办法。在编写这个程序之前,在我的认识傍边,是知道用一排红外检测管是能够检测出黑色轨迹的,但是在处理轨迹方位的时分,一直都不知道怎样处理,怎样才干让单片机知道黑线在那个地方。想了良久,才从视点的这个方向去了解,终究找到了方位处理的办法。
4、必定要注重循环,尽或许多的运用循环。在上述程序的比照中,我榜首感觉是用switch句子进行比较,当输入和whitch中的某一个case吻合时,履行相应的句子。但是在这样的情况下,得写28个case句子,并写与之对应输出句子。这样会大大添加程序的体积,这在单片机内存空间很少的情况下,形成的过错是丧命的。
为了节约存储空间,就开端寻求其他办法来处理这个问题。这样我想到了冒泡程序中逐次比照的办法。我这个程序的问题也能够用屡次个循环来完结次比较啊,假如比较成果为真,则履行相应的句子。
所以就得到了这个比较程序:
for(i=0;i<28;i++)//经过循环比较,获得黑色轨迹与中轴的偏移视点
{
if(iPLace==iRoutPlace)
{
Angle=iplaceAngle;
}
}