微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 飞思卡尔那些事之离散型光电管路径识别

飞思卡尔那些事之离散型光电管路径识别

时间:11-23 来源:互联网 点击:
光电管路径识别算法

资源:
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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top