You are on page 1of 96

Freescale 智能车入门手册

(V0.6)

飞思卡尔半导体大学计划部

2010 年 3 月
版本历史

版本 时间 备注

V0.2 08/03/2010

V0.3 10/03/2010

V0.6 12/03/2010
目 录
第一章 概述 ................................................................................................................................1

第二章 工具与材料 ....................................................................................................................3

2.1 工具 ....................................................................................................................................3
2.1.1 测量类工具................................................................................................................. 3
1. 游标卡尺......................................................................................................................3
2. 卷尺..............................................................................................................................3
3. 直角尺..........................................................................................................................4
4. 丁字尺..........................................................................................................................4
2.1.2 五金类工具................................................................................................................. 4
1. 虎钳..............................................................................................................................4
2. 尖嘴钳..........................................................................................................................5
3. 偏口钳..........................................................................................................................5
4. 剥线钳..........................................................................................................................6
5. 美工刀..........................................................................................................................6
6. 剪刀..............................................................................................................................6
7. 锉刀、砂纸..................................................................................................................7
8. 螺丝刀..........................................................................................................................7
9. 扳手..............................................................................................................................7
10. 镊子............................................................................................................................8
11. 手动钢锯....................................................................................................................8
12. 锤子............................................................................................................................8
13. 吸锡器........................................................................................................................9
2.1.3 设备类工具................................................................................................................. 9
1. 电烙铁..........................................................................................................................9
2. 热风箱..........................................................................................................................9
3. 手钻............................................................................................................................10
2.1.4 仪器仪表类工具....................................................................................................... 10
1. 万用表........................................................................................................................10
1) 电压的测量 ........................................................................................................... 11
2) 电阻的测量 ........................................................................................................... 11
3) 二极管的测量 ....................................................................................................... 11
4) 三极管的测量 ....................................................................................................... 11
5) 其他档位 ............................................................................................................... 11
2. 示波器........................................................................................................................ 11
1) 区分模拟带宽和数字实时带宽 ...........................................................................12
2) 有关采样速率 .......................................................................................................12
2.2 材料 ..................................................................................................................................13
2.2.1 零件........................................................................................................................... 13
1. 螺钉、螺母................................................................................................................13

I
2. 轴承............................................................................................................................13
3. 铜柱、塑料柱............................................................................................................14
2.2.2 跑道材料................................................................................................................... 14
1. KT 板 ..........................................................................................................................14
2. 黑胶带........................................................................................................................14
2.2.3 加工材料................................................................................................................... 14
1. 铝材............................................................................................................................14
2. 不锈钢材....................................................................................................................14
3. 碳纤维........................................................................................................................14
2.2.4 其他........................................................................................................................... 14

第三章 模型车的组成及安装调整方法 ..................................................................................16

3.1 模型车组成 ......................................................................................................................16


3.2 模型车的安装 ..................................................................................................................17
3.2.1 转向机构的安装....................................................................................................... 17
1. 改变舵机安装方式....................................................................................................17
2. 改变车轮定位............................................................................................................18
3. 悬架............................................................................................................................19
3.2.2 差速器的安装........................................................................................................... 20
3.2.3 码盘的安装............................................................................................................... 20
3.2.4 传感器支架及赛道传感器的安装 ........................................................................... 21
3.2.5 速度传感器安装....................................................................................................... 22
3.2.6 电池的安装............................................................................................................... 22
3.2.7 驱动电机................................................................................................................... 22
3.2.8 伺服电机................................................................................................................... 23
3.3 机械调整 ..........................................................................................................................23
3.3.1 前轮倾角调节........................................................................................................... 23
3.3.2 齿轮传动机构调节................................................................................................... 25
3.3.3 后轮差速机构调节................................................................................................... 25
3.3.4 底盘高度的调整....................................................................................................... 26

第四章 循线原理与设计方案 ..................................................................................................27

4.1 循线原理 ..........................................................................................................................27


4.2 光电传感器方案 ..............................................................................................................27
4.2.1. 寻线原理.................................................................................................................. 27
4.2.2. 光电传感器方案的特点.......................................................................................... 27
4.2.3. 光电传感器分类...................................................................................................... 27
4.3 摄像头方案 ......................................................................................................................28
4.3.1 选用摄像头的优势................................................................................................... 28
1. 分辨率高....................................................................................................................28
2. 前瞻远........................................................................................................................29
3. 路径好........................................................................................................................30
4.3.2 摄像头信号原理....................................................................................................... 30

II
4-3.3 摄像头信号程序采集原理 ...................................................................................... 31
4.4.4 摄像头信号黑线提取程序原理 ............................................................................... 32

第五章 赛车常用电路 ..............................................................................................................34

5.1 电源电路 ..........................................................................................................................34


5.1.1 +12V 电压的获得...................................................................................................... 34
5.1.2 +6V 电压的获得........................................................................................................ 34
5.1.2 +5V 电压的获得........................................................................................................ 34
5.1.3 +3V 电压的获得........................................................................................................ 35
5.2 编码器电路 ......................................................................................................................35
5.3 通信部分电路 ..................................................................................................................36
5.4 电机驱动电路 ..................................................................................................................37

第六章 开发环境与主控芯片特性 ..........................................................................................38

6.1 HCS12 开发环境 ..............................................................................................................38


6.1.1 Codewarrior 的使用 .................................................................................................. 38
6.1.2 工程文件组织........................................................................................................... 42
6.1.3 编译程序................................................................................................................... 43
6.1.4 样例........................................................................................................................... 45
6.2 DG128 的特点 ..................................................................................................................45
6.2.1 时钟和复位产生模块、存储器与封装形式 ........................................................... 46
6.2.2 丰富的 IO 接口 ........................................................................................................ 46
6.2.3 内部结构简图、引脚图及引脚功能 ....................................................................... 46
6.2.4 DG128 最小系统 ....................................................................................................... 47
6.3 智能车常用的功能模块 ..................................................................................................49
6.3.1 GPIO 模块 ................................................................................................................. 49
1. GPIO 概述 ..................................................................................................................49
2. I/O 口的使用方法 ......................................................................................................49
1)数据方向寄存器(Data Direction Register x,DDRx) .........................................49
2)数据寄存器(Port x I/O Register,PORTx) ..........................................................49
3)上拉电阻控制寄存器...........................................................................................50
3.样例程序......................................................................................................................50
1) 小灯控制头文件 Light.h .......................................................................................50
2) 小灯控制子函数 Light.c .......................................................................................50
3) 小灯控制主函数 main.c ........................................................................................50
6.3.2 串口模块................................................................................................................... 51
1. 串口模块概述............................................................................................................51
1)SCI 初始化 ...........................................................................................................52
2)发送一个数据与接收一个数据 ...........................................................................53
2. 样例程序....................................................................................................................54
1) 串行通信头文件 SCI.h .........................................................................................54
2) 串行通信子函数 SCI.c .........................................................................................54
3) 串口测试(查询方式)主函数 main.c .....................................................................56

III
6.3.3 A/D 转换模块 ............................................................................................................ 56
1. A/D 模块概述 .............................................................................................................56
2. DG128 内部 A/D 转换模块 .......................................................................................57
3. A/D 转换模块的基本编程方法 .................................................................................57
1) A/D 转换初始化.....................................................................................................57
2) 启动 A/D 转换 ......................................................................................................58
3)获取 A/D 转换结果 ..............................................................................................58
4. 样例程序....................................................................................................................58
1) A/D 转换头文件 ADC.h ........................................................................................58
2) A/D 转换子函数 ADC.c ........................................................................................59
3) A/D 转换测试主函数 main.c .................................................................................60
6.3.4 定时器模块............................................................................................................... 61
1. 概述............................................................................................................................61
2. DG128 定时器特点 ....................................................................................................61
2. 样例程序....................................................................................................................62
1) 定时器溢出中断头文件 Timer.h ..........................................................................62
2) 定时器溢出子函数文件 Timer.c ..........................................................................62
3) 定时器溢出中断测试主函数 main.c ....................................................................63
4) 定时器溢出中断处理程序 ...................................................................................64
6.3.5 输入捕捉功能........................................................................................................... 64
1. 输入捕捉概述............................................................................................................64
2. 样例程序....................................................................................................................65
1) 输入捕捉头文件 InputCapture.h ..........................................................................65
2) 输入捕捉子函数 InputCapture.c...........................................................................65
3) 输入捕捉中断处理函数 isr.c ................................................................................66
6.3.6 脉冲累加功能........................................................................................................... 66
1. 脉冲累加概述............................................................................................................66
2. 样例程序....................................................................................................................66
1) 脉冲累加头文件 PA.h...........................................................................................66
2) 脉冲累加子函数 PA.c ...........................................................................................67
3) 脉冲累加测试主函数 main.c ................................................................................67
6.3.7 PWM 功能 ................................................................................................................. 68
1. PWM 概述 ..................................................................................................................68
2. 样例程序....................................................................................................................68
1) PWM 头文件 PWM.h ............................................................................................68
2) PWM 子函数 PWM.c ............................................................................................69
3) PWM 测试主函数 main.c ......................................................................................71

第七章 软件设计的常用算法 ..................................................................................................72

7.1 黑线提取算法 ..................................................................................................................72


7.1.1 二值化算法............................................................................................................... 72
7.1.2 直接边缘检测算法................................................................................................... 73
7.1.3 跟踪边缘算法........................................................................................................... 73

IV
7.2 车体控制算法 ..................................................................................................................74
7.2.1 PID 算法 .................................................................................................................... 74
7.2.2 模糊控制算法........................................................................................................... 74

第八章 赛车设计样例 ..............................................................................................................77

8.1 硬件组装 ..........................................................................................................................77


8.1.1 车模各部件的安装................................................................................................... 78
8.1.2 电路板的设计及安装............................................................................................... 78
8.2 软件设计 ..........................................................................................................................78
8.2.1 软件流程介绍........................................................................................................... 78
1. 主程序........................................................................................................................78
2. 中断处理程序............................................................................................................79
8.2.2 软件复用模块........................................................................................................... 80

第九章 调试及常见问题分析 ..................................................................................................82

9.1 光电组赛车调试及常见问题分析 ..................................................................................82


9.1.1. 传感器...................................................................................................................... 82
9.1.2. 舵机.......................................................................................................................... 82
9.1.3. 主板.......................................................................................................................... 83
9.1.4. 电机部分(后桥).................................................................................................. 83
9.1.5. 码盘(测速装置).................................................................................................. 84
9.2 摄像头组赛车调试及常见问题分析 ..............................................................................84
9.2.1 上位机程序的制作................................................................................................... 84
1.通信模块...................................................................................................................84
2.数据显示...................................................................................................................85
1)显示赛车状态信息...............................................................................................85
2)显示 CCD 赛道图像 ............................................................................................86
9.2.2 通信问题................................................................................................................... 86
9.2.3 摄像头调节............................................................................................................... 87
9.2.4 常见问题分析........................................................................................................... 88
9.3 其它常见问题 ..................................................................................................................88

V
第一章 概述

大学生智能汽车竞赛是以智能汽车为竞赛平台的创意性科技竞赛, 是面向大学生的一种具
有探索性的工程实践活动,具有技术含量高,涉及学科多,趣味性强,参赛成本低等特点。
参赛选手须使用统一指定的竞赛车模套件,采用飞思卡尔半导体公司的8位、16位微控制
器作为核心控制单元,自主构思控制方案进行系统设计,设计内容包括传感器信号采集处理、
电机驱动、转向舵机控制以及控制算法等。在此基础上,完成智能车的制作及调试,并于指定
日期与地点参加比赛。
大学生智能汽车竞赛的比赛方式是,各队选手将设计好的智能汽车在规定宽度的白色跑道
上沿着中间黑色线行进,以完成时间最短者为优胜。主要的比赛规定有:
 智能竞赛车模的规定
比赛须采用统一指定的车模,细节及改动须受到一定的限制。如禁止改动舵机、驱动
电机以及电池、车底盘结构、轮距、轮径及轮胎,禁止采用其它型号的驱动电机等。
 有关赛场的规定
(1)赛道路面用专用白色基板制作,跑道所占面积一般不大于 5000mm* 7000mm,跑
道宽度不小于 600mm。
(2)跑道表面为白色,中心有连续黑线作为引导线,黑线宽 25mm;
(3)跑道最小曲率半径不小于 500mm;
(4)跑道可以交叉,交叉角为 90°;
(5)赛道不一定封闭;
(6)赛道有一个长为 1000mm 的出发区,如图 1-1 所示,计时起始点两边分别有一个
长度 100mm 黑色计时起始线,赛车前端通过起始线作为比赛计时开始或者与结束时刻。

图1-1 赛道基本参数

1
大学生智能汽车涵盖了控制、模式识别、传感技术、电子、电气、计算机、机械等多个学
科的知识,具有很强的综合性和实践性。
该项比赛的参赛对象来自不同专业,需要相互团结协作共同完成以下工作:
(1)根据汽车理论知识,调整前轮及其主销的倾角,包括主销内倾、主销后倾、前轮外
倾和前轮前束,以保障汽车直线行驶的稳定性、转向轻便和减少轮胎的磨损。
(2)使用舵机控制前轮的转向。舵机安装的方向和位置直接影响着舵机操作的灵活性。
(3)采集黑色引导线信号。根据所参加的竞赛组别的不同,引导线信号可以是光电信号、
摄像信号或电磁信号。若选择摄像头作为采集路线的传感器,软件算法更复杂,需要利用模式
识别技术,但是竞赛观赏性更好。
(4)算法设计。每队选手都须采用飞思卡尔的 8 位或 16 位微控制器作为核心控制芯片,
一般只需使用其中的 ADC、定时器、串口、PWM 以及 GPIO 等模块,利用 PID 控制理论编写
控制算法,保证小车能灵活流畅地运行。
(5)电机驱动设计。驱动信号来自核心控制芯片,需设计专门的驱动电路,提升电流和
电压,保证足够的功率驱动电机,且使电机快速运转,以便获得好的竞赛成绩。
本竞赛融科学性、趣味性和观赏性为一体,以迅猛发展、前景广阔的汽车电子为背景。竞
赛规则透明,评价标准客观,坚持公开、公平、公正的原则,以保证竞赛向健康、普及、持续
的方向发展。
总之,对多数参赛者来说,通过竞赛,培养了他们对已学理论知识和实验技能的综合运用
能力。他们带着背景对象中的各种新问题,学习多个学科新知识,并向来自不同学科背景的同
学学习,逐渐学会了在交叉、 集成基础上的综合运用。 他们在竞赛中还必须考虑赛车的可靠性、
寿命、外观工业设计、性能价格比等,即须从系统工程角度出发,结合技术与非技术、集成科
学与非科学,使其在具体约束条件下融合形成整体的综合运用。应该说,这样的训练是很有意
义的。同时,通过竞赛实践,逐渐培养大学生在一个团队中,学会正确地评价自己及评价他人;
学习和发挥他人的长处;建立组织和调动各类人员积极性的能力。使他们既能当好主角,也甘
于当好配角,初步具备脚踏实地做好本职工作的基本素质。

2
第二章 工具与材料

2.1 工具
2.1.1 测量类工具
1. 游标卡尺

图2-1 游标卡尺

用途:测量工件厚度或内外直径的用具,精密度可至 0.01 毫米(如图 2-1 所示)



注意:
(1)游标卡尺是比较精密的测量工具,要轻拿轻放,不得碰撞或跌落地上,使用时不要用
来测量粗糙的物体,以免损坏量爪,不用时应置于干燥地方防止锈蚀;
(2)测量时,应先拧松紧固螺钉,移动游标不能用力过猛,两量爪与待测物的接触不宜过
紧,不能使被夹紧的物体在量爪内挪动;
(3)读数时,视线应与尺面垂直,如需固定读数,可用紧固螺钉将游标固定在尺身上,防
止滑动;
(4)实际测量时,对同一长度应多测几次,取其平均值来消除偶然误差。
举例:测量螺钉外径。

2. 卷尺

图2-2 卷尺

3
用途:测量较长工件的尺寸或距离(如图 2-2 所示)。
举例:测量跑道总长。

3. 直角尺

图2-3 直角尺

用途:具有一个直角和两个直边,用于画或检验直角的工具(如图 2-3 所示)。


举例:测量跑道临边是否垂直。

4. 丁字尺

图2-4 十字尺
用途:为一端有横档的“丁”字形直尺,由互相垂直的尺头和尺身构成,用于画某物体外
廓边界的垂线(如图 2-4 所示)。
举例:测绘 KT 板(跑道材料) 。

2.1.2 五金类工具
1. 虎钳
用途:利用螺旋传动使两钳口作相对移动而夹持工件的工具(如图 2-5 所示)。
注意:用虎钳固定工件进行加工时,加工工具不可接触虎钳钳口,以免损坏。
举例:加工铝材或木材等型材时用于固定被加工物。

4
图2-5 虎钳

2. 尖嘴钳

图2-6 尖嘴钳
用途:能在较狭小的工作空间操作,刃口能剪切细小零件,为仪表及电讯器材等装配及修
理工作常用的工具(如图 2-6 所示)

举例:在狭小的工作空间中,拆装螺母。

3. 偏口钳

图2-7 偏口钳
用途:将元件过长的引脚剪掉,使元件引脚稍露出焊点即可(如图 2-7 所示)。
举例:去除元件多余引脚。

5
4. 剥线钳
用途:用来剥掉细缆导线外部的绝缘层(如图 2-8 所示)。
举例:焊接导线时剥掉外层绝缘层。

图2-8 剥线钳

5. 美工刀
用途:一种抽拉式结构的刀,大多由塑刀柄和刀片两部分组成。刀片多为斜口,用顿时可
顺片身的划线折断,出现新的刀锋(如图 2-9 所示)。
举例:切割 KT 板(跑道材料)

图2-9 美工刀

6. 剪刀

图2-10 剪刀
用途:用于切割布、纸、薄板、绳片状或条状物体的双刃工具(如图 2-10 所示)

6
举例:剪断细电线或纸板。

7. 锉刀、砂纸

图2-11 锉刀
用途:表面上有许多细密刀齿、条形,用于锉光工件的手工工具,用于对金属、木料等表
层做微量加工(如图 2-11 所示)。
举例:对被锯开的工件断口进行精加工。

8. 螺丝刀

图2-12 螺丝刀
用途:用来拧转螺丝钉以迫使其就位的工具,通常有一个薄楔形头,可插入螺丝钉头的槽
缝或凹口内。主要有一字(负号)和十字(正号)两种(如图 2-12 所示)。
举例:组装或拆卸车模螺钉。

9. 扳手

图2-13 扳手

7
用途:利用杠杆原理拧转螺栓、螺钉、螺母等的手工工具(如图 2-13 所示)。
举例:组装或拆卸车模螺母,一般和螺丝刀配合使用。

10. 镊子

图2-14 镊子

用途:用于贴片电子元件或螺钉取用(如图 2-14 所示)。


注意:(1)不可使其加热 (2)不可夹酸性药品 (3)用完后必须使其保持清洁。
举例:焊接时用于夹持贴片元件

11. 手动钢锯

图2-15 手动钢锯
用途:用于精度不高、较硬材料的切割(如图 2-15 所示)。
举例:切割铝材或木材等型材。

12. 锤子

图2-16 橡皮锤
用途:锤头用橡胶制作,用于敲击强度较低的零件,防止其变形或断裂(如图 2-16 所示)。

8
举例:折弯铝条

13. 吸锡器

图2-17 吸锡器
用途:用于拆卸修理已焊好的电路元件或清理焊锡,一般配合电烙铁使用(如图 2-17 所
示)。
举例:清理焊盘。

2.1.3 设备类工具
1. 电烙铁

图2-18 电烙铁
用途:用来焊接电路,一般配合“焊锡丝”使用(如图 2-18 所示)。
注意:
(1)使用时注意安全,防止烫伤或烫坏电源线绝缘层。
(2)焊接时应一次焊好,防止长时间焊接使电路受热变形。
(3)使用后应及时断电,消除火灾隐患。
举例:焊接电路。

2. 热风箱

图2-19 热风箱
用途:用于热风加热、
拆焊大面积焊接的电子元件和热缩管处理等多种需要热能的场合(如

9
图 2-19 所示)。
注意:(1)在热风焊枪内部,装有过热自动保护开关,枪嘴过热保护开关动作,机器停止
工作。必须把风量钮(ATPCAPACITY)调至最大,延迟 2 分钟左右,加热器才能工作,机器
恢复正常。(2)使用后,要注意冷却机身:关电后,发热管会自动喷出冷风,当停止吹风时再
拔掉电源插头。(3)不使用时,请把手柄放在支架上,以防意外。
举例:拆卸芯片。

3. 手钻

图2-20 手钻
用途:加工少量精度要求不高的较小直径孔(如图 2-20 所示)。
注意:
(1)钻头必须用卡盘钥匙锁紧,以防钻头松脱飞出;
(2)被加工工件应固定。
举例:车模底盘打孔。

2.1.4 仪器仪表类工具
1. 万用表

图2-21 万用表

