STC12C5A60S2做的智能小车——上位机可控制行驶路径、超声避障、信息化远程监控
单片机实践之闭门造车安徽师范大学07级电子信息工程
一、造车综述
从2003年全国电子设计大赛以来智能小车一直备受青睐,大家都在前人的基础上纷纷亮出自己的得意之作。且大部分是以循迹小车为主题,主控芯片自然是用的赞助商提供的片子为多。其中飞思卡尔、MPS430等都是智能小车的热门主控芯片,甚者有采用FPGA、DSP、ARM来做控制台的,个人觉得Cortex-M3很适合,不过既然是单片机实践自然要从基础的做起,这样以后也可以很方便的移植到Cortex-M3上。而此文为大家介绍的是采用STC12C5A60S2为主控芯片,STC89S52为从处理器搭建的智能小车平台。
简单介绍一下智能小车平台需要实现的功能:上位机无线遥控可发送速度、转向、行车时间、轨迹、测距、自动蔽障等控制命令,同时可以反馈实时速度、距离、电源电压、功率等状态数据。
二、总体方案
测速采用光电管或者霍尔传感器来实现,而这些传感器的待处理信号都是开关量也就是周期性的脉冲,故测速需要占用两只定时器。测距离目前常用的有超声波测距、红外测距两种,这两种方案都至少占用一只定时器。电机调速采用PWM信号,如果采用定时器来产生PWM信号的话又需要占用一只定时器。再算上一些串行口、定时器查询等估计别说是普通的AT89S52就连AVR的片子也很吃力,所以采用两片单片机也变得合情合理了。而且也为以后扩展其他信号传感器提供接口。一般片级通信多是采用SPI通信,51的片子很少有支持,所以大部分SPI多是软件模拟的(某些串行的AD转换)。不过这里要是使用模拟的SPI来实现片级通信的话会由于没有SPI中断给通信带来很大的局限性,或者有些人会想到使用定时器中断来查询实现软件模拟的SPI片级通信,而这样又会占用定时器(不考虑定时器服用的情况下)。分析考虑所需的资源,最终选取STC12C5A60S2作为主控制器,该芯片自带2路PWM控制器、2个定时器、2个串行口支持独立的波特率发生器、3路可编程时钟输出、10位AD转换器、一个SPI接口等。
测速模块挂在STC12C5A60S2上面并配置一路PWM输出至直流电机驱动模块(后轮驱动),同时通过光耦隔离控制直流电机转向以及步进电机步进节拍。STC89S52负责超声测距通过串行口发送至STC12C5A60S2。主控芯片综合处理各方面的信息,通过另一个串行口与PC机通信。无线模块最初采用自带串行接口的蓝牙模块,但由于蓝牙距离不够、重启系统需重新配置等原因后期采用NRF2401来替代。总体结构框图如下(采用Microsoft Office Visio绘制)
三、硬件原理
1、电机驱动:
智能小车采用12V直流电机为后轮驱动力,6V步进电机为前轮转向控制提供动力,故智能车平台需驱动12V直流电机和6V步进电机。由于需要控制小车的车速以及小车行驶的方向(包括转向以及前进、后退、停车),直流电机驱动采用常用的H桥电路,通过控制信号选通对管与否实现电机的正反转,并改变所加电压的占空比来改变电机转速。这里采用电机驱动专用芯片L298N,该芯片可驱动两路5-36V的直流电机或者一路四拍的步进电机。同时在L298N与主控芯片间通过四路光耦TLP521-4隔离消除干扰信号。
搭建好电路后不要直接在小车上调试,外界一只相同电压的电机测试模块。在STC12C5A60S2上配置好串口、PWM,实现串口接收的数据直接赋值给PWM定时器CCAP1L、CCAP1H。利用串口调试助手发送控制信息给STC12C5A60S2,同时辅助外界电源更改L298N的IN1和IN2,共同完成L298N电机驱动模块的调试。
2、光电对管测速
光电对管采用TCRT5000,由一只特殊的发光二极管和光电三极管构成,当二极管发出的光打在光电三极管的基极B上时三极管CE导通。而正常情况下二极管的光不能到达光电管的基极上,故通过在车轮上贴反射片即可实现对小车的测速。假设车轮均匀贴有n片反射片,测得光电三极管的输出脉冲频率为f,则车速=f/n。为了提高测速的精度,在信号后级添加比较器调理信号为标准的方波,调节比较器运放的偏置电压使方波信号最适合于测速。
同样适用外界电机(已配有自制的编码盘),给电机加电让其带动编码盘旋转,将光电对管靠近编码盘,用示波器观测输出脉冲信号的有无与好坏,调节比较器偏置电压使脉冲最接近于方波且幅度大于3.3V。
3、超声测距
超声波测距的方法有多种:如往返时间检测法、相位检测法、声波幅值检测法。本设计采用往返时间检测法测距。其原理是超声波传感器发射一定频率的超声波,借助空气媒质传播,到达测量目标或障碍物后反射回来,经反射后由超声波接收器接收脉冲,其所经历的时间即往返时间,往返时间与超声波传播的路程的远近有关。测试传输时间可以得出距离。假定s为被测物体到测距仪之间的距离,测得的时间为T,超声波传播速度为V表示,则有关系式S=VT/2 。
超声波发射部分是为了让超声波发射换能器TCT40-16T能向外界发出40 kHz左右的方波脉冲信号。编程由单片机端口输出40 kHz左右的方波脉冲信号,由于单片机端口输出功率不够,40 kHz方波脉冲信号分成两路,送给一个由74HC04组成的推挽式电路进行功率放大以便使发射距离足够远,满足测量距离要求,最后送给超声波发射换能器TCT40-16T以声波形式发射到空气中。发射部分的电路,如图4所示。图中输出端上拉电阻R31,R32,一方面可以提高反向器74HC04输出高电平的驱动能力,另一方面可以增加超声换能器的阻尼效果,缩短其自由振荡的时间。
上述TCT40-16T发射的在空气中传播,遇到障碍物就会返回,超声波接收部分是为了将反射波(回波)顺利接收到超声波接收换能器TCT40-16R进行转换变成电信号,并对此电信号进行放大、滤波、整形等处理后,这里用索尼公司生产的集成芯片CX20106,得到一个负脉冲送给单片机的INT0引脚,以产生一个中断。
接在CX20106的第五脚上的电阻,用以设置带通滤波器的中心频率f0,阻值越大,中心频率越低。电路中采用一只粗调的可变电阻和一只精密调节的电阻串联而成。调节函数信号发生器产生40K的方波,接在超声发射电路的输入端,同时用示波器观测超声接收电路的输出端。用书本等模拟障碍物,调节两只电阻观测示波器看接收端否会产生电平跳变。
若产生跳变则发射与接收电路调试完成。
4、电源模块
对于小车而言电源是整个系统的咽喉,考虑到体积、重量、电能容量等。这里我们选取8节1.5V锂电池串联起来作为总电源输出(12V),采用LM78L05、LM317构成整个电源模块。
5、无线通信模块
无线通信采用现成的串行接口的蓝牙模块,只需要配置主从机、信道、通信密钥、波特率即可实现无线串行通信。这样PC和主控STC12C5A60S2只需将通信理解为串行通信,给程序构架带来便利。不过需要考虑通信接口的问题:STC12C5A60S2是5V电压供电,TXD和RXD的通信电信号自然是以5V为参考电平;蓝牙模块是3.3V电压供电,TXD和RXD的通信电信号自然是以3.3V为参考电平。所以我们需要添加电平转换,实现STC12C5A60S2与蓝牙模块的正常通信。一般电平转换可以使用专用的芯片74xHCT或164245,电阻分压法、OC/OD 器件法、晶体管上拉电阻法等。不过对比几种方案同时考虑电平兼容、电源次序、速度/频率、输出驱动能力等,最终选取晶体管法,电路如下,图中NPN的管子可以选取8050,1815等,不过倒不是所有的NPN的管子都可行,调试时使用9014就不能实现正常通信,估计是输出驱动能力不够的缘故。由于蓝牙的通信范围约束,我们还采用射频NRF2401来实现远距离的无线通信,由于篇幅有限这里不予细述。
四、软件构架
1、主控STC12C5A60S2
配置STC12C5A60S2定时器0为定时器方式2、10ms中断,定时器1为计数器方式,初值为0。累计100次定时器0中断为1秒,此时TL1即光电对管输入的脉冲频率,最终Speed=L*TL1/n(n为后轮上反射纸的片数,L为后轮的周长)。同时在此一秒内触发AD采集一次电源电压Voltage送入内存。当Voltage低于与设电压值时蜂鸣器报警。
配置STC12C5A60S2串行口2为方式2、独立波特率发生器9600、允许接收中断。当串口2接收到PC机数据转入中断处理程序,检测接收到的数据最高位,以此来区分数据是控制信号还是速度信息。
配置STC12C5A60S2串行口1为方式1、波特率固定、允许接收中断。当串口1接收到从处理器STC89S52数据将转入中断处理程序,将接收到的数据处理后送至主控的内存当中,以备主控芯片使用,同时等待PC命令随时传给PC机控制台。
配置STC12C5A60S2脉宽调制PWM为8位、无中断。主程序中循环执行PwmContral函数实时更改PWM定时器CCAP1L、CCAP1H的值。
PwmContral()程序如下(AutoFlags为超声自动调速标志):
uchar Pid(uchar Setpoint,uchar Achieved)
{
floatP=5,I=1,D=0.5;
floatEun=0.0,En=0.0,En1=0.0,En2=0.0;
int Output0=0,Output1=50;
En=Setpoint-Achieved;
Eun=P*En-I*(En-En1)+D*(En1-En2);
Eun=Eun/500;
Output0=Output1+(int)Eun;
Output1=Output0;
En2=En1;
En1=En;
return Output0;
}
uchar AutoDistance(uchar D,uchar S)
{
uint Output;
uint t;
t=D/S;
Output=0xff-0.75*t;
return Output;
}
void PwmContral()
{
if(AutoFlags==1)
{
PwmTemp = AutoDistance(Distance,Speed);
if(PwmTemp>256)
PwmTemp=256;
if(PwmTemp<0)
PwmTemp=0;
PwmLower=PwmTemp;
PwmHigher=PwmTemp;
CCAP1L=PwmLower;
CCAP1H=PwmHigher;
}
if(AutoFlags==0)
{
if((Speed-ContralSpeed)<=-100||(Speed-ContralSpeed)>=100)
PwmTemp=Pid(ContralSpeed,Speed);
if(PwmTemp>256)
PwmTemp=256;
if(PwmTemp<0)
PwmTemp=0;
PwmLower=PwmTemp;
PwmHigher=PwmTemp;
CCAP1L=PwmLower;
CCAP1H=PwmHigher;
}
}
2、从处理器STC89S52
配置STC89S52串行口为方式1、波特率固定、允许接收中断(与主控的串行口1作双机通信交换数据信息)。此种情况下需将主控芯片与从处理器的晶振选取为同一数值,这里我们选取12M。若是选取11.0592M会导致测距的定时器0和定时器1算得的时间不准确,极大影响测距结果。同时主控选取12M晶振的同时也会影响它与PC机之间的双机通信,故我们配置STC12C5A60S2的串行口2为独立波特率发生器。
配置STC89S52定时器0为16为定时器、初值为0、开定时器0允许中断,定时器1为方式2、中断产生40K方波、关定时器1。定时器0中断处理程序中开定时器1允许中断、重装初值。定时器1中断处理程序中产生40K方波,通过控制产生2个脉冲后关掉定时器1,开外部中断0。
外部中断0处理程序中,关掉定时器0、定时器1和总中断EA同时置位接收成功标志ReceFlags,最终发送超声波到接收到超声波时间差为Time=256*TH0+TL0。对于时间Time需要作适当的修正补偿,带入Distance=Time*0.017即可得到小车与前方障碍物的距离。将Distance送入STC89S52的内存中,以备通过串行口发送至主控的串行口1。
主程序中等待ReceFlags,当接收成功清除标志同时通过短延时控制测量间隔,也就是再一次发送2个脉冲的超声波时间。
3、上位机界面
采用Visual Baisc6.0编写智能车控制台,使用MSCcom串口通信控件实现数据传输,实时监测与控制。
4、双机通信
考虑到小车需要实时反馈速度以及测得前方的障碍物的距离,同时需要将居多控制命令发送给小车。由于主控芯片是8位的片子,串口缓冲区大小就是1个字节(8位数据),一般将信息数据送入堆栈,不过对于数据处理就变得复杂了。这里为了便捷我们考虑到速度值和控制命令都可以控制在1字节以内,只是需要区分这些信息而已。这里我们约定控制命令都以最高位为标志位,当最高位为1时是控制信息,为0时是速度信息。同时考虑到速度会超过0x7f所以在上位机上将速度除以2,等待下位机接收之后再还原。当然还需要对反馈的数据流作处理,将速度与上0xfe、距离或上0x01,以此通过最低位来区分数据流。
五、造车心得:
小车从规划到完工一共花了4天时间,虽然很普通也没有什么创新之处,却也和以往的小车不大一样。既然上位机已经可以往小车发送各种控制命令和信息了,那么只要我们在PC端的控制台上多花点时间,小车就有他的价值所在了。比如说雷区探雷,在小车上安装探雷的传感器,PC机解析人工提供的路径为控制命令和信息,按规律发送给小车,实现小车的人工智能。
学习单片机就是需要不停的实践,哪怕看起来很简单的你也需要自己去体会一下。就拿超声测距说事,很久以前就有所了解,觉得这玩意太简单了只不过是测一个时间而已(定时器一开一关当时就这样认为的)。然而自己去弄了才知道,需要考虑的问题很多,或许你会想到网上有现成的程序参考一下不就得了。但是如果等下一次你接触的很少有人研究怎么办,你去参考谁?有一套自己解决问题的方法比什么都强,而这个就来自多次的——单片机实践。
2010-8-17 lyzhangxaing
1、由于文章中有大量的图片,论坛上传图片不太方便所以就上传一个pdf版的完整篇啦,各位见谅一下
点击此处下载 ourdev_587099GZXQ65.pdf(文件大小:724K) (原文件名:闭门造车.pdf)
2、文中提及的框图是用Visio画的,上传全部框架
点击此处下载 ourdev_587100LMPQ4H.rar(文件大小:244K) (原文件名:框图Visio.rar)
3、第一版本无线采用的是蓝牙传输,后来采用nRF2401作为无线传输,上传文档一篇(自己写的不要拍砖啊 HoHo)
点击此处下载 ourdev_587101P2HE77.pdf(文件大小:417K) (原文件名:NR2401无线通信.pdf) 上传程序代码:
1、小车程序包括STC12C5A60S2和STC89C51的程序,程序框架是我个人写的驱动库Easy Hw OS,反正就是这样结构我看着舒服移植也很方便,同时也方便大家看。小弟初学程序写的不好,望各位多多提点意见,便于我成长,也不枉我敲这么多字,呵呵。
点击此处下载 ourdev_587107V6OVUV.rar(文件大小:140K) (原文件名:Double Transfer.rar)
2、nRF2401的程序包,为了方便以后使用采用AT89C2051加上nRF2401构成通信节点,很方便的实现无线串行通信,用户直接使用无须考虑其他问题。不过2051很少用了,可以在STC中找一款替代的片子,我看了一下一般在1.8元左右的STC片子都可以用来替代,价格在这摆着呢,相关的说明请看——NR2401无线通信.pdf。
点击此处下载 ourdev_587108HJURHN.rar(文件大小:52K) (原文件名:NFR2401无线串口.rar)
3、上位机控制台采用Visual Basic 6.0编写,程序还没达到预期的功能。是初版的不过模型已经搞定了,接下来就是将一系列的命令打包就可以啦,上传源代码
点击此处下载 ourdev_587109K60R2U.rar(文件大小:77K) (原文件名:智能车控制台.rar) 顶下 没有图片,笔记本的屏幕太小了,手头也没相机,只能截一张上位机控制台的图片了
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_587133H2RT3N.JPG
(原文件名:控制台.JPG) 顶下 ding`~~` 回复【楼主位】lyzhangxiang
-----------------------------------------------------------------------
楼主,你上位机那里不用单片机控制蓝牙发送吗?是用到了三块单片机吗? cool 楼主问一下,STC12C5A60S2这个单片机的复位引脚怎么处理?需不需要单独的上电复位电路,第二复位在什么情况下用? 呵呵 我毕设也是做这个不过到现在东西还没做出来 我用pt2262跟2272做行为控制跟数据传输 元件还没到不知道实时性怎么样 必须顶,太强了! 回复【8楼】undeadhuman
-----------------------------------------------------------------------
晶振不超过12M的时候就不需要第二引脚复位了,和普通8051一样。当跑的频率高的时候就需要第二引脚复位了 我是这样理解的 不知道对不对啦 回复【6楼】lxjjiang
-----------------------------------------------------------------------
你好 只用了两片单片机stc12c5a60s2和stc89c51 蓝牙那边是集成的 ,建议看后来改进的nRF2401的版本 回复【9楼】qq779089973
-----------------------------------------------------------------------
PT2262和PT2272是采用315M的吗?在超声接收模块,不过这个传输的信息量不大呀,好像最多只能是6个位的数据吧,这样你的8位数据如何传送呢 部分查表么? 很好 很有帮助 谢谢啊 你把我想做的做好了 厉害 酷! 搞了一大堆名词 谢谢~顶~ mark!! 谢谢分享,支持。 mark http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_587955MU5E70.jpg
(原文件名:未命名.jpg)
哈哈。抓了楼主好多蓝色词,感谢分享 MARK 阅~~~有时间慢慢在品味近期对 STC 1T 很反感~~~ 数码管亮度都不下平均 mark 谢谢 置酷 学习 MARK 很强大,顶! 好东西,支持楼主 mark 好好学习下,谢谢楼主! 顶 mark。。。。。。。。。。。 以前也做过智能小车,值得关注~ COOL!!要是早传上来就好了,呵呵,暑假的比赛就有参考了。不过,自己做过后再看又是另一种感觉,呵呵……谢谢楼主分享!! 强大···学习了 mark备用!谢谢楼主啊 马克 mark 回复【12楼】lyzhangxiang
-----------------------------------------------------------------------
不好意思 最近一直在做毕设 都没时间上网 确实用pt2262只能传6位数据把6位中的两位做为帧开始的标志 接收到2次数据却只收到一次开始标志就算收到一个字节,因为pt2262发一个数据会发4次 所以传输的速度算比较慢的 做毕设玩玩就好了 mark 回复【楼主位】lyzhangxiang
-----------------------------------------------------------------------
学习了 谢谢楼主 感觉功能够全的了,四天时间,呵呵,菜鸟小子羡慕啊 强力MARK 牛人!!!!MARK!! mark mark 我正做小车呢 帮助很大啊 mark!!! 好东西!谢谢分享! 必须顶! 标记 MARK ji记号 lihai a cool 挺不错,正想玩 做得不错,谢谢分享! 回复【1楼】lyzhangxiang
-----------------------------------------------------------------------
mark mark mark mark mark 不错,收藏一下,没仔细看,有视频监控吗? 好样的 八错八错!!!楼主很犀利! 大哥~你就是曙光啊 mark mark 顶 顶 不错,学习 mark mark Mark! GOOD 不错,顶 强人,顶一下。 不错啊,顶一下 我也想 标记 太好了,必须顶 mark mark 留着有用 mark mark mark mark mark mark 好,标记啦! mark mark mark 不错,MARK mark mark