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

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

时间:11-23 来源:互联网 点击:

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;
}
}

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

网站地图

Top