用途:测量直流电流、直流电压、交流电压、电阻和音频电平等,有的还可以测交流电流、
电容量、电感量及半导体的一些参数(如图 2-21 所示)。

10
1) 电压的测量
直流电压的测量,如电阻两端电压、单片机某一管脚输出电压等。首先将黑表笔插进万用
表的“COM”孔,红表笔插进“VΩ”孔。然后把旋钮旋到比估计值大的量程,把表笔接电
源或电池两端;保持接触稳定。最后读取显示屏数值。
注意:
(1)表盘上的数值均为最大量程。
(2)“V-”表示直流电压档,“V~”表示交流电压档,“A”是电流档。
(3)若显示屏上显示为“1”,则表明量程太小,那么就要加大量程后再测量。
(4)若读取的数值左边出现“-”,则表明表笔极性与实际电源极性相反,即此时红表笔
接在负极上,黑表笔接在正极上。
2) 电阻的测量
将表笔插进“COM”和“VΩ”孔中,把旋钮打旋到“Ω”中所需的量程,将红、黑表
笔分别接在电阻两端金属部位,测量中可以用手接触电阻,但不要把手同时接触电阻两端,这
样会影响测量精确度的(人体也是导体,存在有限阻值)。读数时,要保持表笔和电阻有良好
的接触;
注意:单位:在“200”档时单位是“Ω”,在“2K”到“200K”档时单位为 “KΩ ”,
“2M”以上的单位是“MΩ” 。
3) 二极管的测量
数字万用表可以测量发光二极管,整流二极管„„测量时,表笔位置与电压测量一样,将
旋钮旋到“ ”档;用红表笔接二极管的正极,黑表笔接负极,这时会显示二极管的正向压降。
调换表笔,显示屏显示“1.”则为正常,因为二极管的反向电阻很大,否则此管已被击穿。
4) 三极管的测量
(1) 基极判断
表笔插位同上,其原理同二极管。先假定 A 脚为基极,用黑表笔与该脚相接,红表笔与
其他两脚分别接触其他两脚;若两次读数均为 0.7V 左右,然后再用红笔接 A 脚,黑笔接触其
他两脚,若均显示"1",则 A 脚为基极,否则需要重新测量,且此管为 PNP 管。
(2) 集电极和发射极的判断
数字表不能像指针表那样利用指针摆幅来判断,那怎么办呢?可以利用“hFE”档来判断:
先将档位打到“hFE”档,可以看到档位旁有一排小插孔,分为 PNP 和 NPN 管的测量。前面
已经判断出管型,将基极插入对应管型“b”孔,其余两脚分别插入“c” ,“e”孔,此时可以
读取数值,即β值;再固定基极,其余两脚对调;比较两次读数,读数较大的管脚位置与表面
“c”,“e”相对应。
注意:上法只能直接对如 9000 系列的小型管测量,若要测量大管,可以采用接线法,即
用小导线将三个管脚引出。
5) 其他档位
如交流电压的测量,电流的测量在智能车的制作过程中一般不会使用。

2. 示波器
用途:可以观察各种不同信号幅度随时间变化的波形曲线,还可以用它测试各种不同的电
量,如电压、电流、频率、相位差、调幅度等等(如图 2-22 所示)。

11
图2-22 示波器
在制作智能车时,在示波器的使用上,主要是用来看各种信号的波形,像接收管在黑白跑
道上接收的波形、CCD 摄像头输出的 PAL 制式波形、单片机输出的控制舵机和电机的 PWM
波形等等。
数字示波器因具有波形触发、存储、显示、测量、波形数据分析处理等独特优点,其使用
日益普及。由于数字示波器与模拟示波器之间存在较大的性能差异,如果使用不当,会产生较
大的测量误差,从而影响测试任务。
1) 区分模拟带宽和数字实时带宽
带宽是示波器最重要的指标之一。模拟示波器的带宽是一个固定的值,而数字示波器的带
宽有模拟带宽和数字实时带宽两种。 数字示波器对重复信号采用顺序采样或随机采样技术所能
达到的最高带宽为示波器的数字实时带宽,数字实时带宽与最高数字化频率和波形重建技术因
子 K 相关(数字实时带宽=最高数字化速率/K)
,一般并不作为一项指标直接给出。从两种带
宽的定义可以看出,模拟带宽只适合重复周期信号的测量,而数字实时带宽则同时适合重复信
号和单次信号的测量。
2) 有关采样速率
采样速率也称为数字化速率,是指单位时间内,对模拟输入信号的采样次数,常以 MS/s
表示。采样速率是数字示波器的一项重要指标。
(1) 避免采样时出现混迭现象
混迭就是屏幕上显示的波形频率低于信号的实际频率,或者即使示波器上的触发指示灯已
经亮了,而显示的波形仍不稳定。
混叠现象的判断。对于一个未知频率的波形,可以通过慢慢改变扫速 t/div 到较快的时基
档,如果波形的频率参数急剧改变,说明波形混迭已经发生;或者晃动的波形在某个较快的时
基档稳定下来,也说明波形混迭已经发生。根据奈奎斯特定理,采样速率至少高于信号高频成
分的 2 倍才不会发生混迭,如一个 500MHz 的信号,至少需要 1GS/s 的采样速率。有如下几
种方法可以简单地防止混迭发生:
a) 调整扫速。
b) 采用自动设置(Autoset) 。
c) 试着将收集方式切换到包络方式或峰值检测方式。
因为包络方式是在多个收集记录中寻找极值,而峰值检测方式则是在单个收集记录中寻找
最大最小值,这两种方法都能检测到较快的信号变化。
d) 如果示波器有 Insta Vu 采集方式,可以选用该种方式,因为这种方式采集波形速度快,

12
显示的波形类似于用模拟示波器显示的波形。
(2) 采样速率与 t/div 的关系
每台数字示波器的最大采样速率是一个定值。但是,在任意一个扫描时间 t/div,采样速
率 fs 由下式给出: fs=N/(t/div),N 为采样点个数。当采样点数 N 为一定值时,fs 与 t/div 成
反比,扫速越大,采样速率越低。
注意:使用数字示波器时,为了避免混迭,扫速档最好置于扫速较快的位置。如果想要捕
捉到瞬息即逝的毛刺,扫速档则最好置于主扫速较慢的位置。

2.2 材料
2.2.1 零件
1. 螺钉、螺母

图2-23 螺丝与螺母
常用的螺钉螺母以 Mx*x 形式统一规格,其中 M 表示最常用的粗牙螺纹,第一个数字表
示螺纹中径长度,第二个数字表示螺钉或螺母的高度,单位都是公制 mm 毫米(如图 2-23 所
示)。其中螺母作为标准件通常高度是固定的,若想改变高度,需要定制。
常用的螺钉规格包括:M2*8,M2*15,M3*5,M3*10,M3*18,螺母为 M2,M3,M4。
还有一种叫做紧固螺母的特殊零件,在螺母的一端镶入了胶套,可以使得螺钉拧入螺母后不会
相对转动,防松。

2. 轴承

图2-24 轴承与铜柱
常用的轴承类型为普通球轴承(如图 2-24 左所示),可以承受相当大的径向力,和一定程
度的轴向力,规格标准为 x*x*x。其中第一个数字为轴承内径,然后是外径,最后的数字表示
高度。
实际使用时会根据轴的强度、功能决定尺寸,然后选择合适的轴承,由于轴承是标准件,
三个参数会配套出现,如果对其中的某个参数有要求,需要定制。常用的有 3*5*3,4*8*4,

13
6*10*3 等。
另外,市场中还有一种带定位面的轴承,外观上加入了一个类似轴肩的设计,参数上也加
了对应的直径标准。

3. 铜柱、塑料柱
用途:用于固定主控板,及起到支架作用(如图 2-24 中、右所示)

2.2.2 跑道材料
1. KT板
用途:跑道的白色底板。

2. 黑胶带
用途:跑道的黑色线条。

2.2.3 加工材料
1. 铝材
铝合金材料是手工制作车架的首选材料,主要考虑了它的强度,密度,易加工的特性。实
际使用的铝材包括 L 型,□型,⊥型,匚型,及板材,可以根据使用情况自主选择。

2. 不锈钢材
对于设计成型的零件,通常会选择由专业的加工厂制作,此时除了铝合金外,还可以选择
更便宜的不锈钢作为加工材料。
需要注意的是在设计时应该考虑到钢材的密度会比较大,所以可以将设计图中对强度和功
能影响不大的部分做简化或是削减。

3. 碳纤维
碳纤维是现在新选用的材料,具有质量轻,强度高的特点,但是成型不容易,价格比较高,
并不常用,需要使用时,可以考虑买市场上现有的型材或是订做。

2.2.4 其他
表 2-1 元件列表
名称 用途
焊接元件。焊接时应该使用 63%-37%铅含量的焊料,较粗的锡线对
焊锡
焊铁头有较好的保护。
有助于焊锡的焊接。助焊剂一般分为无机助焊剂、有机助焊剂和树
助焊剂
脂助焊剂。树脂系列的助焊剂以松香焊剂使用。
502 胶、热熔胶 固定器件
绝缘胶带 导线连接时使用
小电视机 调试摄像头使用
机油 轮轴润滑
排线 连接多个接口
扎丝 固定器件

14
电阻 限流
电容 滤波
电压转换芯片 电压转换
接线端子 连接导线时使用
跳线帽 短接两个接口
拨码开关 设置运行参数
数码管 显示数字
蜂鸣器 声音提示
摄像头 数字摄像头或模拟摄像头
光电管 红外发射管和红外接收管
电磁传感器 用于捕捉交变电流产生的磁场

15
第三章 模型车的组成及安装调整方法

3.1 模型车组成
智能车组委会提供的车模见图 3-1 所示。车模主体包括底盘,前轮伺服舵机,后轮驱动电
机三个部分,另外底盘上有很多固定孔,可以方便各部件固定。

驱动电机

伺服舵机

车模底盘

图3-1 车模总体图
伺服舵机负责驱动前轮转向,驱动方式为 PWM,特定频率和占空比的 PWM 信号将使伺
服舵机旋转到特定的角度,从而使前轮转到特定的角度。
驱动电机负责驱动后轮旋转,产生使车模前进的动力。电机可以正反转,使车辆前进或倒
退。驱动电机使用专用的驱动芯片 MC33886,控制信号为 PWM,通过调整 PWM 的占空比实
现对电机的调速。
为了获取赛道的黑线信息,必须有赛道检测传感器。通常的检测传感器有红外传感器和摄
像头。
红外传感器由发射管和接收管组成。发射管发射红外光照射跑道,跑道表面与中心黑线有
不同的反射强度,利用接收管来检测这些信息。通过合理安排红外发射接收管的空间位置可以
检测到模型车前方道路相对于车模的位置。
摄像头则是直接拍摄赛道图像,利用算法从图像中提取赛道信息。
两种方式各有优缺点,红外方式电路和算法比较简单,但由于前瞻小。摄像头方式电路和
算法均比较复杂,但右路赛道信息丰富,处理方式可以灵活多变,因此,小车的速度也远比红
外方式快。
另外,为了能实时得到当前车的速度,从而进行闭环控制,必须要有速度传感器。常用的
速度传感器有光电码盘和编码器。速度传感器通常直接测量后轮的转速。编码器齿轮旋转时,

16
其信号线输出脉冲,旋转一周输出固定数目的脉冲,测试一定时间内编码器的脉冲数目就能获
得当前小车的速度。

3.2 模型车的安装
3.2.1 转向机构的安装
1. 改变舵机安装方式

图3-2 原车模的舵机安装
原车模的舵机安装是横直势的(如图 3-2 所示)
,舵机转向点不在车的正中间,导致车的
两个转向连杆长短不一致,在控制模型车左右车轮转过相同角度时,单片机输出 PWM 波的占空
比相对舵机中值(保持模型车直线行驶时单片机输出 PWM 波的占空比)不对称,所以给模型车
转向控制带来一定的困难;而且原装模型车舵机输出轴与转向拉杆的铰支点间距离较短,使得
转向轮转向力大,但响应速度缓慢,试验证明,模型车转向是不需要很大的转向力矩,但当车
速较高时,舵机的响应速度就不能满足控制要求,因此需加长舵机输出轴与转向连杆铰支点的
距离。

图3-3 改变舵机安装方式一
安装时,首先应设计一套支架使舵机安装在车的纵向轴线上,安装方式用两种,一是可将
舵机纵向立置(如图 3-3 所示)
,这种安装方式简便、稳定,且能利用上模型车原有地盘上的
安装孔,但这种安装方式提高了模型车的中心位置;另一种安装方案是将舵机躺下放置(如图
3-4 所示),舵机输出轴向下,这样相对前者可降低中心位置,但安装较为困难。如果舵机安
装在车纵向轴线上,左右转向轮连杆的长度要保持相同,这样单片机输出 PWM 波的占空比相对
舵机中值对称。

17
图3-4 改变舵机安装方式二
在设计舵机输出轴与连杆间的加长臂时,应注意加长臂的尺寸,过长会减小转向力,放大
转向连杆铰接点的间隙,导致转向轮晃动,过短会使转向响应速度变慢。经过尝试,选择加长
臂的长度在 30mm 左右比较合适。
最终的转向机构应尽量满足内外转向轮的法向延长线与后轴的延长线交于一点,或至少满
足内侧转向轮的转角略大于外侧撞向轮的转角(如图 3-5 所示)
,这样可以使模型车在过弯时
转向轮处于纯滚动状态,减少过弯时的阻力,减小轮胎的磨损。

图3-5

2. 改变车轮定位
此套车模在车轮定位方面可以改动的地方有:主销前后倾角、主销内外倾角。

图3-6
主销前后倾角可以通过改变悬挂上前后黄色小垫片的数量(原车前后各有两个黄色小垫片,
主销处于垂直状态),当模型车需过坡道,或在比较颠簸的路面行驶时,主销宜有一定后倾角,
但后倾角不能过大,否则会产生过大的回正力矩,导致模型车在出弯进入直道时发生左右摆动。
主销内外倾角可通过旋转悬挂上导向臂螺杆,改变上导向臂螺杆长度,在不同的赛道调试
时,主销内外倾角会有不同的设置,在急弯较多的赛道上行驶时,宜使主销有一定的内倾角,
提高过弯时的稳定性,但倾角不宜过大。

18
图3-7
主销的倾角设置应在调试赛车时不断调整,不同的赛道和不同的程序会有不一样的倾角设
置,具体的角度设置应视调车时车辆的行驶情况而定。

3. 悬架
模型车悬架上原装的弹簧属于刚度较大的弹簧(如图 3-8 所示),适用于较高车速,在高
速过弯时可以减小车身的侧倾,提高稳定性。但模型车的悬挂上没有阻尼,在高速通过急转弯
时,前轮会出现较大的跳动,大大降低车速和行驶稳定性,当出现这种情况时,应选用刚度较
小的弹簧。

图3-8
模型车悬挂的下方可以加装垫片,用来降低底盘高度,在没有坡道或比较平顺的路面行驶
时,应降低底盘高度,来降低整车重心高度,这样有利于模型车在高速行驶时的稳定性。当加
装垫片后,会使底盘与悬挂连接的螺钉容易松动,应改用较长的螺钉,同时改用螺栓连接或用
胶粘来防止螺钉松动。当赛道上有坡道时,底盘就不能过于降低,过低的底盘会在模型车通过
坡道时,底盘与赛道发生碰撞,
所以底盘高度应调整到通过坡道时底盘不与赛道发生碰撞为宜。

图3-9
车轮是模型车与地面接触的唯一部件,所以车轮的安装也十分必要,由于规则的限定,只
能对轮胎性能做部分改动。可以将轮胎与轮毂用胶粘住,增加轮胎的侧偏刚度,提高车轮高速
过弯的能力,粘胎时要十分谨慎,不能让胶撒在轮胎表面上。粘胎用的胶可选用 502,由于 502
为腐蚀性胶水,长时间使用轮胎会产生裂纹。为提高轮胎与地面的附着力,可将轮胎中间的凸

19
起线剪掉,保持轮胎与地面接触面平整。
在跑车时要时刻保持轮胎清洁,必要时要用湿布擦洗,
保持轮胎潮湿,但不能有水,可以提高轮胎与地面的附着力。

3.2.2 差速器的安装

图3-10 差速器及调试
模型车的差速器(如图 3-10 所示)采用滚珠差速器,差速器由两个金属片夹持一个内镶
有滚珠的大齿轮构成,差速时滚珠滚动,滚珠两侧的线速度的相反,以此来完成差速。组装差
速器时,车轮的定位块(铜制定位块,上装有顶丝)应与车架间留有一定的间隙,使车轴能够
舒畅旋转,但间隙不能过大,两个金属片和差速齿轮间可加注差速油,拧紧车轮内的紧定螺钉
时应十分小心,紧定螺钉的预紧力十分总要,过紧会降低差速性能,不利于转向,过松会降低
直道加速性能,在调整时应满足以下三点:
捏住左右两侧后轮,无法转动差速齿轮;
捏住差速齿轮,转动一侧车轮,另一侧车轮能够顺畅地反向旋转;
后桥与车架间有微小间隙,当不与电机齿轮啮合时,可以轻松转动。为提高模型车的稳定
性,可以加长后轮轮距,更换模型车自带的选装加长件,但会增加一点差速器的负担。

3.2.3 码盘的安装
为使智能车速度闭环控制,需加装码盘来测量车速,码盘的选择有两种,一是选用现成的
码盘,这种方法可靠性高、安装简便,只需将码盘与差速齿轮或电机输出齿轮相啮合即可,但
这种码盘成本高,重量大。另外可以自制码盘,用光电对射管和光栅或霍尔传感器等都可以测
量车速。光电对射管可以在市场上买到,光栅可以自己制作,通过金属腐蚀或线切割制成能够
切断光路的即可,当然光栅的缝隙越密越好,但要能让光电对射管识别出缝隙。霍尔测速传感
器,可在车轮或差速齿轮上加装小磁铁,通过霍尔传感器测量车速。
另外还可以采用从动轮码盘技术测量车速,在模型车上安装一从动轮测量车速,由于从动
轮上没有驱动力,从动轮不会出现打滑现象,这样可以准确地测量出车速,但这种从动轮码盘
安装复杂,需设计悬挂机构使车轮时刻与路面接触,且这种速度信号不宜用于速度控制,由于
从动轮码盘不存在打滑现象,所以可以用于赛道记忆。

图3-11

20
3.2.4 传感器支架及赛道传感器的安装
红外传感器利用黑白地面对红外光的不同反射程度来识别赛道。通过合理的安排红外传感
器的空间位置,可以知道当前车身相对于赛道的位置。常见的排列方式有双排和单排,八字形
和一字形。
以最简单的单排一字形为例。当接收管受到红外光时,其输出电压为高(用 1 表示) ,没
有接收到反射光时,其输出电压为低(用 0 表示)。这里使用 8 个红外传感器。将 8 个传感器
的输出接到 MCU 的一个数据口上。某位数据为 1,表示黑线在某个传感器的下面。
摄像头的支架可选用碳纤维杆制作,重量轻刚度大,碳纤维杆的下端与底盘相连接的部分
要非常稳定,杆不宜过长,满足使用要求即可(使摄像头有足够的视野)。碳杆与摄像头连接
的部分要稳定可靠, 连接部件可以沿杆上下移动,且摄像头仰俯角度可以改变,这样方便调试,
在确定摄像头角度和位置后要通过紧定部件固定,防止摄像头角度在行驶颠簸时变动。整个机
构重量要轻便简单,尽量减轻碳杆上端的重量,降低重心,稳定的支架在车行驶时摆动小。碳
杆的位置应视具体车的情况而定,应选择在车的纵向轴线上,且尽量与车的底盘相连接,由于
后桥是浮动的,所以不宜与后桥相连接。
常用的摄像头安装方式见图 3-12。

图3-12 常用的摄像头安装方式
光电传感器支架的安装,应视传感器的个数和尺寸而定,在满足整车尺寸规则要求的情况
下,尽量增加前瞻。对于比较脆弱容易损坏的传感器应加装防护装置。若传感器支架架设在车
前部,应使传感器支架的重量尽量轻,可选用轻铝或碳纤维板作为制作支架的材料。对于行驶
速度较高的车,在车前方应加装保险杠,防止前轮高速撞击后导致舵机损坏。
整车传感器支架加装完成后,应使整车的重心尽量在车的纵向轴线中间偏后的位置上,保
持良好的操控稳定性。
常用的红外传感器的安装方式见图 3-13。

21
图3-13常用的红外传感器安装方式

3.2.5 速度传感器安装
以常用的速度传感器编码器为例,其输出是脉冲信号。利用 MC9S08DG128 的脉冲累加
器模块对脉冲计数,然后在一定时间间隔后读取脉冲累加器计数,就能获得小车当前的速度。
脉冲累加器可以设定脉冲到来时不产生终端,这样大大节省的 CPU 时间。
这里以常用的编码器为例。常见的编码器固定方式是使用齿轮传动,安装方式见图 3-14。

图3-14 编码器固定方式

