基于ARM_CORTEX_M4的磁导航自主路径识别系统毕业设计.docx_第1页
基于ARM_CORTEX_M4的磁导航自主路径识别系统毕业设计.docx_第2页
基于ARM_CORTEX_M4的磁导航自主路径识别系统毕业设计.docx_第3页
基于ARM_CORTEX_M4的磁导航自主路径识别系统毕业设计.docx_第4页
基于ARM_CORTEX_M4的磁导航自主路径识别系统毕业设计.docx_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

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

文档简介

北京联合大学毕业设计摘 要本文详细介绍了基于ARM Cortex M4的磁导航自主路径识别系统的设计与实现过程。本系统以飞思卡尔32位单片机MK60DN512ZVLL10为控制核心,通过电感检测赛道上通电导线产生的磁场来判断赛道信息,从而控制小车自主行驶。对电感切割磁场产生的信号,先进行了选频,然后使用运放对信号进行放大,再利用肖特基二极管对交流信号进行检波,最后送入AD中获得小车在赛道上的位置信息。在控制小车自主循迹中,方向与速度控制上分别使用了位置式PID与增量式PID。在调试PID参数以及系统时,还使用了上位机软件。 关键词:磁导航 自主路径识别 MK60DN512ZVLL10 PIDAbstractThis paper describes the design and implementation process based on ARM Cortex M4 magnetic navigation path independent recognition system. This system MK60DN512ZVLL10 Freescale 32-bit microcontroller to control the core, through the inductor wire produces a magnetic field detection circuit is energized to determine the track information to control car autonomous driving. Cutting the magnetic field generated by the inductor signal, the first for a selected frequency, and then use the op amp to amplify the signal, and then use the AC signal Schottky diode detector, and finally into the AD position information obtained in the car on the track. In self-control car tracking in the direction and speed control are used positional PID and incremental PID. PID parameters during commissioning and system, also used the PC software.矚慫润厲钐瘗睞枥庑赖。Key Words:magnetic navigation path independent recognition MK60DN512ZVLL10 PID聞創沟燴鐺險爱氇谴净。V目 录摘 要I残骛楼諍锩瀨濟溆塹籟。AbstractII酽锕极額閉镇桧猪訣锥。引 言- 1 -彈贸摄尔霁毙攬砖卤庑。1硬件电路- 2 -謀荞抟箧飆鐸怼类蒋薔。1.1单片机最小系统板- 2 -厦礴恳蹒骈時盡继價骚。1.2电源模块- 2 -茕桢广鳓鯡选块网羈泪。1.2.1 LM1117- 2 -鹅娅尽損鹌惨歷茏鴛賴。1.2.2 LM2940- 3 -籟丛妈羥为贍偾蛏练淨。1.2.3 LM2576-ADJ- 3 -預頌圣鉉儐歲龈讶骅籴。1.2.4 主板总体设计- 4 -渗釤呛俨匀谔鱉调硯錦。1.3 电机驱动模块- 4 -铙誅卧泻噦圣骋贶頂廡。1.4 传感器模块- 6 -擁締凤袜备訊顎轮烂蔷。1.4.1磁感应传感器- 6 -贓熱俣阃歲匱阊邺镓騷。1.4.1.1 选频电路设计- 6 -坛摶乡囂忏蒌鍥铃氈淚。1.4.1.2放大电路设计- 7 -蜡變黲癟報伥铉锚鈰赘。1.4.1.3检波电路设计- 7 -買鲷鴯譖昙膚遙闫撷凄。1.4.1.4磁感应传感器整体设计- 7 -綾镝鯛駕櫬鹕踪韦辚糴。1.4.1.5磁感应传感器的实际电路设计- 8 -驅踬髏彦浃绥譎饴憂锦。1.4.2速度传感器- 8 -猫虿驢绘燈鮒诛髅貺庑。1.4.3起跑线检测传感器- 8 -锹籁饗迳琐筆襖鸥娅薔。2 机械调校- 10 -構氽頑黉碩饨荠龈话骛。2.1 舵机的安装- 10 -輒峄陽檉簖疖網儂號泶。2.2 前瞻的固定- 10 -尧侧閆繭絳闕绚勵蜆贅。2.2.1电感的排布- 10 -识饒鎂錕缢灩筧嚌俨淒。2.2.2前瞻的长度- 11 -凍鈹鋨劳臘锴痫婦胫籴。2.3 编码器的安装- 11 -恥諤銪灭萦欢煬鞏鹜錦。2.4 降低重心- 11 -鯊腎鑰诎褳鉀沩懼統庫。3 软件编写- 13 -硕癘鄴颃诌攆檸攜驤蔹。3.1 开发环境- 13 -阌擻輳嬪諫迁择楨秘騖。3.2 程序下载- 13 -氬嚕躑竄贸恳彈瀘颔澩。3.3 底层驱动编写- 13 -釷鹆資贏車贖孙滅獅赘。3.3.1 GPIO模块- 14 -怂阐譜鯪迳導嘯畫長凉。3.3.1.1 打开时钟- 14 -谚辞調担鈧谄动禪泻類。3.3.1.2 设置引脚功能- 15 -嘰觐詿缧铴嗫偽純铪锩。3.3.1.3 GPIO口方向设置- 15 -熒绐譏钲鏌觶鷹緇機库。3.3.2 PIT模块- 16 -鶼渍螻偉阅劍鲰腎邏蘞。3.3.2.1 时钟设置- 16 -纣忧蔣氳頑莶驅藥悯骛。3.3.2.2 使能PIT模块- 16 -颖刍莖蛺饽亿顿裊赔泷。3.3.2.3 计算并设定定时器初始值- 16 -濫驂膽閉驟羥闈詔寢賻。3.3.2.4 使能PIT定时中断- 17 -銚銻縵哜鳗鸿锓謎諏涼。3.3.3 ADC模块- 17 -挤貼綬电麥结鈺贖哓类。3.3.3.1 ADC设置步骤- 17 -赔荊紳谘侖驟辽輩袜錈。3.4 控制模块- 18 -塤礙籟馐决穩賽釙冊庫。3.4.1方向控制- 18 -裊樣祕廬廂颤谚鍘羋蔺。3.4.2速度控制- 18 -仓嫗盤紲嘱珑詁鍬齊驁。3.4.3电感值处理- 19 -绽萬璉轆娛閬蛏鬮绾瀧。3.4.4丢失处理- 20 -骁顾燁鶚巯瀆蕪領鲡赙。3.5调试系统- 20 -瑣钋濺暧惲锟缟馭篩凉。3.5.1 调试工具- 20 -鎦诗涇艳损楼紲鯗餳類。3.5.1.1 上位机软件- 20 -栉缏歐锄棗鈕种鵑瑶锬。3.5.2.2 无线串口- 21 -辔烨棟剛殓攬瑤丽阄应。3.5.2 PID参数整定- 21 -峴扬斕滾澗辐滠兴渙藺。结 论- 24 -詩叁撻訥烬忧毀厉鋨骜。参考文献- 25 -则鯤愜韋瘓賈晖园栋泷。致 谢- 26 -胀鏝彈奥秘孫戶孪钇賻。附 录A- 27 -鳃躋峽祷紉诵帮废掃減。附 录B- 29 -稟虛嬪赈维哜妝扩踴粜。- 51 -引 言近年来,无人驾驶汽车发展的飞速,所谓无人驾驶汽车就是车可以自动驾驶无需人工控制。国外比较有代表性的是谷歌无人驾驶汽车,通过各种传感器检测到其他车辆。国内的无人驾驶汽车也发展的比较快,比较有代表性的就是,2011年的国防科技大学发明的无人驾驶汽车。无人驾驶汽车有很好的发展前景,我们不需要再亲自开车,就有了更多的时间干其他事情,无人驾驶汽车还可以用于送货等。但是无人驾驶汽车还有很多难题恶待解决,比如无人驾驶汽车是否可以应对紧急情况,这就需要无人驾驶汽车变得更加智能。本论文详细介绍了采用飞思卡尔32位的MK60DN512ZVLL10作为控制核心,通过检测道路中心的通电导线的磁场使小车实现自主路径识别,对研究无人驾驶汽车具有现实意义。其实现了通过电感检测磁场来获取赛道信息,并利用获取的赛道信息来控制舵机转向,即控制小车行驶方向。为了让小车更快的自主循迹并且不冲出赛道,对速度还进行了控制,比如直道加速、弯道减速等。陽簍埡鲑罷規呜旧岿錟。1硬件电路硬件系统主要是由最小系统板,放大电路,主板,电机驱动等组成。在设计硬件电路原理图与PCB时,使用的是Altium Designer 9。沩氣嘮戇苌鑿鑿槠谔應。1.1单片机最小系统板Kinetis芯片是首款基于ARM Cortex M4内核的微控制器,基于飞思卡尔创新的90nm薄膜存储器(TFS)闪存技术,具有独特的Flex存储器(可配置的内嵌EEPROM)。Kinetis芯片融合了最新的低功耗革新技术,具有高性能、高精度的混合信号能力,宽广的互连性,人机接口和安全外设。钡嵐縣緱虜荣产涛團蔺。我使用的最小系统板是Kinetis系列的MK60DN512ZVLL10,外观如图1.1所示。图1.1 MK60DN512ZVLL101.2电源模块电源模块好比是大厦的基石,小车的稳定运行是以电源模块稳定供电为基础的。为小车供电的是信号为7.2V 2000mAh Ni-Cd电池,需要提供给单片机、放大电路等3.3V的电源,提供给电机驱动、编码器等5V电源。因此,我们采用了低压差集成稳压器,低压差集成稳压器是线性稳压器的一种,相比于传统的线性稳压器、开关式电压稳压器等有结构简单、线性度好等优点。懨俠劑鈍触乐鹇烬觶騮。1.2.1 LM1117为了给单片机与传感器提供3.3V的电压,我们选用了三端稳压器LM1117。LM1117输出电压有可调式和固定式,我们使用的是3.3V固定输出电压。对于给传感器模块供电电路也是相同的。原理图如图1.2所示。謾饱兗争詣繚鮐癞别瀘。图1.2 3.3V单片机电源1.2.2 LM2940硬件电路上多处用到了5V的电源,包括电机驱动、编码器、无线串口等,还提供给了单片机与传感器的输入电压。我们选用了低压差集成稳定器LM2940来提供5V电源,电路原理图如图1.3所示。呙铉們欤谦鸪饺竞荡赚。图1.3 5V电源1.2.3 LM2576-ADJ舵机的额定工作电压为5V,为了能让舵机反应更快、更灵敏,我们通常会增大给舵机的电压,我们给舵机提供的电压是6V,使用的是开关式电源变换器LM2576-ADJ,ADJ的意思就是可以调节。可通过调节R6可变电阻来改变输出电压。电路原理图如图1.4所示。莹谐龌蕲賞组靄绉嚴减。图1.4 6V舵机电源1.2.4 主板总体设计主板总体供电示意图如图1.5所示,实物图如图1.6所示。图1.5 电源供电示意图图1.6 主板实物图1.3 电机驱动模块智能小车的动力来源于一台直流电机,电机不仅要有较快的速度,还需要有较高的加速度,因此对电机的转速要求较高。实现直流电动机正反转的电路有很多,比较常用的电路就是H桥驱动电路,因其形状类似于字母”H”而得名。H桥驱动电路示意图如下图所示。从电路图上,很容易看出,当开关Q1、Q4接通时,电流从左往右流过电机,电机正转;当开关Q3、Q2接通时,电流从右往左流过电机,电机反转。由此来控制直流电机的正反转。H桥示意图如图1.7所示。麸肃鹏镟轿騍镣缚縟糶。图1.7 H桥驱动电路示意图但是,当电机运行时,必须要保证Q1、Q2以及Q3、Q4不能同时导通,可使用图1.8电路示意图来解决。图1.8 H桥控制电路示意图驱动芯片我用的是英飞凌公司的BTS7960集成半桥驱动器,BTS7960有着出色的性能和极高的稳定性。使用两片BTS7960搭成一个H桥驱动电路,来控制电机。电机驱动原理图如图1.9所示,实物图如图1.10所示。納畴鳗吶鄖禎銣腻鰲锬。图1.9 电机驱动原理图图1.10 电机驱动实物图1.4 传感器模块1.4.1磁感应传感器小车需要通过检测道路中心的通有100mA导线的磁场来实现路径识别,使用的交变电流频率为20kHz,那么磁场检测就显得尤为重要了。现在测量磁场的方法很多,可以通过电感、磁阻、霍尔元件等交变磁场传感器来测量磁场。我使用的是10mH工字型电感,如图1.11所示。風撵鲔貓铁频钙蓟纠庙。图1.11 10mH工字型电感1.4.1.1 选频电路设计电感切割磁场会产生感应电动势,但是这个感应电动势信号太弱,只有几十毫伏,而且噪声很多,会受到周围不同频率的磁场的干扰。因此,电感切割磁场产生的电动势需要进行选频,减少其他干扰信号的影响。利用电感电容即可组成简单的并联谐振电路来实现选频电路,谐振频率要求为20kHz,则可以通过公式1-1计算出C的值。灭嗳骇諗鋅猎輛觏馊藹。2fL=12fC (式1-1)铹鸝饷飾镡閌赀诨癱骝。将L=10mH,f=20000Hz代入公式,可以得到C=6.3 nF左右,在市场上能够买到的最为接近6.3nF电容的标称电容为6.8nF。电路图如图1.12所示。攙閿频嵘陣澇諗谴隴泸。图1.12 并联谐振电路1.4.1.2放大电路设计选频后的信号还是很弱,因此为了能够更加准确地获得赛道信息,还需要对感应电压进行进一步的放大,这也是信号检测最主要的部分。可以选用运算放大器进行电压放大,运放在选型上应该选择低噪音、动态范围大、高速、单电源、增益带宽积较高的运放。运放的选择有很多,我们试过由TI公司生产的LMV358,虽然LMV358价格便宜,容易购买,但是其增益带宽积仅有1MHz,在20kHz的信号频率下,开环增益仅有50倍,而一般放大倍数要大于100倍,所以性能一般。在运放芯片的不断尝试中,我们最终选择了性能卓越的OPA2350,也是TI公司生产的高速、单电源、至轨运放,其增益带宽积达到了38MHz,在20KHz频率下开环增益达到了1900倍,这足以看出来OPA2350性能非常的出色。趕輾雏纨颗锊讨跃满賺。1.4.1.3检波电路设计经过选频和放大后的电压信号仍然是交流信号,如果直接将交流信号接入单片机的AD端口,使用单片机直接采样交变电压信号的话,采集数据的处理方面比较麻烦。所以,一般将交流信号整流为直流信号再送入AD中进行处理。可以使用肖特基二极管,对信号进行检波处理,以便可以获得更大的动态范围。夹覡闾辁駁档驀迁锬減。1.4.1.4磁感应传感器整体设计从电感切割磁场产生感应电动势要经过选频、放大、检波,最后再送入AD中。过程如图1.13所示。图1.13 放大电路过程1.4.1.5磁感应传感器的实际电路设计放大电路使用的运放芯片是OPA2350,电感切割磁场产生的电动势经过选频、放大、检波等步骤。设计的电路图如图1.14所示,实物图如图1.15所示。视絀镘鸸鲚鐘脑钧欖粝。图1.14 放大电路原理图图1.15 放大电路实物图1.4.2速度传感器小车在自主循迹过程中,速度的控制很重要。小车在直道上加速行驶,进入弯道后减速行驶,否则很容易冲出赛道。而在控制小车速度的环节上,首先得获得小车的当前速度,然后才能决定是加速还是减速。用于测速的传感器通常有霍尔传感器、光电传感器、测速电机、编码器四种,我们选用了测量精度较高,稳定性较好的编码器来进行测速。根据精度要求,我们购买了360线的欧姆龙编码器,为数字量输出,可供单片机直接采集以获得速度值。偽澀锟攢鴛擋緬铹鈞錠。1.4.3起跑线检测传感器智能小车除了能够实现自主循迹外,还要有跑完一圈后自动停车功能。电磁组的赛道在起跑线处有永磁铁,用来检测起跑线。选择干簧管来检测永磁铁无疑是最简单的方法,干簧管我也试了很多种,有的好用有的不好用,好不好用是以可以检测的最高高度衡量的,而且有的干簧管外表是玻璃的,很容易打碎,经过选择,发现了外面有塑料包装的干簧管,不容易损坏,我最终使用的是这个,检测高度大约有1.5CM,这个高度已经足够了。当然磁铁的大小不同,稍微有些差异。緦徑铫膾龋轿级镗挢廟。2 机械调校2.1 舵机的安装小车转向是通过舵机来驱动的,所以舵机的安装会影响到小车转向的角度和灵敏度。由于小车上面的空间有限,为了合理利用,将舵机安装位置挪到了两前轮之间。舵机的固定需要支架,使用了铝合金材料的支架,不仅结实而且特别轻,不会使小车的重心向前移。舵机的安装如图2.1所示。騅憑钶銘侥张礫阵轸蔼。图 2.1 舵机的安装2.2 前瞻的固定2.2.1电感的排布智能小车的前瞻应该尽量长点,正所谓“站得高看得远”,足够的前瞻量能提前获得赛道的信息以便更好的控制小车。当使用多个传感器的时候,传感器之间的距离越大,便越能获得更多的赛道信息。我使用的是两个电感的方案,两个电感之间的距离为25cm左右,如图2.2所示。疠骐錾农剎貯狱颢幗騮。图2.2 电感的排布2.2.2前瞻的长度由于车模不限制长度,所以为了能够提前获取赛道信息以便更快的响应,我增加了前瞻的长度。当然,并不是说前瞻越长越好,而是需要一个合适的长度,与控制算法有关系,要结合实际情况。但是,短前瞻效果肯定不好。前瞻的材料使用的是碳纤维杆,为了减轻前瞻的重量,使小车的中心不往前移,我试了不同直径的碳纤维杆,以小车行驶时前瞻不颤动为标准,选用了直径为4*2mm的规格。前瞻的固定如图2.3所示。镞锊过润启婭澗骆讕瀘。图2.3 前瞻的固定2.3 编码器的安装编码器的安装需要注意的事项就是齿轮的咬合,包含编码器与差速、差速齿轮与电机。调节齿轮之间的距离,然后打开电机听声音可以判断齿轮咬合的松紧。如果转动声音尖锐,则表示齿轮咬合的太紧。如果声音零碎,则表示齿轮咬合的太松。齿轮咬合的太松,容易损坏齿轮,齿轮咬合的太紧,影响电机。所以,调整齿轮咬合,以松紧合适为准,既不松动,也不卡滞。编码器的安装如图2.4所示。榿贰轲誊壟该槛鲻垲赛。图2.4 编码器的安装2.4 降低重心为了让小车运行稳定,转向灵活,过弯时不侧翻,通常会降低小车的重心。小车上最重的就是电池了,所以为了降低小车的重心,我将电池的高度往下降了,并且位置往后移动一点。还去掉了小车上一些无关紧要的零件,最大限度的减轻小车的重量,使小车运行起来轻便,转向灵敏,加速减速更快。电池的安装如图2.5所示。邁茑赚陉宾呗擷鹪讼凑。图2.5 电池的安装3 软件编写3.1 开发环境Kinetis是基于ARM Cortex M4核心的,可以使用飞思卡尔公司推出的面向嵌入式应用开发的软件工具CodeWarrior(简称CW),还可以选用第三方的开发环境,我使用的是嵌入式系统开发工具IAR。软件界面如图3.1所示。 嵝硖贪塒廩袞悯倉華糲。图3.1 IAR界面3.2 程序下载程序写好之后,还需要下载到单片机中,我们使用的是USB接口的J-LINK下载器,将电脑与单片机通过J-LINK连接后,在IAR界面的右上角有个下载按钮,点击下载即可。IAR程序下载界面如图3.2所示。该栎谖碼戆沖巋鳧薩锭。图3.2 IAR程序下载界面3.3 底层驱动编写Kinetis芯片是首款基于ARM Cortex M4内核的微控制器,基于飞思卡尔创新的90nm薄膜存储器(TFS)闪存技术,具有独特的Flex存储器(可配置的内嵌EEPROM)。Kinetis芯片融合了最新的低功耗革新技术,具有高性能、高精度的混合信号能力,宽广的互连性,人机接口和安全外设。劇妆诨貰攖苹埘呂仑庙。Kinetis系列微控制器第一阶段产品有五个系列,如图3.3所示。图3.3 Kinetis微控制器产品组合3.3.1 GPIO模块GPIO即输入输出端口,常用于输入或输出逻辑信号。3.3.1.1 打开时钟使用GPIO需要先启用该端口的时钟,否则无法使用,而时钟需要通过SIM模块的SIM_SCGC5寄存器设置,SIM_SCGC5寄存器图3.4所示。臠龍讹驄桠业變墊罗蘄。图3.4 SIM_SCGC5寄存器将SIM_SCGC5寄存器的第9、10、11、12、13位设置为1,IO口模块获得系统时钟,然后才能正常工作。可以使用宏定义来实现,不容易出错。鰻順褛悦漚縫冁屜鸭骞。宏定义的代码如下:#define SIM_SCGC5_PORTA_MASK 0 x200u穑釓虚绺滟鳗絲懷紓泺。#define SIM_SCGC5_PORTB_MASK 0 x400u隶誆荧鉴獫纲鴣攣駘賽。#define SIM_SCGC5_PORTC_MASK 0 x800u浹繢腻叢着駕骠構砀湊。#define SIM_SCGC5_PORTD_MASK 0 x1000u鈀燭罚櫝箋礱颼畢韫粝。#define SIM_SCGC5_PORTE_MASK 0 x2000u惬執缉蘿绅颀阳灣熗鍵。SIM_SCGC5寄存器的设置代码如下:SIM_SCGC5|=SIM_SCGC5_PORTA_MASK|SIM_SCGC5_PORTB_MASK|SIM_SCGC5_PORTC_MASK|SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;贞廈给鏌綞牵鎮獵鎦龐。3.3.1.2 设置引脚功能Kinetis系列的单片机的IO口一般都有复用功能,所以我们只有通过设置启用GPIO功能,IO口才能使用,所以打开时钟之后就需要将使用的引脚设为GPIO模块,通过设置引脚控制寄存器(PORTx_PCRn)来实现。该寄存器如图3.5所示。嚌鲭级厨胀鑲铟礦毁蕲。图3.5 PORTx_PCRn寄存器引脚复用功能通过设置MUX即可,将MUX设为1则该引脚GPIO功能即启用。代码如下:PORTE_PCR0= 0 x00000100;/E0引脚设置为GPIO模式还可以通过宏定义的方式,宏定义如下:#define PORT_PCR_MUX(1) 0 x00000100薊镔竖牍熒浹醬籬铃騫。3.3.1.3 GPIO口方向设置大多数单片机的IO口都是双向的,当然功能强大的Kinetis系列的单片机也不例外。在使用IO口前,需要设置IO口为输入或者输出,可通过设置IO口方向寄存器,即GPIOx_PDDR寄存器来确定IO口为输入还是输出。GPIOx_PDDR寄存器如图3.6所示。齡践砚语蜗铸转絹攤濼。图3.6 IO口方向寄存器GPIOx_PDDR其中,PDD为引脚方向设置位,PDDx=1是将引脚x设置为输出,PDDx=0是将引脚x设置为输入。具体代码如下:GPIOE_PDDR|=0X00000001;/E0设置为输出3.3.2 PIT模块中断程序的作用是,中断发生后,当前程序会被立即暂停,然后进入中断程序,等中断服务程序执行完毕,再恢复现场,并回到断点处继续执行刚才的程序。不同的中断源,触发中断的事件也不同。在单片机的应用中,经常会用到的一种中断就是定时中断,当定时时间到时则触发中断。定时中断在智能车中最主要的应用就是测速,而Kinetis中的PIT模块用来做简单的定时是最简单的一种。PIT模块即周期定时模块,主要功能是用来产生定时中断。定时中断的原理是通过对总线时钟进行计数,当计数递减到0时即产生中断,我们可以通过给每个计数器赋予不同的初值来获得想要的中断周期,每次中断后,计数器便会自动加载我们自己设定的初值,如此反复即实现了定时中断的功能。绅薮疮颧訝标販繯轅赛。3.3.2.1 时钟设置如果要使用定时中断的话,就需要先打开时钟。通过寄存器SIM_SCG6的设置可以打开PIT模块的时钟,将寄存器SIM_SCG6的第1215位设置为1即可打开PIT时钟,具体代码如下:饪箩狞屬诺釙诬苧径凛。SIM_SCGC6|=SIM_SCGC6_PIT_MASK;/打开pit时钟其中SIM_SCGC6_PIT_MASK为宏定义:#define SIM_SCGC6_PIT_MASK 0 x800000u烴毙潜籬賢擔視蠶贲粵。3.3.2.2 使能PIT模块开启PIT模块的时钟之后,需要使能PIT模块,通过设置PIT模块控制器即PIT_MCR来实现,PIT_MCR寄存器如图3.7所示。鋝岂涛軌跃轮莳講嫗键。313029282726252423222120191817161514131211109876543210ReadMDISFRZWriteReset00000000000000000000000000000010图3.7 PIT_MCR寄存器其中,MDIS为模块使能位,默认为1,1为禁止状态,将其置0即可。具体代码如下:PIT_MCR=0;/PIT模块使能3.3.2.3 计算并设定定时器初始值下面便要设定定时器的初始值来实现自己想要的定时周期了。因为每次中断重新载入计数器初始值需要一个时钟周期,然后递减到0,所以我们在计算计数器初始值时需要考虑这个额外的时钟周期,即每两个周期中断一次。撷伪氢鱧轍幂聹諛詼庞。由此可得:计数初值LDVAL = (定时周期/ 模块时钟周期) -1或者:计数初值LDVAL = (定时周期*模块时钟频率) -1将计数初值LDVAL赋值给定时器初值寄存器PIT_LDVALn即可,具体代码如下:PIT_LDVAL0=time*60000-1;/计数器初始化,time为中断周期,单位ms3.3.2.4 使能PIT定时中断最后还要使能定时器,使能中断。用于设置对应通道的定时器是否使能以及是否产生中断请求的寄存器为定时器控制寄存器PIT_TCTRLn,如图3.8所示。踪飯梦掺钓貞绫賁发蘄。313029282726252423222120191817161514131211109876543210ReadTIETENWriteReset00000000000000000000000000000000图3.8 PIT_TCTRLn寄存器其中,TIE=1为定时器中断使能,TEN=1为定时器使能。具体设置代码为:PIT_TCTRL0=PIT_TCTRL_TEN_MASK|PIT_TCTRL_TIE_MASK;/定时器使能,中断使能婭鑠机职銦夾簣軒蚀骞。其中PIT_TCTRL_TEN_MASK与PIT_TCTRL_TIE_MASK为宏定义:#define PIT_TCTRL_TEN_MASK 0 x1u譽諶掺铒锭试监鄺儕泻。#define PIT_TCTRL_TIE_MASK 0 x2u俦聹执償閏号燴鈿膽賾。3.3.3 ADC模块智能车既然是自主循迹,那作为智能车“眼睛”的传感器是必不可少的,而电磁小车的传感器是电感,电感通过切割通电导线周围的磁场产生电压,但是单片机本身无法对电压进行处理,需要进行AD转换,即将模拟量转换为数字量。ADC实际上是一把用来丈量电压大小的尺子,对于3.3V供电的Kinetis芯片而言,能够丈量电压的范围就是03.3V。缜電怅淺靓蠐浅錒鵬凜。3.3.3.1 ADC设置步骤a. 打开ADC模块时钟。b. 选择时钟和分频系数。c. 设置采样精度,是否启用长采样时间、高速模块,设置触发方式,是否启用硬件均值滤波、硬件比较,选择采样通道。骥擯帜褸饜兗椏長绛粤。d. 选择使用硬件触发还是软件触发。e. 等待转换完成,读取结果。其实,很多寄存器无需设置,使用默认值即可。3.4 控制模块3.4.1方向控制在方向控制上,我采用的是两个电感的方案,通过两个电感值用公式3-1:pos=(long)(Sensor0-Sensor1)*K/(long)(Sensor0)*Sensor1) (式3-1)癱噴导閽骋艳捣靨骢鍵。其中pos值代表小车中心偏离赛道中心的程度量,K值可以根据实际情况进行测定。获得赛道中心位置值后,还需要通过赛道中心值来控制舵机,我使用的是PD控制,控制公式3-2:鑣鸽夺圆鯢齙慫餞離龐。SERVO=(int)(CENTER+P*pos+D*poserro+D*preposerro/2) (式3-2)榄阈团皱鹏緦寿驏頦蕴。其中CENTER为舵机中值,然后根据实际情况不断地调节P与D的值,直道控制效果最佳为止。3.4.2速度控制在速度控制上,我们使用了比较经典的PID控制,具体是增量式PID控制,增量式PID控制可以使小车的速度变化比较平稳连续,如果使用位置式PID的话,小车的速度就会变化的比较大,不利于小车的平稳运行。逊输吴贝义鲽國鳩犹騸。/增量式PID速度控制/公式:增量=KP*En-KI*En-1+KD*(En-1-En-2)int PID_Control(int curr_Value)/传入当前值int currError;/当前误差int increment;/增量值currError = ideal_speed - curr_Value;/当前误差increment = (int)(P_value*currError);/增量值lastError = currError;/记住上次的误差prevError = lastError;/记住上上次的误差return increment;3.4.3电感值处理AD转换后的电感值由于比较杂乱,通常要对大量的电感值进行预处理,然后再利用处理后的电感值控制小车自主循迹。幘觇匮骇儺红卤齡镰瀉。可通过软件滤波来滤出干扰信号,来获取更为有价值的信号。通过一个算法即可实现,我们使用的是中值滤波,对因偶然因素而引起的波动有很好的克服作用。具体算法代码如下。誦终决懷区馱倆侧澩赜。unsigned int ADCmid(int channel) /ADCmid:(中值滤波)获取1路通道channel中值滤波后的A/D转换结果 医涤侣綃噲睞齒办銩凛。 int i,j,k,mid; i = ADCvalue(channel); j = ADCvalue(channel); k = ADCvalue(channel); if (i j) mid = i; i = j; j = mid; if (k = j) mid = j; else if (k = i) mid = k; else mid = i; return mid; 电感值通过中值滤波后,我们还进行了均值滤波,使电感值变化比较平稳,不至于跳变的特别厉害,具体算法代码如下。舻当为遙头韪鳍哕晕糞。unsigned int ADCave(int n,int channel)/ATDave:(均值滤波)对1路通道channel的A/D转换结果求n次平均值鸪凑鸛齏嶇烛罵奖选锯。 int i; int ave=0; for (i=0; i MCG_S_CLKST_SHIFT) != 0 x2)绥骅懸缙澀鷂禍紳撻粮。 /进入FBE模式, MCG_C5 = MCG_C5_PRDIV(0 x0e);/分频在24MHz之间,分频后频率=晶振频率/(PRDIV+1) 3.3MHz 馒锁開钥焖緒珏編軻錙。 MCG_C6 = 0 x0;/确保MCG_C6处于复位状态,禁止LOLIE、PLL、和时钟控制器,清PLL VCO分频器獄质嶇僅痺鲒潰脫帧開。 temp_reg = FMC_PFAPR;/保存FMC_PFAPR当前的值 FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | 鍥苋娛殫秽笾殇蕢谬藓。 FMC_PFAPR_M5PFD_MASK | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; /通过M&PFD置位M0PFD来禁止预取功能 杂砖墳雖紜飯曇覡墾騾。 /设置系统分频器 /MCG=PLL, core = MCG, bus = MCG/3, FlexBus = MCG/3, Flash clock= MCG/8轼栀嗶鑊绷瘍懔諍訝澤。 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(2) 尋头厭呛羈阴帥讕匦赞。 | SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(7); FMC_PFAPR = temp_reg;/从新存FMC_PFAPR的原始值 /设置VCO分频器,使能PLL为100MHz, LOLIE=0, PLLS=1, CME=0, VDIV=26訪齙剛玺苏滥夹趕萤凭。 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(30); /VDIV = 31 (x54)写韞僂谌虛鍤囈辮褻糝。 /VDIV = 26 (x50) while (!(MCG_S & MCG_S_PLLST_MASK); / wait for PLL status bit to set 罴醬畝饼誊歿凑鈑繳锱。 while (!(MCG_S & MCG_S_LOCK_MASK); / Wait for LOCK bit to set 鲢診龄師該铃書銨鴇开。 /进入PBE模式 /通过清零CLKS位来进入PEE模式 / CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0 MCG_C1 &= MCG_C1_CLKS_MASK; /等待时钟状态位更新 while (MCG_S & MCG_S_CLKST_MASK) MCG_S_CLKST_SHIFT) != 0 x3);磚緙鹅綱谩擞鴻鑌纸蘚。/PIT0初始化void Pit0_Init(uint32 time) /time为定时时间,单位ms SIM_SCGC6|=SIM_SCGC6_PIT_MASK;/打开pit时钟 PIT_MCR=0;/PIT模块使能 PIT_LDVAL0=time*50000-1;/计数器初始化,time为中断周期,单位 ms PIT_TCTRL0=PIT_TCTRL_TEN_MASK|PIT_TCTRL_TIE_MASK;/定时器使能,中断使能鬮煒鳍輥賠還鲂隊驼骡。 /ADC初始化void ADC_Init(void)SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK );/打开ADC0时钟SIM_SCGC3 |= (SIM_SCGC3_ADC1_MASK );/打开ADC1时钟ADC0_SC1A=0|ADC_SC1_ADCH(1);/选择ADC0ADC0_CFG1|= ADC_CFG1_ADIV(0);/时钟分频20ADC0_CFG1|=ADC_CFG1_MODE(2);/DIFF=0时,单端10位精度ADC0_CFG1|=ADC_CFG1_ADICLK(1);/时钟源选择,总线时钟Bus Clock/2毕懍鲅鵑较惻飾顳矯泾。ADC0_CFG2|=ADC_CFG2_ADHSC_MASK;ADC0_SC2=0;ADC0_SC3=0;ADC1_SC1A=0|ADC_SC1_ADCH(7);/选择ADC1通道ADC1_CFG1|= ADC_CFG1_ADIV(0);/时钟分频20ADC1_CFG1|=ADC_CFG1_MODE(2);/DIFF=0时,单端10位精度ADC1_CFG1|=ADC_CFG1_ADICLK(1);/时钟源选择,总线时钟Bus Clock/2钆歷驾无醬赔隽驍韉贈。ADC1_CFG2|=ADC_CFG2_ADHSC_MASK;ADC1_SC2=0;ADC1_SC3=0;void displaypara(uint8 line,uint8 row,int16 val) char n5; if(val0)/负数 n4=-48;/负号字型码 val=-val;/取反 else n4=(char)(val/10000); /计算各数值位 n3=(char)(val/1000)%10); n2=(char)(val/100)%10); n1=(char)(val/10)%10); n0=(char)(val%10); LCD_P8x16chr(line,row,n4+48); LCD_P8x16chr(line+6,row,n3+48); LCD_P8x16chr(line+12,row,n2+48); LCD_P8x16chr(line+18,row,n1+48); LCD_P8x16chr(line+24,row,n0+48);/* 延时1ms */徠鲣饮脸铄尝鏍鯢炀憑。void delay_1ms( void) unsigned int pp; for(pp=0;pp13000;pp+);/* 延时n ms */謂镊颇铵鋃誼铰鸚镉糁。void delay_nms(unsigned int n) while(n-) delay_1ms();/液晶显示延时void para_delay() unsigned int i,j; for(i=0;i=10000;i+) for(j=0;j=250;j+); /*变赵陧涼镦囑釧亿殮錙。函数名:keyscan作用:按键扫描,保存键值,记录按键状态标志,由10ms定时中断置位,主程序查询标志位调用入口参数:无返回值:无*/荟蓥闶漸陸讣轾减鈿異。void keyscan(void) keycode=(GPIOC_PDIR)&0 x0F;/读取键值,PC3,UP键,PC2,OK键,PC1,DOWN键,PC0,ESC键鹏筛镐討颛办費叹摄虏。 if(keycode!=0) /如果有键按下 switch(keyflag) case 0:/如果是新按按键 keyflag=1;/表示有键按下 keycode_last=keycode; break; case 1:/如果不是新按按键 if(keycode=keycode_last)/如果和上一次扫描时键值相同则表示去抖完成 keyflag=2; default:break; else/所有按键为抬起状态 keyflag=0; keycode_last=0; void setPARA(unsigned char i) unsigned char flag=0; unsigned int val; byte k; /LCD_P14x16Str(0,0,实训基地); LCD_P8x16Str(0,0,disparai); val=parameteri; displaypara(0,2,val); while(flag=0) /GetSensor();/获取传感器的值 if(keyscan_F=1)/按键扫描时间到 keyscan_F=0; keyscan(); if(keyflag=2)/如果有键按下且去抖完成 switch(keycode) case 8:/esc键 parameteri=val; flag=1; set_F=1; FTFL_Erase(FLEXNVM_START_ADDR); FTFL_Write_LongWord(FLEXNVM_START_ADDR,0);/先写入设置标志,0表示dflash已写入参数 糝殒锔雋駛鶯诼垆辐驄。 for(k=1;k=Para_Num;k+) FTFL_Write_LongWord(FLEXNVM_START_ADDR+k*4,parameterk-1);頜层铢壶鲜儀計尧當涇。 break; case 4:/ok键s5键 parameteri=val; flag=1; break; case 2:/down键s4键 if(i=2|i=3) val-=10; else val-; displaypara(0,2,val); break; case 1:/up s2键 if(i=2|i=3) val+=10; else val+; displaypara(0,2,val); break; default: break; keyflag=3; /设定参数void init_parameter() unsigned char i=0; while(set_F=0)/等待设置参数完成 for(i=0;iPara_Num;i+) /6个参数,可自行修改参数数目 setPARA(i); LCD_Fill(0 x00); if(set_F=1) break; int get_max(int a,int b) if (ab) return b; else return a;void get_parameter() WANp= parameter0; Fd= parameter1; MAXSPEED=parameter2; MINSPEED=parameter3;/* ATD模块函数 */滚伛钮硕鷙耸蒋忆貯赠。unsigned int ADCvalue(int channel) /获取通道channel=通道号(015)的10位A/D转换结果 该通道的A/D转换结果(01023)铣饜酝贻龙鵠臚拧奥凭。 int temp=0;if(channel=0)ADC0_SC1A=0|ADC_SC1_ADCH(1);while(ADC0_SC1A&ADC_SC1_COCO_MASK)=0);temp=ADC0_RA;else if(channel=1)/加速度计 ADC0_SC1A=0|ADC_SC1_ADCH(20);while(ADC0_SC1A&ADC_SC1_COCO_MASK)=0);temp=ADC0_RA;else if(channel=2)/电磁传感器1 ADC1_SC1A=0|ADC_SC1_ADCH(1);while(ADC1_SC1A&ADC_SC1_COCO_MASK)=0);temp=ADC1_RA;else if(channel=3)/电磁传感器2 ADC1_SC1A=0|ADC_SC1_ADCH(20);while(ADC1_SC1A&ADC_SC1_COCO_MASK)=0);temp=ADC1_RA;return temp;unsigned int ADCmid(int channel) /ADCmid:(中值滤波)获取1路通道channel中值滤波后的A/D转换结果 撾鉬辙魇侨絢绾来诔緊。 int i,j,k,mid; i = ADCvalue(channel); j = ADCvalue(channel); k = ADCvalue(channel); if (i j) mid = i; i = j; j = mid; if (k = j) mid = j; else if (k = i) mid = k; else mid = i; return mid; unsigned int ADCave(int n,int channel)/ATDave:(均值滤波)对1路通道channel的A/D转换结果求n次平均值賒調轧憊劌髋糾殡縣锲。 int i; int ave=0; for (i=0; in; i+) ave += ADCmid(channel); ave /= n; return ave;int abs(int x) if (x70) Sensor1=lastsensor1; if(sensorerro070) Sensor0=lastsensor0; lastsensor1=Sensor1; lastsensor0=Sensor0; /动态显示void display_dongtai_canshu(void) /第一列显示 LCD_P8x16Str(0,0,Sen:); displaypara(32,0

温馨提示

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

评论

0/150

提交评论