3.2.6 电池的安装
电池模块在整个车模重量占很大比重,根据车模重心尽量低,重心保持在车身中心之后的
原则,因此将电池安装在车身中心靠后的部位。
在电池安装和使用时,除了应该正确的充足电后,还应该制作好接触良好的接头。

3.2.7 驱动电机
驱动电机型号 RS380(如图 3-15 所示),输出功率 0.9~40W。驱动芯片使用大赛组委会指

22
定的驱动芯片 MC33886(如图 3-16 所示)。

图3-15 驱动电机 图3-16 驱动芯片MC33886

调速使用 PWM 信号控制,PWM 占空比越大速度越快。

3.2.8 伺服电机
伺服电机主要靠脉冲来定位,基本上可以这样理解,伺服电机接收到 1 个脉冲,就会旋转
1 个脉冲对应的角度,从而实现位移,因为,伺服电机本身具备发出脉冲的功能,所以伺服电
机每旋转一个角度,都会发出对应数量的脉冲,这样,和伺服电机接受的脉冲形成了呼应,或
者叫闭环,如此一来,系统就会知道发了多少脉冲给伺服电机,同时又收了多少脉冲回来,这
样,就能够很精确的控制电机的转动,从而实现精确的定位。组委会提供的伺服电机型号为
S3010,使用 PWM 控制其转角,其性能参数见图 3-17。

图3-17 伺服舵机参数图

3.3 机械调整
3.3.1 前轮倾角调节
为了尽可能降低转向舵机负载,对前轮的安装角度,即前轮定位进行了调整。前轮定位的
作用是保障汽车直线行驶的稳定性,转向轻便和减少轮胎的磨损。前轮是转向轮,它的安装位
置由主销内倾、主销后倾、前轮外倾和前轮前束等 4 个因素决定,反映了转向轮、主销和前轴
等三者在车架上的位置关系。

23
主销内倾是由主销装在前轴略向内倾斜的角度,它的作用使前轮自动回正。角度越大前轮
自动回正的作用就越强烈,但转向时就越费力,轮胎磨损增大;反之,角度越小前轮自动回正
的作用就越弱。见图 3-18。

图3-18 主销内倾角示意图

主销后倾是指主销装在前轴,上端略向后倾斜的角度。它使用车辆转弯时产生的离心力所
形成的力矩方向与车轮偏转方向相反,迫使车轮偏转自动恢复到原来的中间位置上。由此,主
销后倾角越大,车速越高,前轮稳定性也越好。见图 3-19。

图3-19 主销后倾角示意图
主销内倾和主销后倾都有使转向自动回正,保持直线行驶的功能。不同之处是主销的回正
与车速无关,主销后倾的回正与车速有关,因此高速时后倾回正作用大,低速时内倾的回正作
用大。
前轮外倾角对汽车的转弯性能有直接影响,它的作用是提高前轮的转向安全和转向操纵的
轻便性。前轮外倾角俗称“外八字”,如果车轮垂直地面一旦满载就易产生变形,可能引起车轮
上部向内倾侧,导致车轮联接件损坏。所以事先将车轮校偏一个外八字角度,这个角度约为 1°
左右。所谓前束是指两轮之间的距离数值与前轮数值之差,也值前轮中心线与纵线向中心线的
夹角,其惯性力会自然将轮胎向内偏斜,如果前束适当,轮胎滚动时的偏斜方向就会抵消,轮

24
胎内外侧磨损的现象就会减少。调整前轮外倾角后示意图见图 3-20。

图3-20 调整后的前轮示意图

3.3.2 齿轮传动机构调节
车模后轮采用 RS-380SH-4045 电机驱动,由竞赛主办方提供。电机轴与后轮轴之间的传
动比为 9:38(电机轴齿轮齿数为 18,后轮轴传动轮齿数为 76) 。
齿轮传动机构对车模的驱动能力有很大的影响。齿轮传动部分安装位置的不恰当,会大大
增加电机驱动后轮的负载,从而影响到最终的成绩。调整的原则是:两传动齿轮轴保持平行,
齿轮间的配合间隙要合适,过松容易打坏齿轮,过紧又会增加传动阻力,白白浪费动力,传动
部分要轻松、顺畅,容易传动,不能有卡住或迟滞现象。判断齿轮传动是否调整好的一个依据
是,听一下电机带动后轮空转时的声音。声音刺耳响亮,说明齿轮间的配合间隙过大,传动中
有撞齿现象;声音闷而且有迟滞,则说明齿轮间的配合间隙过小,或者两齿轮轴不平行,电机
负载加大。调整好的齿轮传送噪音小,并且不会有碰撞类的杂音。

3.3.3 后轮差速机构调节
差速机构的作用是在车模转弯的时候,降低后轮与地面之间的滑动;并且还可以保证在轮
胎抱死的情况下不会损害到电机。当车辆在正常的过弯中(假设:无转向不足亦无转向过度),
此时 4 个轮子的转速(轮速)皆不相同,依次为:外侧前轮>外侧后轮>内侧前轮>内侧后轮。
此时所使用车模配备的是后轮差速器。差速器的特性是:阻力越大的一侧,驱动齿轮的转速越
低;而阻力越小的一侧,驱动齿轮的转速越高,以此次使用的后轮差速器为例,在过弯时,因
外侧前轮轮胎所遇的阻力较小,轮速便较高;而内侧前轮轮胎所遇的阻力较大,轮速便较低。
差速器的调整中要注意滚珠轮盘间的间隙,过松过紧都会使差速器性能降低,转弯时阻力
小的车轮会打滑,从而影响车模的过弯性能。好的差速器,在电机不转的情况下,右轮向前转
过的角度与左后轮转过的角度之间误差很小,不会有迟滞和过转向情况。
差速器的调整可以使用车模套件里的相应工具拧后轮的螺母,如图 3-21 所示。

25
图3-21 差速器调节方法示意图

3.3.4 底盘高度的调整
底盘适当降低,在可以过坡道的情况下,尽量降低底盘,从整体上降低车的重心,使车在转
弯时可以更加稳定、快速。此外,底盘降低后,前轮的转向能力得到提升,最小转弯半径减小,
在转弯时可以获得更大的灵活度。具体调整的方法可以在前论处加装垫片来实现,如 图3-22
所示。

图3-22 底盘高度调节示意图

26
第四章 循线原理与设计方案

4.1 循线原理
参赛队伍通过设计基于单片机的自主控制器控制模型车在跑道上自主循线运行。自主控制
器以单片机为核心,配合有传感器、电机、舵机、电池以及相应的驱动电路,它能够自主识别
路径,控制模型车高速稳定运行在跑道上。比赛跑道表面为白色,中间有连续黑线作为引导线,
黑线宽 25cm。比赛规则限定了赛道宽度和拐弯最小半径等。
检测赛道相对于车模的偏移量、方向、曲率等信息是实现车模自主沿着赛道运行的基础,
获取更多、更远、更精确的赛道信息是提高车模运行速度的关键。道路检测方法总体上分为两
大类:
 红外发射/接收管检测模式。通过红外发光管发射红外光照射跑道,跑道表面与中心线有
不同的反射强度,利用红外接收管来检测这些信息。通过合理安排红外发射接收管的空间
位置可以检测到模型车前方道路相对于车模的位置。
 CCD/CMOS 摄像头检测方式。比赛规定 CCD/CMOS 摄像头算作一个传感器。单片机采集道路
前面图像,通过软件处理获取道路的各种参数。由于赛道只有黑白两种颜色,采用黑白图
像传感器即可满足要求。

4.2 光电传感器方案
4.2.1. 寻线原理
所谓光电传感器寻迹方案,即路径识别电路由一系列发光管、接收二极管组成,由于赛道
中存在轨迹指示黑线,落在黑线区域内的光电二极管接收到的反射光线强度与白色的赛道不同,
由此判断行车的方向。光电传感器寻迹方案的优点是电路简单、信号处理速度快。
光电传感器的排列方法、个数、彼此之间的间隔都与控制方法密切相关,彼此之间可能会
有干扰。但一般的认识是,在不受到外部因素影响的前提下,能够感知前方的距离越远,行驶
速度越高。
由于光电传感器电路板不可能伸出车体太远,因此不少参赛队伍调整了光电传感器电路板
与地面的夹角,使光电传感器可以感知更远一点的赛道情况。

4.2.2. 光电传感器方案的特点
 优点:程序和算法相对简单。光电传感器寻迹的优点是电路简单、信号处理速度快。在不
受外部因素影响的前提下,光电管能够感知的前方距离越远,行驶效率越高,即智能车的
预瞄性能越强。
 缺点:前瞻有限,获取道路信息有限,速度相对摄像头车慢。硬件较为复杂,尤其是激光
传感器,很难调试。车的抗打击性较差,比较容易损伤。

4.2.3. 光电传感器分类
 LED 发射管

27
图 4-1 LED 红外传感器
技术要求最低,也是最原始的智能车采用的传感器。前瞻较近,所以很难提速。
根据发射光的频率又可分为可见光和红外光。其中可见光光电传感器易受外部光线干扰,
对环境的适应能力较差,所以推荐使用红外光光电传感器。
 激光发射管

图4-2 激光传感器
采用激光发射管可以得到较大的前瞻(试验 1m,实际使用 0.4m-0.8m),前瞻决定速度,
所以采用激光发射管的车相对于 LED 有着较大的优势,更容易提速。但是,激光管传感器也有
着造价较高,容易相互干扰,调试难度很大,容易烧坏等缺点。
 激光扫描引擎
激光扫描引擎就是超市收银台所用条码枪里的部件,是利用反射激光原理读取条形码。同
理利用此原理可以通过它来获得道路信息。具有前瞻大,广度大,重量轻等优点。此方案的开
发难度主要在于很难买到合适的激光扫描引擎。若能找到扫描频率高(100hz) ,不需要解码或
可解码,受震动影响较小激光扫描引擎用于智能车,可以说是目前最理想的光电车解决方案。
建议有一定技术基础的同学尝试。

4.3 摄像头方案
红外检测和摄像头检测各有优缺点。红外检测方法的电路设计相对简单,检测信息的速度
快,调试简单,成本低。但也存在缺点,如道路参数检测精度低,道路参数检测种类少,传感
器个数较多,检测前瞻距离较短,耗电量较大。摄像头检测方法检测前瞻距离打,检测范围宽,
检测道路参数多。但存在如下缺点,如电路设计复杂,需视频信号同步分离电路,而且软件的
计算量大,初期上手比较难。
采用摄像头方案主要是通过一个摄像头来检测赛道信息,将采集回来的图像信号经过图像
处理模块处理之后输入到单片机,通过特定的算法计算之后,单片机对舵机和电机发出相应的
控制信号。

4.3.1 选用摄像头的优势
1. 分辨率高
大家可以自己想象一下,如果采用光电管检测赛道,以最常用的一字形排布为例,相当于
同一时间内得到了赛道上水平方向一条线上的信息,而且由于组委会对光电管数目的限制,在

28
横向上的分辨率也不高;而摄像头则不然,它是以每秒 30 到 40 帧的速率(具体速率与摄像头
型号有关)扫描赛道上特定的一个范围,经过处理之后每帧图像的分辨率达到 210*85,这样,
就相当于使用了 85 排光电管,每排 210 个,这样获得的赛道信息将会非常丰富。因此,分辨
率高是摄像头技术的一大优势。 图 4-3、4-4、4-5 是将图像发到上位机上显示出来的几个图
片:

图4-3 S形弯道

图4-4普通弯道

图4-5十字交叉道

从上面可以看到,分辨率还是比较高的,
赛道信息越丰富就可以做越多的算法处理和控制。

2. 前瞻远
前瞻意思就是赛车能够看到的最远地方与赛车最前部的距离。在赛车行进过程中,前瞻距
离是很重要的。前瞻越远,遇到弯道时给系统的反应时间就越长。这就相当于自己开车,如果
你在很远的距离处就可以清楚地看到弯道的话,那么你的直道速度就可以加得很快,因为你有
充足的反应时间来减速和转向。
采用摄像头寻线技术的赛车前瞻可以达到 1.6 米左右,赛车前部的盲区大概在 10 厘米左
右。经过实际测量,赛车在直道上的速度可以达到 5m/s,平均速度稳定在 3.4m/s。而光电管
赛车前瞻大概在 70 厘米左右,平均速度最快达到 3m/s,差距还是比较大的。

29
3. 路径好
智能车比赛虽然是在赛道上有一条黑色的引导线,但赛车不必完全按照黑线行驶,只要不
出赛道就行。因此,在过弯时,路径规划比较好的赛车就可以切内道,某些 S 形弯道,赛车可
以做到直冲。摄像头赛车由于前瞻远、采集的赛道信息丰富,因此可以很容易得走出比较好的
路线。
摄像头赛车有这么多优势,但同时上手比较困难,因此,可以综合一下优缺点,选择自己
的方案,毕竟,要是摄像头赛车做好的话,基本上光电的车就很难超越了。

图4-6
大家如果看了比赛规则就会知道,智能车要循着黑线跑,而且在不违反规则的情况下跑的
越快越好。由于比赛前赛道图是不公布的,所以不能像机器人竞赛那样做到全场标定,赛车只
能根据自己的传感器检测到的车前方有限的赛道信息进行相关转向和速度的控制,所以传感器
反馈的前方赛道的信息的多少直接影响赛赛车的速度,可见传感器在智能车竞赛中起着举足轻
重的作用。
用摄像头做赛车的检测赛道传感器比光电传感器有着天然优势,这也是全国智能车竞赛组
委会把摄像头车和光电车分开比赛的原因。摄像头是图像传感器,它就像人的一只眼睛一样反
馈给单片机的信息是一幅图像,这幅图像可以把车前方 1.5 米左右以内的赛道信息真实的反映
出来,然后赛车根据这幅图像判断出黑线延伸的趋势进行相关控制,相比之下光电传感器的前
瞻距离要小很多,很难达到半米以上。所以在实际比赛时,摄像头赛车达到光电车很难达到的
效果是:
 S 弯的直冲效果。
 直道很快,入弯提前一米多就可以减速。
需要注意一点是:对于初学者,摄像头车因为要做很多的图像处理算法,所以编程上要比
光电车复杂。

4.3.2 摄像头信号原理
摄像头输出的信号是 PAL 制式模拟图像信号,原理跟电视机信号类似,一幅图像有 625
行,采一幅图像需要 40ms。图像又平均分成奇场和偶场,每场 312.5 行(奇场的最后一行和
偶场的第一行是半行信号) ,花时 20ms。其中奇场含第 1,3,5﹍﹍625 行信号,偶场含剩余
的行信号。摄像头采一幅图像是先进行感光,将 625 行图像信号用感光电荷储存下来,然后花
20ms 将奇场信号(第 1,3,5﹍﹍625 行信号)通过信号线输出,再花 20ms 输出偶场信号。
由此可见奇场信号和偶场信号表示的图像基本是相同的(但实际测试时奇偶场信号是有些区别
的,感兴趣可以自己测试) ,因此实际用的时候是将奇场和偶场作为两幅独立的图像单独处理
应用的。
摄像头输出的信号是行同步信号、场同步信号和具体的每一行图像信号的叠加,如图 4-7

30
所示。

图4-7
其中:
A, 行同步信号是指换行标志信号,表现为信号换一次行,图像信号中叠加一个拉低的脉冲信
号,该信号的周期为 40ms/625 = 64us。
B, 场同步信号是指换场标志信号,表现为每次换场图像中叠加的场同步信号要高低电平之间
变换一次,最终表现为奇场叠加高电平(或低电平) ,偶场相反,信号周期为 40ms。
C, 具体的每一行图像信号直接表示看到的实际图像中该位置的颜色深浅。黑线的图像信号比
白地板的要低。因此,A/D 转换后黑线的值要小或者二值化后黑线值为 0,白的位置为 1,
由此来将黑线位置提取出来。
需要先将前两种信号分离出来后分别提供给单片机。

图4-8

利用芯片 LM1881 将摄像头信号 VI 分离出场同步信号 O/E 和行同步信号 IRQ。其中场同步


信号可以直接接单片机普通 I/O 口, 用时只需读该 I/O 口的高低电平就可以知道摄像头当前输
出是奇场还是偶场。行同步信号需要接单片机的外部中断口 IRQ 脚,并将中断设置为下降沿触
发(或低电平触发) ,每次行同步信号到来都引发一次外部中断,便可知道当前黑白图像信号
是哪一行,并重新开始从左到右记录该行黑白图像信息。有了行同步信号和场同步信号相当于
确定了当前是第几幅图像的第几行,但该行的左右位置和每个位置的黑白信息却不清楚。这就
需要用到黑白图像信号。
由于赛道的黑白信号在摄像头输出信号中占绝大部分比例,因此叠加行同步信号和场同步
信号,对黑白信号经过二值化后的结果影响很小。所以直接将摄像头的输出信号经过 A/D 转换
(或比较器转换等)后提供给单片机作为每行提取赛道黑线时的参考信号。

4-3.3 摄像头信号程序采集原理
将信号提供给单片机后只有经过正确的采集程序,得到数字化的图像才算将图像采集了才

31
能进一步利用。
程序采集图像信息一般的方法是用一个二维数组记录一幅图像信息——即每一行每一个
点的高低状态。首先将行同步信号接口(IRQ 脚)设置为中断使能,这样每次行同步信号到来
时引发中断,进入中断函数,行变量等重新置数,并读取场同步信号的高低状态跟上一次行同
步中断时读取的场同步信号的高低状态进行比较,若发生变化则说明奇偶场变化,需要采集新
的一幅图像,就将行变量清零重新记录。

4.4.4 摄像头信号黑线提取程序原理
实际的赛道上除了黑线还有一些干扰点也是黑的,而且有时候由于反光黑线位置返回来的
的信号是偏高的,如果处理错了就很容易跑出去,所以就需要根据一些算法将真正的黑线提取
出来,将其他的干扰都滤除掉。
如图 4-9 所示,左边一幅图像是直接提取未经过处理的原始图像,右边一幅图像是经过算
法将干扰滤除后提取的黑线。很明显,不经过处理的图像用起来很容易出错。

图 4-9
下面是提取黑线的一些心得,希望有所帮助:
a) 将原始图像通过二维数组记录下来后,从最近出向远处逐行提取。因为进出图像清晰,
且干扰较少,准确率较高。
b) 提取完最近一行后,向远处提取时取前一行左右一定范围内的点。因为根据黑线的连
续性,相近两行的黑线位置不应相差太大。
c) 若一行内有两个以上的黑块满足条件,则寻找离上一行黑线中心最近的一个黑块作为
该行黑线中心。
d) 黑线宽度有一个范围,在确定的黑线宽度范围内才认为黑线有效,这样可以滤除不在
宽度范围内的黑点干扰。
e) 若已经知道一场图像的信息,则可以根据该场图像最近若干行的黑线中心位置确定下
一场最近一行黑线中心的搜索范围
f) 根据前一段线的倾斜度确定下一行黑线搜索范围。有时图像黑线比较倾斜,跟据线的
趋势可以很好确定搜索范围。
g) 有选择的选用某些行的信息提取黑线。每场有三百多行,实际不需要都用,可以隔几
行采一行
其实,采集到的每一行信息都相当于一排光电传感器采到的信息,利用任意一行图像信息
就可以像光电车那样跑。实验发现,用含有黑线信息的最远端一行进行控制赛车,也可以跑的
不错,但前提是该行信息要可靠准确!!

32
图4-10

实际上有这么多的信息,如果不充分利用确实可惜了,但这么丰富的一幅图像怎么来控制
车的转向和速度呢?
这里介绍一个简单实用的方法,想必进行图像程序采集时候每一行的黑线中心点位置都已
经用二维坐标确定了,这里只需要对这些黑线中心点进行处理就行了。一种常用方法就是对这
些点进行加权平均,远处的点权重大,近处的点权重小,这样既充分利用了所有行的信息也满
足了足够的前瞻。当然还有好多新颖的方法,还可以做一些图行整理,这里十分鼓励大家创新。

33
第五章 赛车常用电路

5.1 电源电路
常用器件需要+12V、+6V、+5V、+3.3V 三种电压。下面将分别对如何获得这几种电压进行
介绍。

5.1.1 +12V电压的获得
由于电池的额定电压为 7.2V,所以+12V 电压需要通过 DC-DC 变换升压获得,以下介绍一
种简单的实现方案:

图5-1开关稳压芯片34063
如图 5-1 所示该电路使用 34063 集成芯片设计,至少可提供 500mA 输出电流。

5.1.2 +6V电压的获得
+6V 电压可为舵机使用,如图 5-2 所示:

图5-2 LM7806

5.1.2 +5V电压的获得
+5V 电压可供传感器和处理器使用,如消耗电流较大,可使用开关稳压电路,以提高转换
效率,如图 5-3 所示:

34
图5-3开关稳压芯片LM2596-5

该电路使用 LM2596 集成芯片设计,可提供 3A 输出电流。


如该+5V 电压仅供处理器和其他数字芯片使用,则消耗电流较小,可使用线性稳压电路,
以简化设计,并可减少电源纹波,但是有一点要注意,一定要使用低压降的稳压芯片,如 2940
或 1117,如图 5-4 所示:

图5-4线性稳压芯片LM2940-5.0

5.1.3 +3V电压的获得
有部分传感器和芯片可能使用+3.3V 电压,如消耗电流较大,可使用开关稳压电路,以提
高转换效率,如图 5-3 所示,如消耗电流较小,可使用线性稳压电路,以简化设计,并可减少
电源纹波,如图 5-5 所示:

图5-5线性稳压芯片AS1085-3.3

5.2 编码器电路
编码器在系统中用于测量电机转速或记录智能车行驶里程,该部分电路主要由脉冲整形电
路。
脉冲整形电路可以使用 74HC14 芯片,该芯片是一个具有施密特触发器功能的反相器,利
用施密特触发器的工作特性实现脉冲整形,如图 5-6 所示:

35
图5-6 脉冲整形电路

5.3 通信部分电路
在通过 PC 机对智能车系统进行调试的过程中,智能车系统与 PC 机之间必须采用可靠的通
讯总线进行实时的数据交换,常用的通讯方式有串行通讯和并行通讯二种方式。由于串行通讯
方式具有使用线路少、成本低,特别是在远程传输时,避免了多条线路特性的不一致而被广泛
采用。在串行通讯时,要求通讯双方都采用一个标准接口,使不同的设备可以方便地连接起来
进行通讯。RS-232 接口是目前最常用的一种串行通讯接口。具有速度快,可靠性高的特点。
以下分别使用 MAX3232 和 SP3220E 芯片设计了 RS-232 串行通讯接口电路,如图 5-7 和图
5-8 所示:

图5-7 MAX3232应用电路

36
图5-8 SP3220E应用电路

5.4 电机驱动电路
该电机驱动板如图 5-9 所示:
由 CPU 发出 PWM 波通过 33886 驱动芯片控制电机的电压,PWM5 输出 PWM 波,经由 IN1 口
输入,OUT 输出电机调速信号。驱动芯片 MC33886 内部具有短路保护、欠压保护、过温保护等
功能。为了增大电流驱动能力,将四个半桥并联使用。

图5-9 33886驱动电路

37
第六章 开发环境与主控芯片特性

Freescale 公司使用 CPU12 内核的 MCU 主要有 HC12 和 HCS12 两种类型。1996 年,摩托
罗拉(Motorola)推出 HC12 系列 MCU,其种类较多,针对不同的场合都可以选到合适的型
号。到了 2002,年摩托罗拉开发出了 HC12 的升级产品系列 HCS12,性价比更高,是 CPU12
系列 MCU 的先进机种。其中智能小车所用的就是这其中的一款,MC9S12DG128(以下简称
DG128)。工作电压 5V,时钟频率最高可达 25MHz。

6.1 HCS12开发环境
嵌入式软件开发有别于桌面软件开发的一个显著的特点,是它一般需要一个交叉编译和调
试环境, 即编辑和编译软件在通常的 PC 机上进行,而编译好的软件需要下载到目标机上执行,
如 DG128 的目标机上。由于主机和目标机处理器体系结构的不同,因此增加了嵌入式软件开
发的难度。Codewarrior 是开发智能小车的平台。目前 Codewarrior 4.6 是 s12/s12x 系列单片机
的开发工具。在开始编写小车程序之前,需要安装 Codewarrior 4.6 开发环境。安装包来源途
径:光盘、官方网站下载。
安装流程非常简单,双击安装包,按照提示进行,选择安装路径。安装完之后重启电脑,
一切就 OK 了。

6.1.1 Codewarrior的使用
(1)创建新项目。打开 Codewarrior IDE 后,出现如图 6-1 的界面。

图6-1 CW环境运行界面
(2)在 File 菜单中选择 New。在弹出的新窗口中,选择 HC(S)12 New Project Wizard,
在 Project Name 框中,输入项目的名称。在 Location 框中,可以指定这个项目保存在哪个文
件夹中。界面如图 6-2 所示。

38
图6-2新建项目

(3) 选择“确定”按钮,出现如图 6-3 所示“处理器类型选择”对话框。在选择框中出


现了所有 12/s12x 系列单片机,由于智能小车用到的是 MC9S12DG128B 这款芯片,选中对应的
选项。点击“下一步” 。

图6-3处理器芯片类型选择
(4)选择“MC9S12DG128B”,点击“下一步”
,出现如图 6-4 所示的“编程语言选择”
界面。选择编写程序所使用的高级语言,有三种语言可供选择:汇编语言(Assembly)、C 语言
以及 C++语言。这三种语言各有优缺点,可以选择其中单独的一种作为开发语言,也可以选
择两种或者三种混合编程。譬如,选择 C 语言,点 next。

39
图6-4编程语言选择
(5)如图 6-5,选择是否采用“处理器专家”自动生成初始化代码,该项功能可以方便
程序的寄存器设置,如果不想开启该功能可以选择“No”;若选择“Yes”
,CodeWarrior 会在
初始化代码中队相关寄存器进行优化设置。 点击“Next”。

图6-5 是否自动生成处理器初始化代码
(6) 下面就是选择是否采用“PC-lint”,如图 6-6 选择“NO”
,点击“NEXT”

图6-6 新建工程

40
(7) 在图 6-7 中选择“ANSI start code”选项,当然也可以选择“minimal startup code”,
这样可以使得 startup 代码更加紧凑。点“Next”,到下一步。

图6-7 Startup代码选择
(8) 在图 6-8 中选择本工程是不是支持浮点数,如果你的工程中用到浮点数,选择“float
is IEEE32,double is IEEE32”、“float is IEEE32,double is IEEE64”中的任意一个。如果工程
中没有用到浮点数计算,选择“None” 。

图6-8 浮点数精度选择

(9) 图 6-9 存储器模式选择,选“Banked”。点 Next

41
图6-9 存储器模式选择
(10) 在图 6-10PC 机与目标板连接方式中选择,TBDML。在这一步一定要注意,要根
据自己写入器的类型,选择不同的连接方式。

图6-10 写入器类型选择

6.1.2 工程文件组织
一个嵌入式系统的工程中往往包含很多文件,如:程序文件、头文件、编译调试相关的信
息文件、工程说明文件及工程目标代码文件等。嵌入式系统的工程文件组织方法以硬件对象的
方式来展开,系统中的每一个对象应包含相关的头文件、程序文件及相关说明文件等。以硬件
对象的方式来组织文件,会使得工程结构清晰,方便调试定位,后期维护修改容易。
在嵌入式系统工程中的基本硬件对象是系统的核心――微处理器(MCU),MCU 的相关文
件是工程中最基本的。一个工程项目的开始往往是围绕 MCU 来展开的,首先要熟悉 MCU 的
寄存器、存储空间,并产生 MCU 的头文件,通常 MCU 的头文件在集成开发环境中自动生成
了,编程者主要是熟悉这些寄存器的相关定义,为后面编程时熟练使用基础;其次是正确设置
MCU 的相关寄存器,确定总线频率、与系统相关的基本模块;再次要正确设置 MCU 中断源;
最后要在开发环境中给出与 MCU 相关的编译参数。与 MCU 相关的程序文件通常有:映像寄
存器名定义头文件、芯片初始化文件、中断处理子程序文件、中断向量表文件、启动程序文件
等。
本节主要以 DG128 控制一盏小灯(发光二极管)的闪烁来介绍工程文件的组织。在这个简
单的样例程序中,包含了两个对象:主控 MCU DG128 和小灯。小灯是一个简单的硬件对象,

42
它的原理是当小灯的两个引脚上有足够高的正向压降时,小灯就会发光,所以如果让小灯的正
端引脚接 DG128 的普通 I/O 口,负端引脚过电阻接地后,在 DG128 的控制小灯的 I/O 引脚上
输出高或低电平,小灯就会亮或暗。小灯对象所对应的程序文件有:小灯驱动头文件和小灯驱
动了程序文件。图 6-11 给出了小灯闪烁程序工程文件组织情况。

图6-11 灯闪烁程序工程文件组织图

6.1.3 编译程序
(1)Build project
Build project 时,可以用以下几种方法:使用菜单 project==>make 命令;或者使用工具栏

中的 按钮;或者直接按“F7”,如果程序语法有错的话,系统会报错,修改错误继续
以下操作。
(2)Start debugger
Start debugger 时,可以使用以下三种方法:使用菜单 project—debug 命令;或者使用工

具栏按钮 ;或者直接按“F5”,出现如图 6-15 所示窗体,等待下载完成,单击


完成下载。

43
图6-12下载程序到小车

下面介绍在线调试时常用到的三个按钮

代表开始运行程序,单片机开始运行,在上面的窗口里面可一看见一些变量和常量
的值。

代表单步执行,功能是一行一行的执行程序代码,方便查看每句程序运行后变量的
状态。

代表停止运行(下载完了后注意先按此按钮再拔下下载线)。
下面介绍一些有用的功能 查看程序运行时的变量和常量的值,如图 6-13: 在 data1 或者
data2 的窗口空白处双击,出现对话框,输入你想查看的变量或常量名,比如“sensor_state”
就可以查看了。最后还有一步要做:在 data1 或者 data2 的窗口空白处右击,选择 mode——
periodical,在弹出的窗口中将 10 改成 1,这样就可以动态的观察变量的值了。

44
图6-13运行时查看变量的值

6.1.4 样例
图 6-14 是第一个 MC9S12DG128 样例程序的工程文件组织。

图6-14 第一个小灯程序工程文件组织
具体程序代码见附件 C01_Frame

6.2 DG128的特点
DG128 微控制器是飞思卡尔公司 HCS12 系列 16 位单片机中的一种,其内部结构主要有
MCU 的基本部分和 CAN 功能模块组成,主要性能概述如下:

45
6.2.1 时钟和复位产生模块、存储器与封装形式
时钟和复位产生模块 CRG(Clock and Reset Generator)包括:低电流振荡器或是标准振荡器
的选择、锁相环时钟频率放大器、看门狗、实时中断、时钟监控器。
存储器包括 128KB 的 FLASH EEPROM、8KB 的 RAM、2KB 的 EEPROM。
封装形式具有 80 引脚 TQFP 和 112 引脚 LQFP 两种形式的封装:具有 5V 输入和驱动能
力,核心运算能力可以达到 50MHz,总线速度可以达到 25MHz,并支持单线背景调试模式
(BDM)、可以在线设置硬件断点。

6.2.2 丰富的IO接口
(1)通用 I/O:29 路独立的数字 I/O 接口,20 路带中断和唤醒功能的数字 I/O 接口。
(2)A/D 转换接口:两个 8 通道的 10 位 A/D 转换器、具有外部转换触发能力。
(3)输入捕捉/输出比较与 PWM:具有 8 个通道的输入捕捉/输出比较。还具有 8 个可
(4)编程 PWM 通道,可配置成 8 通道 8 位或 4 通道 16 位 PWM,其每个通道的周期和
占空比均可以通过编程独立设置。可编程的时钟选择逻辑,使得输出脉冲的频率可设定在较宽
的范围内。
(5)串行通信接口:具有两个串行异步通讯接口 SCI、两个同步串行外设接口 SPI、
Byteflight、Inter-IC 总线以及 SAE J1850 Class B 数据通信网络接口。

6.2.3 内部结构简图、引脚图及引脚功能
表 6-1 MC9S12DG128(112 脚) I/O 类引脚分类
第一 第二 第三
I/O 口名 引脚 说明
功能 功能 功能
82 ADT1 外部触发输入脚
普 ADT1 输入引脚
AATD1 80、78、76、74、

模拟 72、70、68

量输 81 ADT0 外部触发输入脚

入 ATD0 79、77、75、73、 ADT0 输入引脚

71、69、67
A口 64~57 宽总线模式下,多路复用外
B口 31~24 部地址和数据线
总线模式下当前总线是否处
36 晶振选择
于空闲周期
37,38 MCU 工作模式的选择 指令队列跟踪信号引脚 内部下拉
非正常单片模式,内总线时
39
E口 钟外部连接引脚
53 低字节选通 TAGLO 引脚
54 通 外部读/写功能引脚; 内部
用 上拉
55、56 外部中断输入脚,
I/O
32~35 口
H口 中断输入引脚
49~52 串行外围接口(SPI1)
98 CAN4 的发送数据的输出引
IIC 模块的串行时钟引脚
J口 99 脚
21、22 KWJ1、KWJ0 PJ1、PJ0
仿真芯片选择 决定 MISC 寄存器
108
输出引脚 ROMON 位值 内部
K口
总线模下外部 上拉
19、20、5~8
总线扩展地址

46
87、88
Byteflight
M口 100,101 SPI0
CAN/BDLC
102~105
109~112、
P口 中断输入引脚 PWM 模块
1~4 SPI1
93~96 SPI0
S口
89~92 SCI
T口 15~18、9~12 定时器模块
备注:若引脚没有使用,用户必须将其设置为输入,并使其带上拉电阻,避免消耗过量电流

表 6-2 MC9S12DG128(112 脚) MCU 最小系统支撑引脚分类

类型 名称 引脚号 说明
VDDX、VSSX 107、106 I/O 的外部电源
VDDR、VSSR 41、40 I/O 和内部电压调节模块的外部电源
VDD1、VSS1、VDD2、VSS2 13~14、65~66 MCU 的电源
电源 VDDA、VSSA 83、86 电压调节及内部 A/D 转换的电源
VRH、VRL 84、85 AD 转换的参考电压端
VDDPLL、VSSPLL 43、45 PLL 的电源供给端
VREGEN 97 片内电压调节模块的使能端
RESET 42 复位引脚(有内部上拉)
控制
BKGD/MODC/ TAGHI 23 背景调试引脚(内部上拉)
XFC 44 PLL 的外部滤波电容连接脚
其他
EXTAL、XTAL 46、47 片内振荡器引脚
可以把全部引脚分为 I/O 引脚及 MCU 最小系统支撑引脚两大类。表 6-1 给出了 DG128(112
脚)的 I/O 类引脚分类简要说明,表 6-2 给出了 DG128(112 脚) MCU 最小系统支撑引脚简要说
明。

6.2.4 DG128最小系统
MCU 最小系统是指可以使内部程序运行起来的所必须的外围电路。DG128 芯片的最小系
统包括电源电路、PLL 电路、复位电路、晶振电路、BDM 调试接口电路等,如图 2-1 所示。
图中也给出了最小系统元件的参考值。
(1)电源电路:HCS12 MCU 的芯片内部使用 3V 电压,I/O 端口和外部供电电压为 5V。
图 6-15 给出的 DG128 最小系统电路中,电源电路部分的 C1 和 C2 构成滤波电路,可以改善
系统的电磁兼容性, 降低电源波动对系统的影响, 增强电路工作稳定性。为标识系统通电与否,
可以增加一个电源指示灯。

47
MC9S12DG128(112 脚)
VDDR VSSR VDDPLL XFC RESET EXTAL BKGD
(41) (40) (43) (44) (42) (46) (23)

C2 CP 5V VDD RESET
R 4 3
5V 4.7µF ST VCC OUT
470pF RS 10K他 0.1µF 51Ω 9.83 MHz 22Ω 1 2
3
C1
1.5K
10K
TTT OSC 4
0.1µF 1 2
CS 4.7nF 5V NC GND GND BKGD

电源电路 PLL 电路 复位电路 有源晶振电路 BDM调试端口电路


电路
图6-15 MC9S12DG128最小系统电路

(2)PLL 电路:片内的 PLL 电路兼有频率放大和信号提纯的功能,因此,系统可以以较


低的外部时钟信号获得较高的工作频率,以降低因高速开关时钟所造成的高频噪声。图 6-15
电路的 PLL 部分,VDDPLL 引脚由单片内部提供 2.5V 电压。CS、 CP 和 RS 的取值和晶振、REFDV
寄存器和 SYNR 寄存器有关,需要通过计算得出。在数据手册上有一个计算的流程图,可以
计算出它们的值。对于 fOCS=4MHz,总线时钟为 25MHz 时,通过计算得出 CS、CP 和 RS 分别
为 4.7nF、470pF 和 10K 欧姆。
MCU 系统时钟电路和电源电路在布 PCB 板时,要按照以下规则布线,才能使得系统的电
磁兼容性得到保证: (1)尽量让时钟信号回路周围电场趋近于零。用地线将时钟区圈起来,时
钟线要尽量短。 (2)石英晶振下面和对噪声特别敏感的器件下面不要走线。(3)PLL 的滤波
电路要尽量靠近 MCU, 每个电源端和接地端都要接一个去耦电容, 去耦电容要尽量靠近 MCU。
(3)复位电路:HCS12 系列 MCU 在响应各种外部或侦测到的内部系统故障时可进行系
统复位。当 MCU 检测到需要复位时,它将寄存器和控制位设置成已知的起始默认值。系统复
位的用途是错误恢复。即当 MCU 检测到内部故障时,它尝试回到一个已知的、明确的状态而
从故障中恢复。共有四种事件可以触发系统复位:外部复位、加电复位、计算机正常工作复位
(Computer Operating Properly—COP)以及时钟监控复位。当上述事件触发复位时,HCS12
在程序计数器中放置一个复位向量(内存地址),处理器执行启动例程。COP 复位和时钟监控
复位还有其各自的复位向量。图 6-15 中包含了芯片硬件的复位电路。正常工作时复位引脚通
过 4.7K 欧姆电阻接到电源正极(这里设为 5V 电源供电),所以应为高电平。若按下复位按钮
RST,则 RESET 脚通过 100Ω 接地,为低电平,芯片复位。要注意的是如果复位引脚被一直
拉低,MCU 将不能正常工作。
(4)晶振电路 :图 6-15 的最小系统电路中的晶振电路部分使用的是有源晶振 oscillator
(振荡器),需要外接电源的晶振称为有源晶振。DG128 的 XCLKS 引脚是晶振电路类型选择
引脚。当 XCLKS=0 时,外部时钟选择科尔皮兹(Colpitts)晶振;当 XCLKS=1 时,选用皮尔兹
(Pierce)晶振,也可以选用与 CMOS 兼容的外部时钟信号(图 6-15 中使用外接有源晶振)。由
于引脚有内部上拉,若该引脚不外接电路(悬空),则 XCLKS 默认为 1。
(5)BDM 接口电路:背景调试模式 BDM(Background Debug Mode)是由 Freescale 半导体
公司自定义的片上调试规范。BDM 调试方式为开发人员提供了底层的调试手段。开发人员可
以通过它初次向目标板下载程序,同时也可以通过 BDM 调试器对目标板 MCU 的 Flash 进行
写入、擦除等操作。 用户也可以通过它进行应用程序的下载和在线更新、在线动态调试和编程、
读取 CPU 各个寄存器的内容、MCU 内部资源的配置与修复、程序的加密处理等操作。而这些

48
仅需要向 CPU 发送几个简单的指令就可以实现,从而使调试软件的编写变得非常简单(通常
用户自己就可以编写) 。BDM 硬件调试插头的设计也非常简单,关键是要满足通信时序关系
和电平转换要求。
表 6-3 BDM 调试端口信号含义
BKGD 1 2 GND
NC 3 4 RESET BKGD 单线背景调试模式引脚
NC 5 6 VDD GND 接地
VDD 电源
图6-15 Freescale的BDM调试头引脚定义
RESET 目标机复位引脚
目前常用的标准 BDM 调试插头如图 6-15 所示,各个引脚信号的定义如表 6-3 所示。由于
早期的 USB 接口比较少见,所以大部分的 BDM 调试头采用了 6 针的封装。但是这样的封装
不仅插拔不方便而且用户很可能将接头插反而导致硬件的损坏。因此需要对 BDM 调试插头的
封装进行改进。考虑到 BDM 调试头实际只用到了四个引脚,可以使用 B 型 USB 连接头来代
替传统的 BDM 调试头封装,这样连接不仅使用更方便,而且可以有效的防止插反。

6.3 智能车常用的功能模块
智能车的制作,主要用到这样几个模块:GPIO 模块,串口模块,A/D 转换模块,定时器
模块(计数功能、输入捕捉功能、脉冲累加功能、PWM 功能),下面以 MC9S12DG128 MCU
为例,来介绍这几个模块的功能,并给出样例程序。

6.3.1 GPIO模块
GPIO 模块可以输出指定的高低电平,或读入输入电平,可以用于小灯,拨码开关,电机
驱动芯片 33886 的控制。

1. GPIO概述
通用 I/O:GPIO(General Purpose I/O),是 I/O 的最基本形式,它是一组输入或输出引脚,有
时也称为并行 I/O(parallel I/O)。作为普通输入引脚,MCU 内部程序可以读取该引脚,知道该
引脚是“1”(高电平)或“0”(低电平),即开关量输入。作为普通输出引脚,MCU 内部程序由该引
脚输出“1”(高电平)或“0”(低电平),即开关量输出。大多数通用 I/O 引脚可以通过编程来设定工
作方式为输入或输出,称之为双向通用 I/O。

2. I/O口的使用方法
MC9S12DG128 MCU 有 10 个普通 I/O 口,分别是 A 口、B 口、E 口、H 口、J 口、K 口、
M 口、P 口、S 口、T 口。这些引脚中的大部分具有双重功能,其中 A、B、E、K 口只用做
GPIO 功能,这里仅讨论它们编程方法。
使用这些 I/O 口主要设置如下寄存器:
1)数据方向寄存器(Data Direction Register x,DDRx)
DDRx 的第 7~0 位分别记为 DDRx7~DDRx0,这些位分别控制着 x 口引脚 PORTx7~
PORTx0 是输入还是输出,若 DDRxn=0,则引脚 PORTAxn 为输入,若 DDRxn=1,则引脚
PORTxn 为输出。复位时 DDRx 为$00。(注:x 代表 A、B、E、K 口中的某一个,n 表示某
一位)
2)数据寄存器(Port x I/O Register,PORTx)
PORTx 的第 7~0 位分别记为 PORTx7~PORTx0。若 A 口的某一引脚 PORTxn 被定义

49
成输出,程序使 x 口 I/O 寄存器 PORTx 的相应位 PORTxn=0,则引脚 PORTxn 输出“低电平”;
程序使 PORTxn=1,则引脚 PORTxn 输出“高电平”。若 x 口的某一引脚 PORTxn 被定义成
输入,程序通过读取 x 口 I/O 寄存器 PORTx,获得输入情况,0 表示输入为“低电平”,1 表
示输入为“高电平”。
3)上拉电阻控制寄存器
A 口、B 口、E 口、K 口分别都有上拉电阻,它们共用一个控制寄存器(PUCR)。PUCR
的第 0 位称为 PUPAE(标识中“A”代表 A 口;B 口、E 口、K 口等亦如此),含义是 A 口的上
拉电阻使能位。当 PUPAE=1 时,A 口的 8 个引脚中被定义为输入的引脚有内部上拉电阻。
类似地,有设定 B 口、E 口、K 口上拉电阻的位:PUPBE、PUPEE、PUPKE,分别是 PUCR
的第 1、4、7 位。PUCR 的其它位未定义。

3.样例程序
1) 小灯控制头文件 Light.h
//小灯控制引脚定义
#define Light_P PORTA //灯(Light)接在PTA口
#define Light_D DDRA //相应的方向寄存器
#define Light_Pin 1 //灯所在的引脚

//小灯控制相关函数声明
void LEDInit(void); //定义控制小灯的MCU引脚为输出
void LED_L_A(INT8U flag); //驱动小灯"亮"、"暗"

2) 小灯控制子函数 Light.c
//LEDInit:定义控制小灯的MCU引脚为输出--------------------------------------*
//功 能:定义控制小灯的MCU引脚为输出,并使小灯初始为暗 *
//参 数:无 *
//返 回:无 *
//-------------------------------------------------------------------------*
void LEDInit(void)
{
Light_D |= 1<<Light_Pin; //令小灯引脚为输出
Light_P |= 1<<Light_Pin; //初始时,小灯"暗"
}

//LED_L_A:驱动小灯"亮"、"暗"-----------------------------------------------*
//功 能:根据flag的值控制小灯的亮和暗 *
//参 数:flag(flag='A',小灯暗;flag='L',小灯亮) *
//返 回:无 *
//-------------------------------------------------------------------------*
void LED_L_A(INT8U flag)
{
if (flag == 'A')
Light_P |= 1<<Light_Pin; //小灯"暗"
else if (flag == 'L')
Light_P &= ~(1<<Light_Pin); //小灯"亮"
}

3) 小灯控制主函数 main.c
//-------------------------------------------------------------------------*
//硬件连接:MCU的I/O口引脚PTA1接小灯 *

50
//程序描述:用I/O口控制小灯闪烁 *
//注 意:如果延时不够长的话,会发觉灯不会闪烁,而是一直亮,这是由于人的 *
// 视觉的引起的. *

//头文件
#include "Includes.h" //总头文件

//主函数
int main()
{
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
LEDInit(); //(1) 小灯控制引脚初始化
//总循环
while (1)
{
LED_L_A('L'); //小灯亮
Delay(500); //延时

LED_L_A('A'); //小灯暗
Delay(500); //延时
}
}
完整程序请见网络光盘“………./第五章样例程序/ 01_Frame”

6.3.2 串口模块
1. 串口模块概述
串口主要用于通信,在小车调试的时候可以使用。
目前几乎所有的台式电脑都带有 9 芯的异步串行通信口,简称串行口或 COM 口,串行通
信是 MCU 与外部设备之间进行通信的一种简单而有效的硬件方法。SCI 采用的是 NRZ 数据
格式,英文全称是: “standard non-return-zero mark/space data format”,可以译为:“标准不归
零传号/空号数据格式” 。不归零”的最初含义是:用负电平表示一种二进制值,正电平表示另
一种二进制值,不使用零电平。 “mark/space”即“传号/空号”分别是表示两种状态的物理名
称,逻辑名称记为“1/0” 。对学习嵌入式应用的读者而言,只要理解这种格式只有“1” 、“0”
两种逻辑值就可以了。
“位”(bit)是单个二进制数字的简称,是可以拥有两种状态的最小二进制值,分别用“0”和“1”
表示。在计算机中,通常一个信息单位用 8 位二进制表示,称为一个“字节”(byte)。串行通信
的特点是:数据以字节为单位,按位的顺序从一条传输线上发送出去。
位长(bit length) ,也称为位的持续时间(bit duration) ,其倒数就是单位时间内传送的位数。
人们把每秒内传送的位数叫做波特率(baud rate) ,波特率的单位是:位/秒,记为 bps,可以省
略。通常使用的波特率有 300、600、900、1200、1800、2400、4800、9600、19200、38400。
在 MCU 中,若用 RS-232C 总线进行串行通信,则需外接电路实现电平转换。在发送端
需要用驱动电路将 TTL 电平转换成 RS-232C 电平,在接收端需要用接收电路将 RS-232C 电平
转换为 TTL 电平。电平转换器不仅可以由晶体管分立元件构成,也可以直接使用集成电路,
目前使用 MAX232 芯片较多。
串口通信编程的基本原理,串行通信接口 SCI 的主要功能是:接收时,把外部的单线输

51
入的数据变成一个字节的并行数据送入 MCU 内部;发送时,把需要发送的一个字节的并行数
据转换为单线输出。图 6-16 给出了一般 MCU 的 SCI 模块的功能描述。为了设置波特率 SCI
应具有波特率寄存器。为了能够设置通信格式、是否校验、是否允许中断等,SCI 应具有控制
寄存器。而要知道串口是否有数据可收、数据是否发送出去等,需要有 SCI 状态寄存器。当
然,若一个寄存器不够用,控制与状态寄存器可能有多个。而 SCI 数据寄存器存放要发送的
数据,也存放接收的数据,这并不冲突,因为发送与接收的实际工作是通过“发送移位寄存器”
和“接收移位寄存器”完成的。发送时,程序员通过判定状态寄存器的相应位,了解是否可以
发送一个新的数据。若可以发送,则将待发送的数据放入“SCI 数据寄存器”中就可以了;接
收时,数据一位一位地从接收引脚 RxD 进入“接收移位寄存器”,当收到一个完整字节时,
MCU 会自动将数据送入“SCI 数据寄存器”,并将状态寄存器的相应位改变,供程序员判定并
取出数据。

接收引脚 发送引脚
RxD TxD

接收移位寄存器 发送移位寄存器

15
SCI 数据寄存器
SPH 15
H 8 7

X 0
MCU 的 内 部 总 线 (Internal Bus)

7 0

SCI 控制寄存器 SCI状态寄存器 SCI波特率寄存器


7
图6-16 SCI编程模型
无论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对 SCI 进行初
始化,主要进行波特率设置、通信格式的设置、发送接收数据方式的设置等。本小节给出最基
本的方法,作为 HCS12 系列 MCU 的串行通信编程入门知识。下一小节将给出规范的串行通
信编程子程序,读者可以直接将其应用于智能小车的开发中。
1)SCI 初始化
有关口地址的定义已经在头文件 mc9s12dg128.h 中给出,SCIBDH、SCIBDL、SCICR1、
SCICR2、SCISR1、SCISR2、SCISDRH、SCISDRL 等接口可以直接使用。
对 SCI 进行初始化,最少由以下三步构成(以 SCI0 为例):
第一步定义波特率。一般选择内部总线时钟为串行通信的时钟源。设 MCU 系统初始化时
已定义总线频率为 fBUS,同时准备定义串行通信波特率记为为 Bt,可通过设置 SCI 波特率寄
存器 SCI0BD 的波特率选择位 SBR[12:0](13 位)以便选择合适的分频系数,代入公式 Bt=fBUS/
(16×SCI0BD) ,使得 Bt 等于预设的波特率值。这里举例说明,设总线频率 fBUS=19.6608Mhz,
准备定义波特率 Bt=9600,则由公式 Bt=fBUS/(16×BR)可以得到 SCI0BD=128,则 SCI0BD
的值应为二进制“10000000” ,即 SCI0BDL=$80,SCI0BDH=$00,程序如下。
//总线频率 fBUS=19.6608MHz,定义波特率 Bt=9600(针对 SCI0)
SCI0BDL=0x80; //须先给低 8 位赋值
SCI0BDH=0x00; //再给高 5 位赋值

52
第二步写控制字到 SCI 控制寄存器 1(SCI0CR1)。设置是否允许 SCI、数据长度、输出
格式、选择唤醒方法、是否校验等。如若设定允许 SCI、正常码输出、8 位数据、无校验,则
SCI0CR1 取值应为二进制“00000000”,程序如下。
//设置允许 SCI,正常码输出、8 位数据、无校验
SCI0CR1=0x00;
实际上,这种情况只要取 SCI0CR1 各位的默认值即可。
第三步写控制字到 SCI 控制寄存器 2(SCI0CR2)。设置是否允许发送与接收、是中断接
收还是查询接收等。如若设置允许发送(TE=1)、允许接收(RE=1)、查询方式收发,则 SCI0CR2
取值应为二进制“00001100” ,程序如下:
//设置允许发送、允许接收,查询方式收发
SCI0CR2=0x0C;
另外几个寄存器供后面编程使用,不需初始化。
2)发送一个数据与接收一个数据
一般情况下,对 SCI 的初始化仅在程序的初始化部分进行一次即可,而串行通信的基本
用途就是编程来发送与接收数据。 发送数据是通过判断状态寄存器 SCI0SR1 的第 7 位
(TDRE)
进行的,而接收数据是通过判断状态寄存器 SCI0SR1 的第 5 位(RDRF)进行的。不论是发送
还是接收,均会使用 SCI 数据寄存器 SCI0DRL。发送时将要发送的数据送入 SCI0DRL 即可,
接收时从 SCI0DRL 中取出的即是收到的数据。
例如,下面的程序将字节型变量 i 中的数从串行引脚 TxD 发送出去。通过对状态寄存器
SCI0SR1 的第 7 位(TDRE)判断是否可以向数据寄存器 SCI0DRL 送数,若 TDRE=1 可以送
数,否则必须等待。
//判断 SCI0SR1 的第 7 位(TDRE)是否为 1,是 1 则可以发送数据 Data
while(1)
if ((SCI0SR1 & (1<<7)) != 0) // SCI0SR1.7=0?为 0 则等待
{ // SCI0SR1.7=1,可以发送数据
SCI0DRL =i;
break;
}
要以查询方式接收一个数据,首先通过状态寄存器 SCI0SR1 的第 5 位(RDRF)判断有没
有数据可收,若 RDRF=1 则有数据可收,下面程序持续等待串行口(实际上是 RxD 引脚)接
收一个字节数据。
//查询方式接收一个字节的数据放入字节型变量 i 中:
while(1)
if ((SCI0SR1 & (1<<5)) != 0) // SCI0SR1.5=0?为 0 则等待
{ // SCI0SR1.5=1,可以取出数据
i = SCI0DRL;
break;
}
在实际编写串行通信接收子函数时,不采用永久循环形式,而改用测试一段时间,若无数
据可接收,则带错误标志返回。

53
2. 样例程序
1) 串行通信头文件 SCI.h
//串行通信寄存器及标志位定义
#define ReSendStatusR SCI0SR1 //SCI状态寄存器
#define ReTestBit 5 //接收缓冲区满标志位
#define SendTestBit 7 //发送缓冲区空标志位
#define ReSendDataR SCI0DRL //数据寄存器

//串行通信相关函数声明
void SCIInit(void); //串行口初始化函数声明
void SCISend1(INT8U o); //串行发送1个字节
void SCISendN(INT8U n,INT8U ch[]); //串行发送n个字节
INT8U SCIRe1(INT8U *p); //串行接收1个字节
INT8U SCIReN(INT8U n,INT8U ch[]); //串行接收 n 个字节

2) 串行通信子函数 SCI.c
//SCIInit:DG128串行口0初始化函数------------------------------------------*
//功 能: *
// 开SCI0关SCI1,关串口中断,对串行口进行初始化,默认为允许SCI,正常码输出,*
// 8位数据,无校验等,允许发送,允许接收 .查询方式收发,波特率为9600 *
// (设fBUS=19.6608Mhz) *
//参 数:无 *
//返 回:无 *
//说 明: *
// (1)若初始化SCI1,只需SCI0->SCI1 *
// (2)该初始化函数与芯片有关 *
//------------------------------------------------------------------------*
void SCIInit(void)
{
INT8U t;
//定义波特率Bt=9600,SCI0BD=fBUS/(16*Bt)
SCI0BDL = 0x80; //须先给低8位赋值
SCI0BDH = 0x00; //再给高8位赋值
SCI0CR1 = 0x00; //设置允许SCI,正常码输出,8位数据,无校验
t = SCI0DRL; //读数据寄存器(清0)
t = SCI0SR1; //读状态寄存器(清0)
SCI0CR2 = 0x0C; //允许SCI0接收和发送 查询方式
}
//SCISend1:串行发送1个字节------------------------------------------------*
//功 能:串行发送1个字节 *
//参 数:o=要发送的数据 *
//返 回:无 *
//------------------------------------------------------------------------*
void SCISend1(INT8U o)
{
//判断ReStatusR的第SendTestBit位是否为1,是1可以发送
while (1)
if ((ReSendStatusR & (1<<SendTestBit)) != 0)
{
ReSendDataR = o;
break;
}
}

54
//SCISendN:串行发送N个字节------------------------------------------------*
//功 能:发送数组中的N个字节数据 *
//参 数:n=待发送的数据字节数,ch=存放待发送数据的数组首地址 *
//返 回:无 *
//内部调用函数:SCISend1 *
//------------------------------------------------------------------------*
void SCISendN(INT8U n,INT8U ch[])
{
INT8U i;
for (i=0; i<n; i++)
SCISend1(ch[i]);
}

//SCIRe1:串行接收一个字节数据---------------------------------------------*
//功 能:从串行口接收1个字节的数据 *
//参 数:p=标志指针 *
//返 回:接收到的数据(若接收失败,返回0xff) *
//说 明:参数*p带回接收标志=0收到数据,=1未收到数据 *
//------------------------------------------------------------------------*
INT8U SCIRe1(INT8U *p)
{
INT16U k;
INT8U i;
//ReStatusR第ReTestBit位为1表示可接收数据
for (k=0; k<0xfbbb; k++)
if ((ReSendStatusR & (1<<ReTestBit)) != 0)
{
i = ReSendDataR;
*p = 0x00;
break;
}
//接收失败
if (k >= 0xfbbb)
{
i=0xff;
*p=0x01;
}
return i; //返回接收到的数据
}

//SCIReN:HC08串行接收N个字节----------------------------------------------*
//功 能:接收N个字节数据,并存放在ch数组中 *
//参 数:n=待接收的数据字节数,ch=存放待接收数据的数组首地址 *
//返 回:接收标志=0收到数据,=1未收到数据 *
//内部调用函数:SCIRe1 *
//------------------------------------------------------------------------*
INT8U SCIReN(INT8U n,INT8U ch[])
{
INT8U m;
INT8U fp;
m = 0;
//接收n个数据
while (m<n)
{

55
ch[m] = SCIRe1(&fp);
if (fp == 1) return 1; //只要有1个字节数据没接收到就返回报错
m++;
}
return 0;
}

3) 串口测试(查询方式)主函数 main.c
//------------------------------------------------------------------------*
//硬件连接:MCU的串行口与PC机的串行口相连 *
//程序描述:利用查询方式把收到的数据发送回去 *
//说 明:波特率为9600,使用SCI0口 *
//------------------------------------------------------------------------*
//头文件
#include "Includes.h" //总头文件

//主函数
int main()
{
INT8U i;
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
SCIInit(); //(1) 串口初始化
//总循环
while (1)
{
i = SCIReN(1,SerialBuff); //等待接收1个数据
if (i == 0) SCISendN(1,SerialBuff); //发送接到的数据
}
}
完整程序请见网络光盘“………./第五章样例程序/ 02_SCIpooling”

6.3.3 A/D转换模块
1. A/D模块概述
A/D 转换模块主要用于路径信息的采集。
在过程控制和仪器仪表中,多由嵌入式计算机进行实时控制及实时数据处理,计算机所加
工的信息总是数字量,而被检测的对象却往往是一些连续变化的模拟量(如,温度、压力、速
度和流量等),因此需要将模拟量转化成为数字量,以便在计算机中进行运算处理,此过程称
为模数(A/D)转换 (Analog To Digital Convert ),如图 6-17 所示。实际应用中,这个模拟量可能
由温度、湿度、压力等实际物理量经过传感器和相应的变换电路转化而来。

被测参量 参量/电压 模拟量 A/D 数字量 数字电子 数字量 D/A 模拟量 被控制
转换 转换器 计算机 转换器 对象
6-17数字控制系统框图
进行 A/D 转换,应该了解以下一些基本问题:
 采样精度:采样精度就是指数字量变化一个最小量时模拟信号的变化量,即通常所说
的采样位数。通常在 MCU 中采样位数为 8 位,某些增强型的可达到 10 位,而专用的 A/D 采

56
样芯片则可达到 12 位,14 位,甚至 16 位。设采样位数为 N,则最小的能检测到的模拟量变
化值为 1/2N。如某 MCU 采样精度最高为 8 位,参考电压为 5V,则检测到的模拟量变化为
5/28=0.0195313V。
 采样速率:采样速率是指完成一次 A/D 采样所要花费的时间。在多数的 MCU 中要花
费 15~20 个指令周期,因而此速率和所选器件的工作频率有很大关系。
 滤波问题:为了使采样的数据更准确,必须对采样的数据进行筛选去掉误差较大的毛
刺,可以采用中值滤波和均值滤波来提高采样精度。中值滤波是取三次采样的中间值,均值滤
波是取多次采样的算术平均值。若要得到更高的精度,可以通过建立其他误差模型分析方式来
实现
 物理量回归:在实际应用中,得到稳定的 A/D 采样值以后,还需要把 A/D 采样值与
实际物理量对应起来,这一步称为物理量回归。A/D 转换的目的是把模拟信号转化为数字信号,
供计算机进行处理,但必须知道 A/D 转换后的数值所代表的实际物理量的值,这样才有实际
意义。例如,利用 MCU 采集室内温度,A/D 转换后的数值是 126,它代表多少温度呢?如果
当前室内温度是 25.1℃,则 A/D 值的 126 就代表实际温度 25.1℃。

2. DG128内部A/D转换模块
MC9S12DG128 MCU 的 8 路 10 位 A/D 转换模块引脚为 AN7/PAD7/ETRIG~AN0/PAD0,
每个引脚都可以实现模拟量(ANx)/数字量(PADx)的复用输入。为了与外部信号同步进行 A/D
转换,A/D 模块具有一个外部触发转换通道 ETRIG,用户可以选定触发的方式(沿触发或电平
触发)。这里讨论 8 路 A/D 转换器的编程方法。
A/D 转换有个参考电压问题,在使用到 A/D 转换器的输入引脚时,芯片的 VRH、VRL 引脚
必须分别接参考电压的正、负,通常就是接电源的正、负端。VDDA、VSSA 引脚作为 A/D 转
换器的电源提供引脚,分别接电源的正、负端。
A/D 转换的最大时钟频率为 2MHz,最小时钟频率为 500KHz,而正常 A/D 转换一般要求
提供 1MHz 的 ADC 时钟频率。一次一路 A/D 转换时间一般为 16 到 17 个 ADC 时钟周期,所
以一般 A/D 转换时间约为 16~17µS。
MC9S12DG128 的 A/D 转换模块有 20 个寄存器,包括 6 个 A/D 转换控制寄存器
(ATDCTL0~ATDCTL5)、2 个 A/D 转换状态寄存器(ATDSTAT0~ATDSTAT7)、2 个 A/D 转换
测试寄存器(ATDTEST0~ATDTEST1)、A/D 转换输入使能寄存器(ATDDIEN)、端口数据寄存
器(PORTAD)、8 个 A/D 转换结果寄存器(ATDDR0~ATDDR7)。通过对这些寄存器的编程,就
可以获取 A/D 转换数据。关于这些寄存器的定义参见芯片手册,在下节的样例程序中将通过
实际的例子来介绍这些寄存器的使用。

3. A/D转换模块的基本编程方法
A/D 转换编程主要涉及 4 个控制寄存器(ATDCTL2~ATDCTL5)、状态寄存器 0(ATDSTAT0)、
数据寄存器(ATDDR0~ATDDR8)。
1) A/D 转换初始化
在程序初始化时应对A/D转换的3个控制寄存器(ATDCTL2~ATDCTL4)写入控制字节,决
定序列长度,设置分频系数和转换精度等。
ATDCTL2 = 0b11000000;
//ATDCTL2.ADPU = 1 为打开转换电源开关
//ATDCTL2.AFFC = 1 为 A/D 转换 CCF 自动清 0 位
ATDCTL3 = 0b00001011;

57
//ATDCTL3.S1C = 1 表示序列长度为 1
//ATDCTL3.FIFO = 0 为非 FIFO 模式
//ATDCTL3.FRZ0~FRZ1 = 11 表示立刻进入冻结模式
ATDCTL4 =0b00000111;
//ATDCTL4.PRS4~PRS0 = 00111 表示总线频率 16 分频
ATDCTL4 &=0b01111111;
//ATDCTL4.SRES8 = 0 表示 10 位转换精度
2) 启动 A/D 转换
对A/D转换状态和控制寄存器ATDCTL5写入控制字节,选取要转换的通道、结果寄存器
的调整方式、设置是连续转换还是一次转换,此时就开始了一路A/D转换。
ATDCTL5 = 0b00100000;
//ATDCTL5.DJM = 0,结果寄存器数据采用左调整方式
//ATDCTL5.SCAN = 1,连续转换序列
//ATDCTL5.CC~CA = 000,启动 0 通道转换
3)获取 A/D 转换结果
若是中断方式,在A/D中断程序中取得,若是查询方式,通过 A/D转换状态寄存器
0(ATDSTAT0)的第7位(SCF位)取得,当SCF=1时可从A/D数据寄存器ATDDR0~ATDDR7中取
的数据。
//取 A/D 转换结果
while(1)
//判断 ATDSTAT0 的第 7 位是否为 1
if((ATDSTAT0&(1<< SCFBit))!=0)
//从 A/D 数据寄存器 0 中读数据
{
temp = ATDDR0; //10-bit 数据
//对数据调整,使低十位有效
temp = (temp >> 6);
break;
}
return temp; //返回 10-bit 的转换结果

4. 样例程序
1) A/D 转换头文件 ADC.h
//[ADC.h]AD转换-------------------------------------------------------------

//AD转换寄存器及标志位定义
#define SCFBit 7 //转换完成标志位

//串行通信相关函数声明
void ADCInit(void); //A/D转换初始化
INT16U ADCvalue(INT8U channel); //1路10位A/D转换
INT16U ADCmid(INT8U channel); //1路10位A/D转换(中值滤波)
INT16U ADCave(INT8U n,INT8U channel); //1 路 10 位 A/D 转换(平均值滤波)

58
2) A/D 转换子函数 ADC.c
//ADCInit:A/D转换初始化----------------------------------------------------*
//功 能:初始化AD转换 *
//参 数:无 *
//返 回:无 *
//-------------------------------------------------------------------------*
void ADCInit(void)
{
//ATDCTL2.ADPU = 1为打开转换电源开关
//ATDCTL2.AFFC = 1为A/D转换CCF自动清0位
ATDCTL2 = 0xC0;
//ATDCTL3.S1C = 1表示序列长度为1
//ATDCTL3.FIFO = 0为非FIFO模式
//ATDCTL3.FRZ0~FRZ1 = 11表示冻结模式进入BDM
ATDCTL3 = 0x0B;
//ATDCTL4.PRS4~PRS0 = 00111表示总线频率16分频
ATDCTL4 = 0x07;
//ATDCTL4.SRES8 = 0表示10位转换精度
ATDCTL4 &= 0x7F;
}

//ADCvalue:1路10位A/D转换函数----------------------------------------------*
//功 能:获取通道channel的10位A/D转换结果 *
//参 数:channel=通道号(0~15) *
//返 回:该通道的A/D转换结果(0~1023) *
//-------------------------------------------------------------------------*
INT16U ADCvalue(INT8U channel)
{
INT16U temp; //暂存A/D转换的结果
//ATDCTL5.DJM = 0,结果寄存器数据采用左调整
//ATDCTL5.SCAN = 1,连续转换序列
//ATDCTL5.CC~CA = channel,启动通道转换
ATDCTL5 = (0x20 | channel);
//取A/D转换结果
while (1)
//判断ATDSTAT0的第7位是否为1
if ((ATDSTAT0&(1<< SCFBit)) != 0)
{
temp = ATDDR0; //从A/D数据寄存器0中读10位数据
temp = (temp >> 6); //对数据调整,使低十位有效
break;
}
return temp;
}

//ADCmid:1路A/D转换函数(中值滤波)------------------------------------------*
//功 能:获取通道channel中值滤波后的A/D转换结果 *
//参 数:channel=通道号(0~15) *
//返 回:该通道中值滤波后的A/D转换结果(0~1023) *
//内部调用函数:ADCvalue *
//-------------------------------------------------------------------------*
INT16U ADCmid(INT8U channel)
{
INT16U i,j,k,tmp;
//1.取三次A/D转换结果

59
i = ADCvalue(channel);
j = ADCvalue(channel);
k = ADCvalue(channel);
//2.从三次A/D转换结果中取中值
if (i > j)
{
tmp = i; i = j; j = tmp;
}
if (k >= j)
{
tmp = j;
}
else
{
if (k >= i)
tmp = k;
else
tmp = i;
}
return tmp;
}

//ATDave:1路A/D转换函数(均值滤波)------------------------------------------*
//功 能:对通道channel的A/D转换结果求n次平均值 *
//参 数:n=均值滤波次数(0~255),channel=通道号(0~15) *
//返 回:该通道均值滤波后的A/D转换结果 *
//内部调用函数:ADCmid *
//-------------------------------------------------------------------------*
INT16U ADCave(INT8U n,INT8U channel)
{
//求n次A/D转换的平均值
INT8U i;
INT16U j;
if(0 == n) n = 1;
j = 0;
for (i=0; i<n; i++)
j += ADCmid(channel);
j /= n;
return j;
}

3) A/D 转换测试主函数 main.c


//------------------------------------------------------------------------*
//硬件连接: *
// (1)PAD1 接模拟量输入端 *
// (2)MCU的串口与PC方的串口相连 *
//程序描述:获取1路A/D转换结果,并滤波,通过串口发送出去 *
//------------------------------------------------------------------------*
//头文件
#include "Includes.h" //总头文件

//主函数
int main()
{
INT16U adv;

60
INT32U j;
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
SCIInit(); //(1) 串口初始化
ADCInit(); //(2) A/D转换初始化
//总循环
while (1)
{
//在通道0做A/D转换,200次中值滤波,串口发送均值滤波结果
adv = ADCave(200,0);
SCISend1((INT8U)(adv>>8)); //先发送高8位
SCISend1((INT8U)adv); //再发送低8位
//延迟
for(j=0; j<200000; j++);
}
}
完整程序请见网络光盘“………./第五章样例程序/ 03_ADC”

6.3.4 定时器模块
1. 概述
在嵌入式应用系统中,有时要求能对外部脉冲信号或开关信号进行计数,这可以通过计数
器来完成。有些设备要求每间隔一定时间开启并在一段时间后关闭,有些指示灯要求不断地闪
烁,这可利用定时信号来完成。
DG128B 芯片只提供一个定时器,定时器的核心是一个处于不断加 1 的 16 位计数寄存器,
简称为计数器。该计数器的时钟频率由总线时钟经过预定的分频因子分频得到,定时器的所有
动作都以这个经过分频的频率作为参考。从 MCU 的角度看,真正的时间间隔被这个计数器的
定时计数所代替。所以在任何时候可以通过读取计数器的值来确定经历的时间。
在定时器内部有个控制寄存器,通过对其某些位的设置,就可以确定多少时间计数器加 1
(即定时间隔) ,定时间隔可以达到几 ms 到几 s。
在定时器内部还有个预置寄存器,当计数器的值等于预置寄存器的值时,称为计数器溢出,
当计数器溢出时,计数器的值被赋 0,同时将计数器溢出标志等状态置于控制和状态寄存器中。
通过对控制和状态寄存器的某位进行设置,可以决定在计数器溢出时,是否允许中断。利
用该中断, 可以编写中断例程, 实现预定的功能。 使用预置计数功能可以得到精确的溢出时间,
可以在任何时候暂停或清除计数器的计数。

2. DG128定时器特点
MC9S12DG128B MCU 定时器还具有输入捕捉、输出比较、脉冲累加功能。该定时器包
含 8 个完整的输入捕捉/输出比较通道和 4 个 8 位的脉冲累加器,8 个输入捕捉通道中有 4 个
是带缓冲的通道,4 个是不带缓冲的通道,4 个脉冲累加器可以进行两两组合构成 2 个 16 位的
脉冲累加器。输入比较功能可用于检测选定的跳变沿并记录发生跳变的时间;输出比较功能可
用于产生一个输出信号,或用于定时器软件延时;脉冲累加器可当作事件计数器来使用,或作
为门控时间累加器来使用。
MC9S12DG128B MCU 的定时器有 8 个输入捕捉/输出比较通道,每一个通道都有一个输
入/输出引脚 IOCx,x 的取值范围是从 0~7,共 8 个引脚,如图 6-18 所示。

61
总线时钟 预分频因子 通道 0
输入捕捉
模块计数中断 16 位计数器 IOC0
输出比较
定时器溢出中断 16 位模块计数器

… …
定时器通道 0 中断 …
~ 寄存器 …
… …
定时器通道 7 中断
通道 7
PA 溢出中断
16 位脉冲累加器 A 输入捕捉
PA 输入中断
IOC7
PB 溢出中断 16 位脉冲累加器 B 输出比较

图6-18 TIM功能框图
具体的例子参考下节的样例程序

2. 样例程序
1) 定时器溢出中断头文件 Timer.h
//定时器相关函数声明
void TimerInit(void); //定时器初始化函数声明
void TimerUpDate(void); //定时器更新函数声明

//外部变量声明
extern INT8U time[3]; //存放时,分,秒
extern INT8U TimInterCount; //中断次数

2) 定时器溢出子函数文件 Timer.c
//TimerInit:定时器初始化函数-----------------------------------------------*
//功 能:定时器初始化,中断一次时间为 1/38 秒 *
//参 数:无 *
//返 回:无 *
//-------------------------------------------------------------------------*
void TimerInit(void)
{
//禁止定时器溢出中断,分频因子 p=8
//中断一次时间计算:t=n/(fbus/p)=1/38 秒,其中 n=65535,fbus=19.6608MHZ
TSCR2 = 0x03;
TSCR1 = 0x80; //允许主定时器开始计数
}

//TimerUpDate:定时器更新函数-----------------------------------------------*
//功 能:更新显示的时间 *
//参 数:无 *
//返 回:无 *

62
//-------------------------------------------------------------------------*
void TimerUpDate(void)
{
time[2]++; //秒数加 1
if (time[2] != 60) goto isrTIMER1_exit; //秒数未增加到 60,转
time[2] = 0; time[1]++; //秒数增加到 60,清 0,分钟数加 1
if (time[1] != 60) goto isrTIMER1_exit; //分钟数未增到 60,转
time[1] = 0; time[0]++; //分钟数增加到 60,清 0,小时数加 1
if (time[0] != 24) goto isrTIMER1_exit; //小时数未增到 24,转
time[0] = 0; //时数增加到 24,清 0
isrTIMER1_exit:
TimInterCount = 0; //中断次数清零
}

3) 定时器溢出中断测试主函数 main.c
//-------------------------------------------------------------------------*
//硬件连接:MCU 的 SCI0 模块接口与 PC 方的串行口相连 *
//程序描述: *
// (1)从串口接收表示时间的 3 字节数据 *
// (2)利用定时器溢出中断修改时间,并发送新时间 *
//-------------------------------------------------------------------------*

//头文件
#include "Includes.h" //总头文件

//主程序
int main()
{
INT8U remember;
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
SCIInit(); //(1) 串口初始化
TimerInit(); //(2) 定时器 1 初始化
//3. 内存初始化
//(1) "时分秒"缓存初始化(00:00:00)
time[0] = 0;
time[1] = 0;
time[2] = 0;
//(2) 临时变量 remember 初始化
remember = time[2];
//(3) 全局变量 TimInterCount 初始化

63
TimInterCount = 0;
//4. 开放各模块中断
EnableSCIReInt; //(1) 开放 SCI0 接收中断
EnableT1OVInt; //(2) 开放定时器 1 溢出中断
//5. 开放总中断
ENABLE_INTERRUPTS; //开总中断
while (1)
{
if (time[2] != remember)
{
SCISendN(3, time); //发送当前"时分秒"
remember = time[2]; //remember 中存放当前秒值
}
}
}

4) 定时器溢出中断处理程序
//isrTimOver:定时器溢出中断处理程序----------------------------------------*
//功 能:时,分,秒的处理 *
//-------------------------------------------------------------------------*
__interrupt 16 void isrTimOver(void)
{
DISABLE_INTERRUPTS; //关总中断
TimInterCount++; //中断次数加一,中断 38 次为一秒
if (TimInterCount == 38)
{
TimerUpDate(); //定时器更新
}
TFLG2 = 0x80; //清除定时器溢出标志位
ENABLE_INTERRUPTS; //开总中断
}
完整程序请见网络光盘“………./第五章样例程序/ 04_TimeOverInt”

6.3.5 输入捕捉功能
1. 输入捕捉概述
输入捕捉功能用来监测外部的事件和输入信号。当外部事件发生或信号发生变化时,在指
定的输入捕捉引脚上发生一个指定的沿跳变(可以指定该跳变是上升沿还是下降沿)。定时器捕
捉到特定的沿跳变后,把计数寄存器当前的值锁存到通道寄存器。如果在输入捕捉控制寄存器
中设定允许输入捕捉中断,系统会产生一次输入捕捉中断。利用中断处理软件可以得到事件发
生的时刻或信号发生变化的时刻。通过记录输入信号的连续的沿跳变,就可以用软件算出输入
信号的周期和脉宽,例如为了测量周期,只要捕捉到两个相邻的上升沿或下降沿的时间,两者
相减就可以得到周期;为了测量脉宽就要记录相邻的两个不同极性的沿变化的时间。当测量的

64
脉宽值小于定时器的溢出周期时,只要将两次的值(看成无符号数)直接相减即可。如果测量值
大于定时器的溢出周期,那么在两次输入捕捉中断之间就会发生定时器计数的溢出翻转,这时
直接将两个数相减就没有意义,需要考虑定时器的溢出次数。
1 2

图6-19 输入捕捉过程

图 6-19 表示输入捕捉引脚的电平变化。假设触发方式是跳变沿触发(这由定时器控制寄
存器 3 和定时器控制寄存器 4 中的 EDGxB 和 EDGxA 决定);在图中的时刻 1 将计数器的值锁
存在通道寄存器中,在输入捕捉中断中,把它另存到一个内存单元以防下次将内容覆盖;在图
中的 2 时刻会再次进入中断, 这次将通道寄存器的值和内存单元的值相减就得到了为低电平的
时间。

2. 样例程序
1) 输入捕捉头文件 InputCapture.h
//输入捕捉寄存器及标志位定义
//TSCR1 寄存器设置
#define TEN 7 //时钟使能位
#define TFFCA 4 //时钟快标志位全部清除位
#define C0F 0 //通道 0 输入捕捉中断位
//TCTL3/TCLT4 寄存器设置
#define EDG0B 1
#define EDG0A 0

//输入捕捉相关函数声明
void ICInit(void); //输入捕捉系统配置初始化

2) 输入捕捉子函数 InputCapture.c
//ICInit:初始化输入捕捉系统配置-------------------------------------------*
//功 能:初始化,设置通道 0 为沿跳变输入捕捉 *
//参 数:无 *
//返 回:无 *
//------------------------------------------------------------------------*
void ICInit(void)
{
TSCR1 = 0; //禁止时钟
TIOS = ~(1<<0); //设置通道 0 为输入捕捉功能
TCTL4 = 0x03; //设置上升沿和下降沿输入捕捉
TIE = 0x01; //允许通道 0 中断
TSCR2 = 0x06; //不允许溢出中断,分频因子为 64
TSCR1 |=(1<<TEN); //时钟计数
}

65
3) 输入捕捉中断处理函数 isr.c
//ISR_TimerChan0:输入捕捉中断函数------------------------------------------*
//功 能:当开关状态发生变化时,小灯的状态随之变化 *
//-------------------------------------------------------------------------*
__interrupt 8 void ISR_TimerChan0(void)
{
DISABLE_INTERRUPTS; //关总中断
LEDDrive(); //驱动小灯亮暗
TFLG1 |= (1<<C0F); //清除输入捕捉标志位
ENABLE_INTERRUPTS; //开总中断
}
完整程序请见网络光盘“………./第五章样例程序/ 05_InputCapture”

6.3.6 脉冲累加功能
1. 脉冲累加概述
脉冲累加主要用于小车速度的实时速度的读取,进而更准确的控制车的速度。
脉冲累加器用来对对应通道上的有效沿进行计数,脉冲累加器有两种工作模式:脉冲累加
锁存模式和脉冲累加队列模式。脉冲累加器的输入通道上的有效沿也有两种形式:用于事件计
数方式的极性沿和用于门控时间累加方式的脉冲。在事件计数方式下,输入引脚上每产生一个
有效沿跳变就会使得脉冲累加器计数器的值加 1。在门控时间累加方式下,输入引脚上的有效
电平将会触发脉冲累加器对 64 分频后的时钟进行计数。
在使用脉冲累加器之前,要先对其进行初始化,脉冲累加器的初始化过程为:
(1)设置单独使用脉冲累加器的条件;
(2)设置脉冲累加方式;
(3)选择脉冲累加器计数器加 1 操作的触发条件,是上升沿触发脉冲累加器计数器加 1,还
是下降沿或是两种沿跳变(上升沿和下降沿)触发脉冲累加器计数器加 1;
(4)设置中断条件;
(5)启用脉冲累加器;
在初始化脉冲累加器之后,如果允许中断的话,就要编写相应的中断处理函数。

2. 样例程序
1) 脉冲累加头文件 PA.h
//脉冲累加寄存器及标志位定义
#define IOS7 7 //通道 7 选择位
#define OM7 7 //输出模式选择位
#define OL7 6 //输出电平选择位
#define OC7M7 7 //输出比较通道 7 屏蔽位
#define PAEN 6 //脉冲累加器 A 使能位
#define PAMOD 5 //计数方式选择位
#define PEDGE 4 //有效沿选择位
#define PAOVF 1 //脉冲累加器计数器溢出标志位
#define PAIF 0 //脉冲累加器捕获到有效沿时的中断标志位

66
#define PAI 0 //脉冲累加器输入引脚有效沿允许位
#define PAOVI 1 //脉冲累加器计数器溢出中断允许位
//串行通信相关函数声明
void PAInit(void); //脉冲累加器 A 初始化子程序

2) 脉冲累加子函数 PA.c
//PAInit:脉冲累加器初始化函数----------------------------------------------*
//功 能:初始化脉冲累加器 *
//参 数:无 *
//返 回:无 *
//-------------------------------------------------------------------------*
void PAInit(void)
{
DISABLE_INTERRUPTS; //禁止中断
TIOS |= (1<<IOS7); //单独使用16位脉冲累加器
OC7M &= ~(1<<OC7M7); //注意此时必须令IOS7=1,OC7M7=0,OM7=0,OL7=0
TCTL1 &= ~(1<<OM7);
TCTL1 &= ~(1<<OL7);
PACTL &= ~(1<<PAMOD); //事件计数方式
PACTL |= (1<<PEDGE); //PT7引脚上的出现上升沿时脉冲累加器计数器加1
PACTL |= (1<<PAOVI); //允许脉冲累加器产生溢出时引发中断
PACTL |= (1<<PAI); //允许PT7引脚上出现上升沿时引发中断
PACTL |= (1<<PAEN); //启动脉冲累加器A
PACN32 = 0x0000;
ENABLE_INTERRUPTS; //开中断
}
3) 脉冲累加测试主函数 main.c
//-------------------------------------------------------------------------*
//硬件连接:LED正极过一个510欧姆电阻接5V,负极接PTT7并过一个按键开关接地 *
//程序描述:按键开关被按下后,MCU向PC机发送当前的按键次数 *

//主函数
int main()
{
DISABLE_INTERRUPTS; //禁止总中断
//1. 芯片初始化
MCUInit();
//2. 模块初始化
SCIInit(); //串行通信初始化
PAInit(); //调脉冲累加器初始化
//3. 内存初始化
//全局变量赋值
g_Count=0;
//4. 开放总中断
ENABLE_INTERRUPTS;
while(1)
{
//等待有效沿跳变捕捉中断,将计数值发送给PC机
SCISend1(g_Count >> 8);
SCISend1(g_Count);
Delay(1000); //延时
}

67
}
完整程序请见网络光盘“………./第五章样例程序/ 06_PulseAccumulate”

6.3.7 PWM功能
1. PWM概述
PWM 主要用于电机和舵机的控制,即电机转动速度和舵机旋转角度的控制。
脉宽调制器(Pulse Width Modulator,PWM)是嵌入式应用系统常用功能之一。PWM 产生
一个在高电平和低电平之间重复交替的输出信号,这个信号被称为 PWM 信号,也叫脉宽调制
波。通过指定所需的时钟周期和占空比来控制高电平和低电平的持续时间。通常定义占空比为
信号处于高电平的时间(或时钟周期数)占整个信号周期的百分比,方波的占空比是 50%。脉冲
宽度是指脉冲处于高电平的时间。图 5-1 给出了几个不同占空比的示意图。图 5-1 给出 PWM
信号的周期是 8 个时钟周期 TPWM=8TCLK,图 6-16 (a)中,PWM 的高电平为 2 TCLK,所以
占空比=2 /8=25%,图 6-16 (b)、6-16 (c)可以类似计算。

图6-16 PWM的周期与占空比

PWM 的可以控制输入到某个设备的平均电流或电压。例如,一个直流电机在输入电压时
会转动,而转速与平均输入电压的大小成正比。假设每分钟转速(rpm)=输入电压的 100 倍,如
果转速要达到 125rpm,则需要 1.25V 的平均输入电压;如果转速要达到 250rpm,则需要 2.50V
的平均输入电压。在图 6-16 中,如果逻辑 1 是 5V,逻辑 0 是 0V,则(a)的平均电压是 1.25V,
(b)的平均电压是 2.5V,(c)的平均电压是 3.75V。可见,利用 PWM,可以设置适当的占空比值
来得到所需的平均电压,如果所设置的周期足够小,电机就可以平稳运转(即不会明显感觉到
电机在加速或减速)。

2. 样例程序
1) PWM 头文件 PWM.h
void PWMInit(INT8U channel,INT8U polarity,INT8U align); //PWM 初始化函数声明
void PWMSetting(INT8U channel,INT8U period,INT8U duty); //PWM 周期、占空比设置
函数

68
2) PWM 子函数 PWM.c
//PWMInit:PWM初始化--------------------------------------------------------*
//功 能:PWM初始化,A,B时钟频率均设为8MHz *
//参 数: *
// channel-通道号,polarity-极性,align-对齐方式, *
// polarity:0-负极性,1-正极性,align:0-左对齐,1-中心对齐 *
//返 回:无 *
//-------------------------------------------------------------------------*
void PWMInit(INT8U channel,INT8U polarity,INT8U align)
{
INT8U i,j;
//1 禁止通道channel
j = 0x01;
for (i=0; i<channel; i++) //禁止通道channel
j = j<<1;
PWME &= ~j;
//2 PWM时钟源选择,选择X时钟作为channel的时钟源
j = 0x01;
for (i=0; i<channel; i++)
j = j<<1;
PWMCLK &= ~j;
//3 设置A,B的时钟频率
switch (channel)
{
//通道0,1,4,5使用A时钟,A时钟频率=19.6608MHz/128
case 0:
case 1:
case 4:
case 5:
PWMPRCLK |= 0x07;
break;
//通道2,3,6,7使用B时钟,B时钟频率=19.6608MHz/128
case 2:
case 3:
case 6:
case 7:
PWMPRCLK |= 0x70;
break;
default:
break;
}
//4 确定channel输出极性
j = 0x01;
if (polarity == 1) //正极性
{
for (i=0; i<channel; i++)
j = j<<1;
PWMPOL |= j;
}
else
{ //负极性
for (i=0; i<channel; i++)
j = j<<1;
PWMPOL &= ~j;
}

69
//5 确定channel输出方式
j = 0x01;
if (align == 0) //左对齐
{
for (i=0; i<channel; i++)
j = j<<1;
PWMCAE &= ~j;
}
else //中心对齐
{
for (i=0; i<channel; i++)
j = j<<1;
PWMCAE |= j;
}
//6 清0通道channel计数器
PWMCNT0 = 0;
}

//PWMSetting:PWM周期和占空比设置-------------------------------------------*
//功 能:根据参数设置f周期和占空比 *
//参 数: *
// period=PWM周期所占用的时钟周期个数 *
// duty=PWM占空比所占用的时钟周期个数 *
// Channel=所要设置的通道号(0~7) *
//返 回:无 *
//说 明:duty的值<=period的值,并且两者的值都在0~255之间 *
//-------------------------------------------------------------------------*
void PWMSetting(INT8U channel,INT8U period,INT8U duty)
{
switch(channel)
{
case 0:
PWMCNT0 = 0x00; //清通道0计数器
PWMDTY0 = duty; //设置周期寄存器
PWMPER0 = period; //设置占空比寄存器
break;
case 1:
PWMCNT1 = 0x00; //清通道1计数器
PWMDTY1 = duty; //设置周期寄存器
PWMPER1 = period; //设置占空比寄存器
break;
case 2:
PWMCNT2 = 0x00; //清通道2计数器
PWMDTY2 = duty; //设置周期寄存器
PWMPER2 = period; //设置占空比寄存器
break;
case 3:
PWMCNT3 = 0x00; //清通道3计数器
PWMDTY3 = duty; //设置周期寄存器
PWMPER3 = period; //设置占空比寄存器
break;
case 6:
PWMCNT6 = 0x00; //清通道6计数器
PWMDTY6 = duty; //设置周期寄存器
PWMPER6 = period; //设置占空比寄存器

70
break;
case 7:
PWMCNT7 = 0x00; //清通道7计数器
PWMDTY7 = duty; //设置周期寄存器
PWMPER7 = period; //设置占空比寄存器
break;
default:
break;
}
}

3) PWM 测试主函数 main.c


//-------------------------------------------------------------------------*
//硬件连接:PTP.0,即定时器1通道0(4脚)接指示灯或蜂鸣器 *
//程序描述:通过对PWM占空比的调节实现现指示灯的渐亮的功能当占空比为100%时 *
// 再从0%逐渐增加 *
//-------------------------------------------------------------------------*
//头文件
#include "Includes.h" //总头文件

int main(void)
{

INT8U period,duty;
INT8S inc;

DISABLE_INTERRUPTS; //关总中断
//1.芯片初始化
MCUInit();
//2.模块初始化
PWMInit(0,1,0); //初始化PWM的0通道,正极性,左对齐
//3.内存初始化
period = 0xFF;
duty = 0x00;
inc = -1;

//主循环
while(1)
{
if (duty==period || duty==0)
inc = -(inc);
duty += inc;
PWMSetting(0,period,duty);
PWME |= 0x01; //允许通道0
Delay(5500); //延时
}
}
完整程序请见网络光盘“………./第五章样例程序/ 07_PWM”

71
第七章 软件设计的常用算法

7.1 黑线提取算法
目标指引线(即赛道上的黑线)宽度相对整个赛道较窄,因此只要提取目标指引线的某些
特征点,就能反映出指引线的形状。可以取每列的中间点或边缘点作为该列的特征点。在下面
的黑线提取算法中,二值化算法采用的是中间点作为特征点,直接边缘检测法和跟踪边缘检测
法采用的是边缘点作为特征点。

7.1.1 二值化算法
算法的思路是:设定一个阈值 valve(例如 45),对于视频信号矩阵中每一行,从左至右
比较各像素值和阈值的大小。 若像素值大于等于阈值, 则判定该像素对应的是白色赛道;反之,
则判定对应的是目标指引线。记下第一次和最后一次出现像素值小于阈值时的像素点的列号,
算出两者的平均值,以此作为该行上目标指引线的位置。
算法流程图如图 7-1 所示:

图7-1 二值化算法流程图

该算法的思想简单,具体实现时还可以一旦检测到左边缘后就退出该行扫描,这样上面的
流程图将变得更加简洁。但是这种提取算法鲁棒性较差,当拍摄图像中只有目标指引线一条黑

72
线时,还能准确提取出目标指引线,但当光强有大幅度的变化,或图像中出现其它黑色图像的
干扰时,该算法提取的位置就有可能与目标指引线的实际位置偏离较大。

7.1.2 直接边缘检测算法
算法的思路是:设定一个阈值(例如 15),对于视频信号矩阵中每一行,从左至右求出相
邻两像素值的差值(左减右) 。若差值大于等于阈值,则判定下一个的像素点对应的是目标指
引线的左边缘,以此像点作为该列的特征点,记录下此像素点的列号,作为该行上目标指引线
的位置。当然,可能出现差值始终小于阈值的情况,此时一种方法是令该行上目标指引线位置
为 0,通过进一步滤波或拟合来修正;另一种方法是让该行上目标指引线位置和通过上一场视
频数据求得的位置一样。
直接边缘检测算法的程序流程图如图 7-2 所示。

图7-2 直接边缘检测算法

该算法较二值化方法而言,抗环境光强变化干扰的能力更强,同时还能削弱或消
除垂直交叉黑色指引线的干扰。因为该算法在视频信号矩阵中是由左至右来寻找目标
指引线的左边缘的,所以当黑色图像出现在目标指引线左方时,该算法无法排除干扰,
而当其出现在右方时,则可以排除干扰。

7.1.3 跟踪边缘算法
这种算法跟上一小节介绍的直接边缘检测算法一样,也是寻找出目标指引线的左边缘,仍
然用左边缘的位置代表目标指引线的位置。但跟踪边缘检测从视频信号矩阵每行中寻找左边缘
的方法与上一小节介绍的不同。因为目标指引线是连续曲线,所以相邻两行的左边缘点比较靠
近。跟踪边缘检测正是利用了这一特性,对直接边缘检测进行了简化。其思路是:若已寻找到
某行的左边缘,则下一次就在上一个左边缘附近进行搜寻

73
在首行边缘检测正确的前提下,该算法具有较强的抗干扰性,能更有效地消除垂直交叉黑
色指引线的干扰,以及指引线外黑色图像的影响,始终跟踪目标指引线。另外,较之前两种算
法,跟踪边缘检测算法的时间复杂度更低,因此效率更高。但值得注意的是第一行的左边缘位
置对整个目标指引线的搜寻影响很大,一旦它的位置和实际导引线偏差较大,就会产生一连串
的错误,这是不可容忍的。

7.2 车体控制算法
7.2.1 PID算法
PID 控制是工程实际中应用最为广泛的调节器控制规律。问世至今 70 年多年来,它以其
结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。单位反馈的 PID
控制原理框图如图 7-3 所示。

图7-3 PID控制原理框图
e 代表理想输入与实际输出的误差,这个误差信号被送到控制器,控制器计算出误差信号
的积分值和微分值,并将它们与原误差信号进行线性组合,得到输出量 u。

其中, Kp,Ki,Kd 分别称为比例系数、积分系数、微分系数。u 接着被送到了执行机构,


这样就获得了新的输出信号 Y。这个新的输出信号被再次送到感应器以发现新的误差信号,这
个过程就这样周而复始地进行。运用 PID 控制的关键是调整三个比例系数,即参数整定。PID
控制器参数整定的方法很多,概括起来有两大类:一是理论计算整定法。它主要是依据系统的
数学模型,经过理论计算确定控制器参数。二是工程整定方法,它主要依赖工程经验,直接在
控制系统的试验中进行,且方法简单、易于掌握,在工程实际中被广泛采用。
一般来说,增大比例系数能够减小上升时间,并减小稳态误差,但不能消除。增大积分系
数能够消除稳态误差,但会使瞬时响应变差。增大微分系数能够增强系统的稳定特性,减小超
调,并且改善瞬时响应。

7.2.2 模糊控制算法
模糊控制是指模糊理论在控制技术上的应用。它用语言变量代替数学变量或两者结合应用;
用模糊条件语句来刻画变量间的函数关系;用模糊算法来刻画复杂关系,是具有模拟人类学习
和自适应能力的控制系统。因为小车本身由于重量、机械结构的偏差导致在建立车体的数学模
型时有很大的困难,S12 大部分系列自带了模糊控制指令,很可惜 XS 系列未带模糊控制指令。
要使用模糊控制算法,只能使用高级语言来实现。
模糊控制器的结构如图 7-4 所示:

74
图7-4 模糊控制器结构图
处理模糊运算分为三个阶段:
(1)首先根据隶属度函数将过程变量变成模糊输入,这部分工作在模糊化接口中完成,
然后将结果放入存储器;
(2)推理运算部分根据规则库和模糊运算输入得到模糊输出,也放入存储器;
(3)解模糊部分通过隶属度函数及相关规则将模糊输出变成控制输出,送往执行机构。
在计算曲率时取了三个有效点,如图 7-5:

图7-5 计算曲率的有效点
曲率计算示意图
定义曲率
CURVE= (X1−X2)−(X2−X3)
= X1+X3-2*X2
式中的 X1,X2,X3 定义见上图
计算出来的曲率值恒为正,因为有专门的程序判别是左弯还是右弯,所以只需知道赛道的
弯曲程度就可以了。
将 CURVE 模糊化,模糊子集定义为:
CURVE={零,极小,小,大,非常大}
注:如果为零,表示曲率半径无穷大,该赛道为直道。
将 CURVE 的语言变量定义为:
Z= 零
VS = 极小
S= 小
B= 大
VB = 极大
将 CURVE 量化为 7 个等级,分别为 0,1,2,3,4,5,6
那么 CURVE 的论域为:CURVE={0,1,2,3,4,5,6}

75
根据调试小车在弯道上的表现给出 CURVE 量的隶属度表:

表 7-1 CURVE 量的隶属度表


量化等级
0 1 2 3 4 5 6
语言变量
零 1 0.5 0 0 0 0 0
极小 0 1 0.5 0 0 0 0
小 0 0 1 0.5 0 0 0
大 0 0 0 0.5 1 0.5 0
极大 0 0 0 0 0 0.5 1

由表 7-1 得到 CURVE 的隶属度函数,见图 7-6:

图7-6 CURVE 的隶属度函数


对于 KP 值同样进行模糊化,模糊子集定义为:
Kp = {零,极小,小,大}
将 Kp 的语言变量定义为:
Z= 零
VS = 极小
S= 小
B= 大
然后建立模糊控制规则表,如下表:

表 7-2 模糊控制规则表
CURVE Z VS S B VB
KP Z VS S B B

76
第八章 赛车设计样例

前面几章通过介绍在智能车软硬件构造的子模块,以及底层基本模块子程序,已经了解了
智能车制作的基本知识。本章则是参赛选手灵感的发挥,充分利用这些知识,开始动手从基本
的零件和元器件,搭建自己的第一辆智能车。

8.1 硬件组装
硬件组装的目的就是尽最大智慧搭建出巧妙而又性能优越的智能车模型。比赛通常分为光
电组和摄像头组,因此车型也分为两种。图 8-1,图 8-2 为两种不同的车型。

图8-1 光电车模

图8-2 摄像头车模
两种车型的主要区别在于采集部分的模块不同。
光电组一般采用若干红外二极管或者激光

77
管组成。而摄像头组则选用 CCD 或者 CMOS 摄像头采集赛道的图像信息。
共同部分除了整体车模外, 还有采集速度的编码器,主控制器电路板以及电机驱动电路板,
这些基本的硬件模块在前面的章节中也都有介绍。

8.1.1 车模各部件的安装
车模的机械部分是影响其行驶性能最直接的部分,其重要性不言而喻。一个不良的机械系
统会增加控制的难度,会为车模的速度提升带来障碍。因此,车模的机械性能应该是优先考虑
的问题。
参考第三章在新购置车模的基础上安装所需的各个部件。

8.1.2 电路板的设计及安装
车模部件安装好之后,则整个小车的结构就基本出来了。下面进入到电路板的设计步骤。
电路板一般是按照车模空间要求来设计,可以充分利用车模上的剩余空间,设计成不同形
状的电路板,为了便于电路板各个模块的独立以及更新换代,可以将电路控制部分分成若干个
分立的电路板。
电路板设计并制作完成之后,则经过细致的焊接过程制成具有控制作用的电路板。焊接结
束后,则需要马上进行测试工作。通过调用前面提供的基本模块程序进行测试。
同时,安装电路板时需要考虑车模部件以及驱动的散热问题。
以上各个模块都安装好之后,整个小车硬件就算组装完成了。

8.2 软件设计
有了稳定的硬件条件,小车仍然还不具备“生命力”,还需要复杂的控制软件来赋予小车
真正的“智能”。万丈高楼平地起。无论多么快速的车模都是由前面的介绍的各个软件模块搭
建成。具备这些软件模块则编写出有效地车模控制代码显得比较容易了。本节以光电组设计为
例,介绍智能车的软件设计架构。

8.2.1 软件流程介绍
前面的章节中给出了芯片资源子模块的程序,已经完成了小车硬件最底层的驱动程序,本
章则在此基础上进行进一步的封装成帧对外部模块的功能性程序, 并通过调用这些功能性程序
实现控制小车的目的。
为了便于软件的编写、修改、调试,在软件设计中一定要采用层次化,模块化和参数化设
计规范。从而不管在程序的调试还是参数的调试都能做到效率的最大化。
智能车软件流程图如图 8-3。整体软件架构由两条主线组成:主循环和中断处理程序。

1. 主程序
主程序中完成系统处理一切工作流程,如图 8-3 所示。

78
图8-3 程序处理流程图
在主程序中,
(1)对系统硬件和系统各个变量进行初始化;
(2)先关总中断,设置 MCU 工作频率和各个外设的状态,初始化各个端口的功能;
(3)然后进行控制算法以及相关参量初始化,开放总中断;
(4)最后程序进入主循环的控制周期中;
(5)在主循环中首先进行赛道检测,并分析出赛道当前情况,判断当前小车与赛道的偏
差;
(6)如果判断到是起跑线路段,则根据是否跑完全程路段来决定是否停车(视比赛规则
而定);
(7)如果不是起跑线,则判断当前赛道线路的位置和上一次相差很小,则可保持上一次
的输出决策量;否则则进入下一步;
(8)通过控制算法,常见如 PID 控制,或者模糊控制算法等;
(9)根据算法处理计算出的决策值输出到执行机构,完成一个周期的控制,小车进入到
下一个循环周期。
在制定的控制器上可通过超频,以获得较高的芯片工作频率,从而获得快速的决策和控制
周期。

2. 中断处理程序
除了主程序时钟在运行外,同时运行的中断接收模块,实时的检测时候有软硬件触发的中
断。
本系统中只有两个中断处理子程序,即串口接收中断服务子程序和定时器服务子程序。使
用串口模块,可以自定义命令协议,有助于整个系统的调试,通过串口接收中断服务子程序处
理 PC 机向 MCU 发送的调试命令或控制命令。定时器服务子程序中完成需要周期性完成的事
情。

79
主程序和中断处理程序之间的共享信息通过全局变量进行传递,以达到很好的实时性控制。

8.2.2 软件复用模块
将第六章介绍的基础模块再次封装成供控制算法调用的驱动方法。
按照涉及到的控制模块
文件列表及功能性控制方法声明如下(详细实例代码见附录):

表 8-1 控制模块功能性文件列表
程序名称 基本功能
Sensor.h,Sensor.c 初始化光电传感器端口的函数以及获取光电传感器采集量的方法
SCI.h,SCI.c 串口初始化以及串口通信的各种方法
MotorSub.h,MotorSub.c 电机和舵机控制端口初始化以及电机和舵机决策量控制的函数。
Timer.h,Timer.c 定时器模块处理方法

// GetSensorData:获取光电传感器输入量-----------------------------------------*
//功 能:检测光电器照射在赛道上的反馈信息,并根据此判断赛道 *
// 的信息以及小车与赛道的偏角。 *
//参 数:无 *
//返 回:传感器返回量 *
//----------------------------------------------------------------------------*
INT16U GetSensorData();

//MotorInit:舵机和电机初始化-------------------------------------------------*
//功 能:舵机和电机初始化,舵机回到平衡位置,电机停止转动 *
//参 数:无 *
//返 回:无 *
//---------------------------------------------------------------------------*
void MotorInit(void);

//DMotorRun:驱动电机按照指定的速度转动---------------------------------------*
//功 能:驱动电机按照指定的速度转动 *
//参 数:vect-定义电机的 100 个档位(0~99) *
// 1~50 为前进档,依次增速;51~99 为后退档,依次增速;0 为空挡 *
//返 回:无 *
//---------------------------------------------------------------------------*
void DMotorRun(INT8U vect);

//DMotorStart:电机开始转动---------------------------------------------------*
//功 能:驱动电机开始转动 *
//参 数:无 *
//返 回:无 *
//----------------------------------------------- -----------------------*
void DMotorStart(void);

80
//DMotorStop:电机停止转动----------------------------------------------------*
//功 能:驱动电机停止转动 *
//参 数:无 *
//返 回:无 *
//--------------------------------------------------------------------------*
void DMotorStop(void);

//SMotorTurn:舵机按照指定的 PWM 值转动-----------------------------------------*


//功 能:驱动舵机按照指定的 PWM 值转动 *
//参 数:value-舵机转动的 PWM 值 *
//返 回:无 *
//------------------------------------- --------------------------------------*
void SMotorTurn(INT16U value);
至此,通过调用以上功能性的函数可以编写沿着赛道稳定行进的控制程序(见附录) 。然
后要求取得较好的驱动效果,还需要采用稍微复杂的驱动控制算法来实现。
在实际竞赛中,由于赛道具有较高的复杂度,因此需要采用一些控制算法以便达到很到的
效果。根据比赛中常见的大小 S 赛道,发夹弯,C 型弯,交叉路以及起始线判断等复杂问题,
制定不同的决策。
经过实验得知,当智能车在直道行走的时候,可以给最高速度;当智能车在弯道出直道时,
速度相对高速;当智能车直道入弯的时候,速度突然减下来;当智能车在弯道时,相对低速。

附件:能够遵循黑线缓慢并稳定前进的控制程序见网上光盘。

81
第九章 调试及常见问题分析

9.1 光电组赛车调试及常见问题分析
静态测试:主要测试软件功能,电路中的供电电路、速度控制电路、传感器是否正常、信
号是否有返回
动态测试:智能车在赛道上运行,调整适当的控制参数或控制算法

9.1.1. 传感器
(1)传感器 LED 不亮
从硬件电路方面考虑:用万用表笔进行检查,是否出现短路及断路现象,传感器两端是否
存在电压;从软件电路方面考虑:控制电路信号错误或者没有给到传感器的电路板上,可以用
示波器检查控制信号是否正确。
(2)传感器输出信号不正确
普通的光电传感器有三条线,正极负极和信号线,所以要确保信号线与单片机管脚连接正
确;还有一种可能输出信号是正确的,对返回信号程序处理上出现错误,其现象同传感器输出
信号不正确是一样的。
(3)传感器无信号返回
保证传感器信号线与单片机管脚之间通路;利用示波器检查传感器在照射在黑色与白色赛
道板时信号线产生的信号,如果还是没有信号产生,需要检查传感器电路及传感器是否被烧坏
或损坏。
(4)传感器光斑较大
采用普通的光电传感器普遍存在光斑较大的问题,可以通过给 LED 部分套上热缩管,使光
斑集中在直径 5mm 范围内。
(5)传感器受其他传感器干扰
可以采用分时点亮并且只在点亮时读取返回信号,这样可以避免相邻传感器间产生的干扰;
当然缩小光斑也可以减少干扰的可能性;也可以采取对接收部分进行遮光。
(6)传感器接收距离过短
可以增加传感器的光强或是在传感器接收部分增加透镜;增加传感器光强可以通过电路和
控制信号实现,也可以通过缩小光斑集中 LED 的光源,经过实践发现控制电路是解决此类问题
的关键。

9.1.2. 舵机
(1)舵机不转
检查舵机正负极是否有电压,不过发生这种情况可能性较小,一般是舵机的频率设置出现
问题,单片机发出的 PWM 波占空比不符合舵机的控制脉冲,最好先通过示波器观察实际脉冲周
期,防止损坏舵机。
(2)舵机不按传感器状态转动
出现此种现象主要检查两个方面,首先保证传感
器返回值一定准确,通过示波器或万用表检查传感器返回的高低电平是否准确,当确定返
回值正确时依次找出舵机的中值和左右最大转角时的极值,然后将舵机控制与传感器状态结合

82
起来。
(3)舵机抖动
舵机频繁抖动,可能因为供电不足,更换电池后看情况是否有好转;当然舵机的控制脉冲
不符合舵机要求的脉冲周期也会发生这种情况,检查 PWM 输出波形。
(4)舵机顺逆时针转动角度不对称
主要是因为舵机中值不适当,应该准确计算中值时脉冲周期,保证顺逆时针转动的角度基
本相等。机械方面考虑,舵机的安装方式会使左右极值不同,如果舵机采用对称式安装,左右
两个连杆长度应基本相等。
(5)舵机转动时齿轮啮合声音过大
保证舵机控制脉冲周期在 5ms--20ms 之间,如果周期和占空比都没有问题,舵机仍旧有很
大的齿轮啮合声音,需要打开舵机外壳确保舵机内齿轮没有出现打齿现象,也可以上些舵机专
用机油缓解此种现象。
(6)行驶中舵机出现异常抖动
出现这类现象可能是因为瞬间电流过大,使舵机瞬间分到的电流变小,会异常的摆正或打
偏,但此类现象多发生在激光传感器的小车上,所以主板电路的供电部分也十分重要。
(7)舵机中值不固定
刚开始调试小车时总会碰到舵机中值发生变化的现象,避免这种现象一般从两方面入手:
在舵机的安装上,确保连接件的紧密配合;在算法处理上,程序的编写也会影响到舵机中值。
(8)舵机没有转矩
舵机正常工作时会有转矩输出,转动时会有齿轮啮合的声响;当舵机没有转矩输出时,舵
机基本已经损坏。

9.1.3. 主板
(1)传感器及舵机和电机不能协同工作
保证各部分供电充足,不会因电压不稳造成传感器与其他部分产生干涉;在此基础上,如
果不存在供电问题,需要检查程序,可以先保证两部分的协同工作,通过调试保证整车各部分
的协同工作。
(2)单片机发热
必须及时关掉电源,检查单片机的正负极及主板电路的线路是否正常,主板电路中是否有
短路等现象;保证主板背面的绝缘,避免因意外的短路对单片机造成烧损。
(3)不能下载程序
保证 CodeWarrior 安装正确,程序编译没有错误,但有时也会因为电脑状态的原因,需要
多尝试几次;当然仿真器 BDM 没有连接好或 BDM 出现问题也会造成程序的不能下载。

9.1.4. 电机部分(后桥)
(1)后桥声音较大
电机的主输出轴要与后轮的驱动齿轮配合良好,防止齿轮配合过松或打齿现象发生;产
生不正常的声音还有可能是因为电机的控制周期不合适,导致电机转动不正常。
(2)带负载时电机不能转动
空载时电机可以工作,当把小车放在跑道上时不能前进,有可能是电池电量不足,可尝试
更换电池;也可能是驱动电路提供的电流不够,需要检查电机驱动电路。

83
9.1.5. 码盘(测速装置)
(1)无返回信号
若是自制码盘,编写输入捕获或输出比较程序是否正确。其次通过对射原理制作的码盘,
需检查码盘孔是否安装准确,使传感器能构接受正常,可通过示波器检查是否有信号产生。
(2)自制码盘信号幅值不够大
需要注意上拉电阻问题。在买回的传感器中,有些并没有上拉电阻,这样信号就不会到达
正常的伏值,并应考虑发射管和接受管的安装距离及安装位置问题。

9.2 摄像头组赛车调试及常见问题分析
赛车在硬件完全安装好,软件部分的底层程序完成之后,就应该能够差不多在赛道上“跑”
了。当然,这所谓的跑“跑”只是可能能在赛道上晃晃悠悠地前进而已,要想赛车能够在赛道
上飞驰,还要进行程序的调试。因为各个赛车上的机械结构部件和电气元件是不可能完全一致
的,而这种不一致就需要程序去适应,去适应出一套适合这辆赛车的程序。还有,由于在写程
序底层的时候,难免会出这样那样的漏洞,因此还要针对不同的问题进行解决。尤其是 CCD
赛车,CCD 摄像头采到图像的好坏就直接关系到赛车后续算法的实现,进而影响整体赛车状态。
好图像就是王道!除此之外,一辆赛车能在一个赛道上跑出好成绩,换了另外一个赛道未必就
能够完成比赛,因此,还需要把赛车对不同赛道进行测试,然后把不同的参数比较分析,进行
适当的折中,让赛车在各种赛道上都能跑出理想的成绩,这样才算是一辆不错的赛车。等等一
系列问题,在完成前期的硬件安装和底层程序编写之后,需要对赛车进行调试。
赛车的调试手段有很多种,简单归类成两种:一是让赛车在赛道上跑,凭借肉眼观察出问
题然后进行更改, 二是通过无线通信把赛车的状态信息发送到上位机上然后根据这些参数进行
调整。一般肉眼观察只能得到赛车大概情况,而细微的东西只有发送到上位机上才能够进行分
析。在这向大家介绍上位机调试赛车的方法。

9.2.1 上位机程序的制作
所谓上位机就是指平时使用的 PC 机。赛车的状态信息由单片机收集后通过无线工具发送
到上位机,由上位机接收后进行简单的处理,再通过数字或图形的方式显示出来。

图9-1
上位机软件可以使用 VC、VB、LabView 等工具编写。大家可以根据自己的实际情况选择,
在这里主要以 VC 为例进行说明。
上位机程序可以分为两个主要模块组成:通信模块和显示模块。

1.通信模块
大家知道,与小车通信主要是通过串口来完成的。由单片机通过自己的 SCI 模块把数据按
照一定的格式发送到无线设备,再由无线设备转发到上位机的串口进行接收。这里使用的是无
线设备不涉及任何复杂的协议,只需简单的数据从单片机发出,在上位机就能够接收了。

84
在 VC 里,可以使用 MSCOMM 来进行串口的通信。
MSComm 作为一个串行通讯控件为程序员串口通讯编程节省了很多时间。在基于对话框的
应用中加入一个 MSComm 控件非常简单。只需进行以下操作即可:

图9-2
打 开 “ 工 程 -> 增 加 到 工 程 ->Components and Controls->Registered Activex
Controls”,然后选择控件:Microsoft Communication Control,version 6.0 插入到当前的
工程中。这样就将类 CMSComm 的相关文件 mscomm.cpp 和 mscomm.h 一并加入到了工程中。
编程时只需将控件对话中的 MSComm 控件拖至你的应用对话框中就 OK 了。
MSComm 控件提供了两种处理通信的方法,事件驱动方式和查询方式。这里用的是事件驱
动方式。所用的事件驱动方式的基本原理就是当接收缓冲区内的有字符时,就触发事件对接收
到的字符进行处理。
此外,使用 MSComm 控件还需设置几个很多重要的属性,
//************初始化串口***********//
m_Port.SetCommPort(1); //设置串口编号,电脑自带的串口一般为 1,使用 USB
转串口工具的一般根据不同的 USB 口变化
m_Port.SetInBufferSize(4096); //设置接受区缓存大小
m_Port.SetOutBufferSize(1024); //设置发送区缓存大小
if(!m_Port.GetPortOpen())
m_Port.SetPortOpen(TRUE); //打开串口
m_Port.SetInputMode(1); //用二进制接受数据
m_Port.SetSettings("115200,n,8,1");//设置波特率,奇偶校验,数据位,停止位
m_Port.SetRThreshold(1); //接受区有数据时触发一次 oncomm 时间
m_Port.SetInputLen(0); //接受缓冲区所有数据
然后,可以设置一个数组或者链表把缓冲区内的数据读出来,再把数据进行处理。
当然,在读数据的过程中,还需要确认数据包。所谓确认数据包就是必须知道单片机发上
来的哪个数据是对应哪个参数的。一般来说在发数据时,都要把数据按一定的格式来发,然后
再在这些数据的首末分别加上帧头和帧尾,这样就比较方便把数据提取出来。

2.数据显示
在把数据提取出来后,就要进行相应的处理然后把数据通过数字方式或者图形方式显示出
来。在这里可以分为两种情况。
1)显示赛车状态信息
小车的状态信息可以直接按照约定好的格式(这里可以称为协议)抽取出来,然后逐个使
用文本框或者图表进行显示。

85
使用文本框进行显示比较简单,熟悉 VC 编程的人都知道。但是文本框显示只能显示一个
时刻的状态值,而这里一般需要观察的是小车连续状态的变化,比如说整个运行过程中的舵机
转角变化,这时最好就是使用图表进行显示了。
图表的绘制使用的是 CPen 类。关于 CPen 的用法也并不复杂,一般有关 VC 的书都有具体
讲解。
2)显示 CCD 赛道图像
赛道图像是 CCD 赛车最为关心的问题,好图像是 CCD 赛车的成功因素。因此,有必要知道
赛车在跑的过程中看到了什么东西。 当然,可以直接通过电视机接收摄像头传回来的模拟信号,
而且这也是调车的一个很重要手段,后边会有介绍。但是,由于单片机所处理的图像是经过数
字化的,所以和用电视机看到的模拟信号会由很大的差距,因此有必要把单片机所采集的图像
传到上位机上进行研究。

图9-3 CCD上位机软件界面
这里讲的赛道显示主要是针对 AD 转换的图像的,AD 转换后的图像就是把实际的像素点挨
个进行数字化得来的。因此当用单片机把这些图像发送给上位机后,上位机只需要按照采集的
方法和扫描顺序把像素点挨个按 AD 的转换值存储在一个二元数组里,然后挨个赋值给画笔,
显示相应的颜色在屏幕上即可。除此之外,还可以用上位机模拟单片机把 AD 的图像进行二值
化在上位机上进行显示,甚至模拟单片机上的算法把黑线提取出来,这样就可以知道单片机处
理出来的黑线是不是和想要的相符了。

9.2.2 通信问题
由于小车系统要求有很高的实时性,在用单片机与上位机进行通信的时候,还必须考虑通
信时所占用单片机的时间。一般来说,处理一场图像的时间是 40 毫秒,这 40 毫秒里边有 20
毫秒是进行采集的,所以只有 20 毫秒的时间来进行图像的处理运算、控制运算以及与上位机
通信。一般单片机处理图像和控制运算的时间并不会太长(除非你把算法写得十分庞大,但是

86
应该没人会这么做) ,最多 5 毫秒左右的时间,而剩下的 15 毫秒时间对于单片机的 SCI 来说是
相当短暂的。假设使用 115200 的波特率(波特率就是发送的速度,115200 代表一秒钟发送
115200 位数据),一秒钟就是能发 14400 个数据,15 毫秒就相当于能发送 200 个左右的数据,
而一幅图像一般都是由上千个像素点构成的,所以一场的时间是不足以把正常图像全发到上位
机上的。因此,可以考虑隔行发送隔点发送等等手段,因为观察时并不是每个像素点都需要考
虑到,并且相邻的像素点的图像不会有太大的差异。
当然,也可以寻找更快的发送方式,比如说 SPI 等,上位机使用 USB 接收等等。

图9-4上位机显示赛道图像效果

9.2.3 摄像头调节
摄像头的调节主要考虑的是摄像头所看到的赛道的范围。摄像头相比光电传感器的最大优
势莫过于它的前瞻和可视角度了,但是由于摄像头的光学性质,摄像头也并非十分完美。
首先,考虑把摄像头往高装和往低装的问题。当摄像头越往高处装时,它的视角就越趋近
于俯视,这样的效果使得摄像头所看到的各个地方相对于摄像头的距离越均匀,失真越小。但
是随之而来的问题就是摄像头越往高处装,为了照顾靠近赛车的赛道情况就必须把摄像头角度
压低,而这样就会损失很大前瞻,摄像头赛车的优势就无法得到体现。并且最重要的问题是摄
像头装得太高会使赛车的重心太高,不利于车过弯。因为重心等问题而翻车的情景并不少见。
当摄像头越往低处装的时候,为了获得大的前瞻,摄像头的视角就趋近于平行于赛道了,
这样虽然能顾及靠近赛车的赛道又能获得大的前瞻,但是过平的视角会引入很大的干扰,特别
是反光。并且由于视角平,远处虽然能够看到,但是远处部分的行数较少,图像失真很严重,
也不利于算法识别。
因此,在摄像头的安装位置上必须很下功夫去耐心调试,适当折中。又想起那句话:好的
设计需要适当的折中。
其次,考虑镜头的问题。使用摄像头上的镜头一般都是可以进行更换的。镜头一般可以大
致分为长焦、普通和广角三种。长焦镜头可以把远处的赛道看得很清晰,但是可视范围很小,
而广角的镜头虽然能得到很大的可视范围,但是它会产生很大的失真,所以在选择镜头上也必

87
须下功夫,找到合适的镜头。鱼和熊掌终究还是不可兼得,继续折中考虑吧!
最后,在选择好安装位置和选好镜头后,就要使用电视机了。要把摄像头输出的模拟信号
直接给电视机,然后直接观察赛道,旋转镜头到合适的焦距。

9.2.4 常见问题分析
问题一:舵机不转
解决方法:
(1)首先检查 GND,VDD 是否接对;
(2)检查控制舵机的信号是否是周期为 20ms(可调)的正确的方波;
(3)如果前两项都没有问题,可以尝试换一个舵机试试。
问题二:电机疯转,不可调速
解决方法:
(1)检查控制电机的信号是否是的正确的方波;
(2)检查电机驱动电路是否工作正常。
问题三:赛车在直道上跑歪,偏离赛道
解决方法:
(1)调整舵机中值;
(2)把赛车放在一段长直道上(一定要放正) ,对照上位机的图像,调节摄像头的角度和
位置,把黑线调节到中心位置。
(3)特别注意,摄像头的安装一定要牢固。
问题四:图像质量不好,清晰度问题
解决方法:
(1)调节摄像头模拟信号数字化的阈值;
(2)调节摄像头镜头的焦距;
(3)如果前两项都不起作用,可以尝试换一个摄像头试试。
如果以上问题都完全解决, 相信你的小车已经能顺利跑起来了。至于如何让小车跑的更快、
更稳,就要发挥自己的想象力和创造力了。

9.3 其它常见问题
(1)假如小车在实验室运行正常,到了比赛场地不能正常运行怎么办?
答:有以下几种可能,第一,看小车电源是否有电,没有电的情况比较简单。如果不是电
源的问题,下一步就是检查小车机械方面,这时需要认真的检查小车的各个连接部分,以确定
是否都安装固定好。如果机械方面没有问题,就有可能是小车软件方面的问题,可以采用由简
单到复杂的方法来测试小车各个部分,如各个 IO 接口、传感器、PWM、电机、舵机等。如果
是这些问题,可以采取更换这些零部件的方法排除故障。如果都仍找不到问题,这时就要考虑
更换比赛小车。
(2)为什么在比赛中出现问题了,参赛队员要按一些键?
答:这是根据比赛场地具体环境来改变一些参数, 使得小车更能适应比赛环境取得好成绩。
(3)在参加比赛时,如果车轮打滑怎么办?
答:为了避免比赛时小车打滑,因此在适应场地的时候一定要将小车调整好。如果出现打
滑可以在比赛之前更换小车的轮胎。
(4)比赛场地的日光灯照对小车的传感器以及信号采集有没有影响,分别对光电组、电

88
磁组、摄像头组的影响呢?
答:这个对摄像头组的影响最大,因此参赛队员在适应场地时一定要将摄像头的一些参数
调整到最佳。对光电组和电磁组的影响不是很大。
(5)光电组如何选择传感器的类型,根据什么样的指标去选择这些元件?
答:1)选择传感器时要考虑功耗,理论上功耗大的红外线发射的比较远,但是这样小车
的性能得不到提高,因此要综合考虑功耗和小车性能;2)光电传感器的扫描方法,对于功耗
大的,不应当一直发射红外线,可以使用 PWM 控制,降低功耗。3)如果要提高前瞻性可以
考虑使用激光,但是这样也会增加小车的成本;4)安装时要考虑小车的前瞻性
(6)光电组、摄像头组如何提高小车的前瞻性?
答:对于光电组、应该使用功率大的;在安装这些传感器时,要跟赛道有一定的夹角;由
于光电组是实时采集赛道信息, 所以提高处理采集到的道路信息也能在一定程度上提高小车的
前瞻性。对于摄像头组,要考虑摄像头的可视范围,安装时支架可以是上下可调节的。
(7)在赛道中如何避免翻车,特别是在上坡,拐弯的时候?
答:为了避免在比赛时翻车,小车的重心在设计时要尽量低;在拐弯或者上坡这些容易翻
车的地方速度不能太高。
(8)赛道为什么用白色的地板黑色的跑道,用其他的颜色可以不可以啊?
答:对于光电组,发射出的红外光可以被白色的底板完全反射,可以被黑色的赛道完全吸
收,因此主要是为了采集信息方便准确。对于摄像头组,采集到的黑白信息容易处理、简单。
而对于其他的颜色搭配达不到用黑白组合的效果。
(9)摄像头组采集的图片是实时的还是隔一定的时间间断的采集?
答:对于摄像头组最重要的是要能够正确及时处理采集到的道路图片信息, 及时做出决策。
所采用的摄像头是 20ms 出一张图片,因此是以一定的时间间隔采集道路信息。
(10)如何提到处理采集到的信号速度?有什么方法?
答:1)可以使用优秀的算法,2)调高小车的前瞻性,让小车及早做出决策 3)还可以将
小车芯片的总线频率提到最大。
最后的最后,给大家再总结一句话:好的赛车是跑出来的。只有不断的跑(当然是在符合
硬件条件的情况下),不断的发现问题,才能不断解决问题。发现的问题越多,解决问题越多,
赛车就会跑得越稳定,当然就会跑得更快了!加油! !

89

You might also like