kl800.com省心范文网

智能车源程序+很详细


由于今年组委会光电管和摄像头分开比赛。 所以传感器部分我们选择了光电 管,比赛以小车的速度记成绩,为了让小车更快更稳得跑完全程,传感器的探 测距离必须要远,既要有大的前瞻,普通的红外对管由于功率较小,探测距离 增大时,干扰严重,所以我们自制了大功率对管,同时采用了程序控制脉冲发 光的办法,有效的降低了发热,提高了系统的稳定性。 系统采用采用了 7.2V 2000mAh Ni-Cd 蓄电池作为系统能源,并且通过稳压 电路分出 6 伏,5 伏已分别给舵机和单片机供电。 直流电机驱动模块接收速度控制信号控制驱动电机运行,达到控制车速目 的。转向伺服模块控制舵机转向,进而控制智能车转弯。速度测量模块实时测 量智能车车速,用于系统的车速闭环控制,以精确控制车速。 系统充分使用了 MC9S12DG128 单片机的外围模块,具体使用到的模块包括: ADC 模拟数字转换模块、定时器模块、PWM 脉冲宽度调制模块、中断模块、I/O 端口和实时时钟模块等。 系统调试过程中,使用了组委会提供的代码调试环境 CodeWarrior IDE,同 时使用了清华的 Plastid2 软件进行了仿真试验。

图 1.1 系统结构框图

第三届全国大学生智能汽车大赛

3.1 舵机部分
为了使转弯更加灵活, 对舵机相关部分作了部分改动。 首先, 我们将舵机力臂加长 85mm。 这样,对于同样的转弯角度值,只需更小的舵机转角,减小了舵机转弯时惯性带来的弊端。 其次,我们将舵机反装,使舵机连杆水平,因为此时舵机提供的力全部用在转弯上。

3.2 前轮部分
为了增加前轮转弯时的稳定性,对前轮相关部分进行了部分改动。首先,更改前后垫片 的数量,使前轮主销后倾,这样,车轮具有更好的自动回正功能。其次,更改连杆的长度, 使车轮外倾,车轮转弯时,前半部分重心上移,促使赛车转弯更加稳定。再次,我们通过 更改舵机连杆的长度,增加前轮前束,同样增加了前轮的稳定性。

3.3 底盘部分
为了提高赛车运行时的稳定性,对地盘相关部分作了部分改动。首先,前轮相关位置加 垫片,降低了前轮重心。其次,更改后轮车轴处的调节块,使后轮重心升高,这样,车身 前倾,一定程度上,增加了车的稳定性。

3.4 后轮部分
首先,更换后轮轮距调节块,使后轮两轮之间间距加大。这样,车在转弯时不容易产生 侧滑。其次,调节后轮差速,使赛车转弯更加灵活。

4.1 电源部分
为了能使智能车系统能正常工作,就需要对电池电压调节。其中,单片机系 统、车速传感器电路需要 5V 电压,路径识别的光电传感器和接收器电路电压工 作为 5V、伺服电机工作电压范围 4.8V 到 6V(或直接由电池提供),直流电机可 以使用 7.2V 2000mAh Ni-cd 蓄电池直接供电。考虑到由于驱动电机引起的电压 瞬间下降的现象,因此采用低压降的三端稳压器成为必然。我们在采用 lm7805, 和 lm7806 作为稳牙芯片。经试验电压纹波小,完全可以满足要求。

电池(7.2v) 2000mAh Ni-cd
1

第三届全国大学生智能汽车大赛

稳压电路 5V 6V 单片机 对管 测速板
Encoder

7.2V 舵机 电机

图 4.1 系统电压调节图

图 4.2 7805 电路图

图 4.3 电源模块示意图

2

第三届全国大学生智能汽车大赛

4.2 电机驱动电路
电机驱动使用飞思卡尔专用电机驱动芯片 MC33886。驱动电路如图 4.4 所示。 为了增大驱动能力,减少单片发热量,电路采用两片 MC33886 并联的方案。系 统使用 PWM 控制电机转速, 充分利用单片机的 PWM 模块资源。 电机 PWM 频 率设定为 8KHz。 MC33886 芯片的工作电压为 5-40V,导通电阻为 140 毫欧姆,PWM 频率小于 10KHz,具有短路保护、欠压保护、过温保护等功能。 电机驱动芯片安装在制作的电机驱动 PCB 板上,在 PCB 板设计时,考虑到芯 片散热问题,在芯片腹部设计了方型的通孔,实际运行效果表明芯片散热均匀, 设计合理。为了防止电动机突然停止时产生的电磁干扰,在电动机的两端焊接 了一个 0.1μ F 滤波电容。
R1 5 Res2 1K U3 PWM3 PWM5 3 19 13 18 20 1 9 10 11 12 IN1 IN2 D2 D1 DN C AG ND PGN D PGN D PGN D PGN D MC3 3 8 8 6 R5 Res2 1K OU T1 OU T1 OU T2 OU T2 DN C V+ V+ V+ Ccp FS 6 7 14 15 8 4 5 16 17 2 C1 2 Cap 47pF R4 Res2 1 .3 K DS2 LED2

VCC

R1 0 +7 .2 V 1 S2 2 3 SW-SPDT Res2 1K

P1 4 2 1 Head er 2

U5 3 19 13 18 20 1 9 10 11 12 IN1 IN2 D2 D1 DN C AG ND PGN D PGN D PGN D PGN D MC3 3 8 8 6 OU T1 OU T1 OU T2 OU T2 DN C V+ V+ V+ Ccp FS 6 7 14 15 8 4 5 16 17 2 C1 4 Cap 47pF R7 Res2 1 .3 K

图 4.4 两片 MC33886 并联使用

3

第三届全国大学生智能汽车大赛

图 4.5 两片 MC33886 并联使用的实物图

在图中可以看到,我们使用 PWM23 和 PWM45 作为电机驱动 PWM 信号,两个 PWM 通道级联可以使其输出更加精确。在程序中,我们把 PWM 值直接转换成 了以米/秒为单位的绝对速度,这样使智能车的速度更加直观切易于调试。

4.3 测速电路
由于考虑到成本需要,我们采用了红外对管和黑白码盘作为测速模块的硬件构 成。其中码盘为 32 格的黑白相间圆盘,如下图所示:

图 4.5 码盘 红外传感器安装在正对码盘的前方,虽然这样做精度比编码器要低很多,但是 成本低廉制作容易,如果智能车速度较快,可以考虑再减少码盘上黑白色条的 数量即可。 当圆盘随着齿轮转动时,光电管接收到的反射光强弱交替变化,由此可以得到 一系列高低电脉冲。设置 9S12 的 ECT 模块,同时捕捉光电管输出的电脉冲的
4

第三届全国大学生智能汽车大赛

上升沿和下降沿。通过累计一定时间内的脉冲数,或者记录相邻脉冲的间隔时 间,可以得到和速度等价的参数值。 测速电路使用自行研制的红外反射式光电测速传感器。速度测量电路使用 红外反射式光电对管 RPR220,自行制作的编码盘,比较电路等组成。 速度测量电路图 2.8 所示。红外反射式光电对管的光敏三极管信号通过比 较器处理后输入单片机的计数 器模块, 利用单片机的输入捕捉 功能, 处理智能车速度信息。 自 制的编码盘有 24 道黑色条纹, 电机旋转一周将产生 24 次输入 捕捉中断。 单片机记录两次中断的时 间间隔 T。 两次中断对应于智能 车前进的距离 S 为: 16.5/24 cm, 即 0.6875cm, 其中 16.5cm 为智 能车后轮实测周长[7]。智能车实时速度 V(cm/s)的计算公式如下: S 16.5 / 24 0.6875 V? ? ? cm / s T T T
图 4.6 测速电路
300 33K RPR220 3 2 4 VCC 10K VCC 5.1K VCC 8 A 1 LM358 5.1K IOC0

4.4 红外对管检测电路
由于我们采用了大功率对管,所以红外对管的电路是整个电路中要求最高的, 不紧要保证对管正常工作,而且还要考虑整个电路的能耗和发热问题。经测试 我们发现单个对管在通以 100mA 到 170mA 电流时可以。保证抬高 20 到 30 厘 米的距离。 此时每个对管的管压降为 1.2 到 1.5 伏。为了进一步加大发光量,我们采用了双 发射管的办法,即一个接受管对应两个发射管。为了降低整体的能耗。我们让 同一对的发射管串联,14 对发射管再并联。同时使用了 irf540 进行开关控制。 控制对管脉冲发光。开关频率为 200HZ。这样既保证了大前瞻探测的需要,又 降低了整体的能耗和对电源的冲击

5

第三届全国大学生智能汽车大赛

图 4.7 先串联再并联的脉冲发光对管电路图。

图 4.8 对管实物图反面

图 4.9 对管实物图正面

4.5 拨码开关电路
由于在智能车比赛开始后,不能够对智能车硬件及软件进行修改,在保证了硬件有效可靠 的同时,软件有可能不能够适应新场地,所以设计拨码开关对智能车有关参数进行设置也 是必要的。拨码开关电路如下图所示:

6

第三届全国大学生智能汽车大赛

R1

Head er 9

1 2 3 4 5 6 7 8 9
VCC SW7 SW6 SW5 SW4 SW3 SW2 SW1 SW0 1 2 3 4 5 6 7 8 SW-D IP8 S1 16 15 14 13 12 11 10 9

图 4.9 拨码开关 这是一个八段的拨码开关,我们把它成成上下连个部分,显然,每个部分都有 16 种状态, 前四个来改变舵机参数,后四个改变直流电机参数,这样对于适应新的场地很有好处。

5.1 路径搜索算法
对于本控制系统采用 14 对光电对管的方案,单排排列在车体头部 10cm 处。 编号为 6、7 的光电对管处于正中央位置。利用 14 对传感器进行道路识别。传 感器对白色的反射率比黑色的大。单片机 ADC 读入值相应也大。在程序中对传 感器信号进行处理,判断传感器是否检测到黑色引导线。 将单个传感器对白色和黑色路面的 ADC 值之差分为平均的两段,每次处理 实时传感器信号时,判断本次采样的 ADC 值与黑色路面 ADC 值之差落在两段中 的哪一段。如果在靠近黑色的一段,则判定该传感器检测到黑线,将该传感器 对应的变量置为判定值 1; 如果在靠近白色的一段, 则判定该传感器检测到白线, 将该传感器对应的变量置为判定值 1;为了增强判断的准确性,在对 ADC 值采样 时,采用了中值滤波方法,以去除瞬间的干扰。 路径检测完后,将测的的路径值暂时存储,然后将路径信息传递给舵机和 电机控制部分,以选择给定合适的转角和速度。

7

第三届全国大学生智能汽车大赛

5.2 舵机、电机的控制
智能车的舵机和电机都采用了经典的 PID 控制方法。但是由于舵机和电机性能 的不同要求,分别对其进行了不同的修改。

PID 控制器由比例单元(P) 、积分单元(I)和微分单元(D)组成。其输入 e (t) 与输出 u (t)的关系为

式中积分的上下限分别是 0 和 t 因此它的传递函数为:G(s)=U(s)/E(s)=kp(1+1/(TI*s)+TD*s) 其中 kp 为比例系数; TI 为积分时间常数; TD 为微分时间常数 比例 KP 用来控制当前,误差值和一个负常数 P(表示比例)相乘,然后和预定 的值相加。P 只是在控制器的输出和系统的误差成比例的时候成立,KP 能够快 速的跟随变化量。及时的产生与之相关的调节作用。但是 KP 是有差调节,无法 消除静态误差。 积分 KI 来控制过去,误差值是过去一段时间的误差和,然后乘以一个负常数 I, 然后和预定值相加。I 从过去的平均误差值来找到系统的输出结果和预定值的平 均误差。一个简单的比例系统会振荡,会在预定值的附近来回变化,因为系统 无法消除多余的纠正。通过加上一个负的平均误差比例值,平均的系统误差值 就会总是减少。所以,最终这个 PID 回路系统会在预定值定下来。 微分 KD 来控制将来, 计算误差的一阶导,并和一个负常数 D 相乘,最后和预 定值相加。这个导数的控制会对系统的改变作出反应。导数的结果越大,那么 控制系统就对输出结果作出更快速的反应。这个 D 参数也是 PID 被成为可预测 的控制器的原因。 参数对减少控制器短期的改变很有帮助。 D 一些实际中的速度

8

第三届全国大学生智能汽车大赛

缓慢的系统可以不需要 D 参数。

舵机 PID
由于舵机是一个具有大的延迟的执行机构,所以在 PID 控制中不能加入积分环 节。 否则会导致小车震荡。 所以小车采用 PD 控制。 同时加入一个一阶惯性环节, 构成不完全微分,给小车一个超前的调节。 实际使用中,为了减少计算时间,将位置式 PID 转化为增量式 增量式 PID 公式:

电机 PID 控制 小车行使过程中,随着跑道的不同,需要配合不同的速度值, 因此对电机的 PID 是一个给定值不断变化的 PID。 小车的目标速度(Object_Speed)给定规则: 1》 小车在直道上,Object_Speed 为最大值 200。 2》 小车在大弯道上,Object_Speed 为 160。 3》 小车在小弯道或 S 型弯道上,Object_Speed 为 120 4》 小车冲出跑道,Object_Speed 为 70。 5》 小车由直道进入弯道,Object_Speed 逐渐减小。
9

第三届全国大学生智能汽车大赛

6》 小车由弯道进入直道,Object_Speed 逐渐加大。 在实验中发现,PID 的超调量主要在第一个波形中起作用,也即 单速度由很大到很小的时候,或由低速突然加到高速的过程中, 会出现很大的超调。但是这个超调并不是有害的,因为,当速度 要求突变的时候,往往是小车由直道入弯道,或者由弯道入直道 的过程, 这个过程往往需要很快的大加减速, 而由于小车的惯性, 一般的 PID 调节难以满足要求,这时使用大的超调量可以使小 车有一个加速或刹车的过程,使之更好的达到要求速度。
6.1 Codewarrior 开发环境
在整个开发调试过程中, 使用 Metrowerks 公司为 MC9S12 系列专门提供的全套 开发工具(Freescale Codewarrior IDE 4.6) 。这是一套用 C 语言进行编程的集成 开发环境——本文智能车定位系统的软件设计部分就是在此开发环境下完成 的。 Codewarrior 是由 Metrowerks 公司提供的专门面向 Freescale 所有 MCU 与 DSP 嵌入式应用开发的软件工具。其中包括集成开发环境 IDE、处理器专家、全芯片 仿真、可视化参数显示工具、项目工程管理、C 交叉编译器、汇编器、链接器 以及调试器。 CodeWarriorIDE 能够自动地检查代码中的明显错误,它通过一个集成的调试器 和编辑器来扫描你的代码,以找到并减少明显的错误,然后编译并链接程序以 便计算机能够理解并执行你的程序。每个应用程序都经过了使用象 CodeWorrior 这 样 的 开发工具进行编码、编 译、编辑、链接和调试的过程。Metrowerks Codewarrior IDE 中的 mc9s12dg128.h 文件对所有寄存器对应的存储映射地址都 进行了宏定义,开发者在软件开发时直接调用这些宏就可以了。

6.2 软件仿真

为了更好的定量分析影响小车行驶的各个因素, 而且最大限度的
10

第三届全国大学生智能汽车大赛

节约时间和成本。我们采用了软件仿真和实际调试相结合的办 法。仿真软件使用了清华的 PLAST2。 通过仿真,我们发现: 1、 小车传感器的探测距离对速度有着决定的影响。所以传感 器应该尽量的探测更远。但是传感器的探测距离不能超过 最小转弯的半径。否则会出现盲区。 2、 适度增加舵机的灵敏度,可以使转弯更加灵活。所以我们 在实际调试中,加长了舵机的力臂。
6.2 实际调试

实际调试过程中,我们发现小车在直道上会出现左右抖动的现 象,通过软件设置死区或其他处理方法,效果都不是很明显,最 后发现小车舵机和前轮的间隙是罪魁祸首, 通过把前轮设置为内 八形,完美的解决了这个问题。 在调试过程中,我们加了液晶显示,还设置了蜂鸣器,这些辅助 设备在比赛中为了减轻小车的重量,都是不需要的。但是在调试 过程中,通过这些设备,可以及时的了解小车运行的情况,达到 事倍功半的效果。

11

第三届全国大学生智能汽车大赛

表 7.1 模型车技术参数统计:

项目 参数 路径检测方法(赛题组)
车模几何尺寸(长、宽、高) (毫米) 车模轴距/轮距(毫米) 车模平均电流(匀速行驶)(毫安) 电路电容总量(微法) 传感器种类及个数 新增加伺服电机个数 赛道信息检测空间精度(毫米) 赛道信息检测频率(次/秒) 主要集成电路种类/数量

光电组
385*220*60 200/150 200 430 红外对管 15 个 0 9 200 9s12 单 片 机 最 小 系 统 /1

12

第三届全国大学生智能汽车大赛

33886 电机驱动电路/4 速度检测电路/1 车模重量(带有电池) (千克) 0.9

参考文献
[1] 黄开胜、金华民、蒋狄南,韩国智能模型车技术方案分析,北京:清华大 学汽车安全与节能国家重点实验室,2004.3 [2] 邵贝贝著,单片机嵌入式应用的在线开发方法,北京:清华大学出版社, 2004.2 [3] ‘LM2940 datasheet’, July 2000, National Semiconductor [4] ‘LM7806 datasheet’ National Semiconductor [5] ‘RPR220 datasheet’, ROHM [6] 'Semiconductor Technical Data MC33887' Aug 2002 Motorola Inc [7] 大赛车模拼装手册 [8] CodeWarrior IDE 3.1 help datasheet [9] 'MC9S12DG128 Device User Guide', October 2002 Motorola Inc [10] 'HCS12 CORE datasheet', Augt 2000 Motorola Inc [11] 'S12PWM8B8CV1 datasheet', Mar 2002 Motorola Inc [12] 'S12ATD10B8CV2 datasheet', Augt 2002 Motorola Inc

13

第三届全国大学生智能汽车大赛

[13] 'S12ECT16B8V1 datasheet', July 2002 Motorola Inc [14] www.smartcar.au.tsinghua.edu.cn [15] www.freescale.com.cn [16] www.21icsearch.com

程序

电机 PID 控制程序
typedef unsigned char BOOL; typedef unsigned char INT8U; typedef signed char INT8S; INT16U; INT16S; INT32U; //无符号 8 位数 //有符号 8 位数 //无符号 16 位数 //有符号 16 位数 //无符号 32 位数 //有符号 32 位数 //单精度浮点数 //双精度浮点数

typedef unsigned int typedef signed int

typedef unsigned long typedef signed typedef float typedef double

long INT32S; FP32; FP64;

14

第三届全国大学生智能汽车大赛

#define MAX_32 (signed #define MIN_32 (signed

long)0x7fffffffL long)0x80000000L

#define MAX_16 ( signed #define MIN_16 ( signed

int)0x7fff int)0x8000

typedef struct { signed signed signed signed signed signed signed signed signed signed int ProportionalGain; int ProportionalGainScale; int IntegralGain; int IntegralGainScale; int DerivativeGain; int DerivativeGainScale; int PositivePIDLimit; int NegativePIDLimit; int IntegralPortionK_1; int InputErrorK_1;

}sCaiXinBoPID; sCaiXinBoPID SpdPID;

extern signed int CaiXinBoPIDController( MeasuredValue,sCaiXinBoPID *pParams);

signed

int

DesiredValue,

signed

int

static signed {

long L_sub(register signed

long src_dst, register signed

long src2)

15

第三届全国大学生智能汽车大赛
return (src2-src_dst); } static signed { return (signed } long)(ssrc); long L_deposit_l(register signed int ssrc)

static {

signed

int extract_l(register signed

long lsrc)

return ( signed int)lsrc; } static signed { register signed laccum=sinp1; laccum*=sinp2; long laccum; long L_mult(register signed int sinp1, register signed int sinp2)

return laccum; } static signed long L_add(register signed { return (src_dst+src2); } long src_dst, register signed long src2)

signed int CaiXinBoPIDController( signed *pParams)

int DesiredValue, signed

int MeasuredValue,sCaiXinBoPID

16

第三届全国大学生智能汽车大赛
{ signed long ProportionalPortion, IntegralPortion, PIDoutput; signed int InputError;

/*-------------------------------------------------------------------------------------------------*/ /* Saturation mode must be set */ /* InputError = sub(DesiredValue, MeasuredValue); */ /* input error */

/*-------------------------------------------------------------------------------------------------*/ /* input error calculation - 16bit range, with and without saturation mode */

PIDoutput = L_sub(L_deposit_l(DesiredValue),L_deposit_l(MeasuredValue)); /* input error - 32bit range */ if(PIDoutput > MAX_16) InputError = MAX_16; else if(PIDoutput < MIN_16) InputError = MIN_16; else InputError = extract_l(PIDoutput); /* input error - 16bit range */ /* input error is less than 0xffff7fff = -32768 - 32bit range */ /* inpur error is greater than 0x00007fff = 32767 - 32bit range */

/* input error = max. positive 16 bit signed value */

/* input error = min. negative 16 bit signed value */

/*-------------------------------------------------------------------------------------------------*/ /* proportional portion calculation */ ProportionalPortion=L_mult((pParams ProportionalGainScale + 1); -> ProportionalGain), InputError) >> (pParams ->

/*-------------------------------------------------------------------------------------------------*/ /* integral portion calculation */ IntegralPortion=L_mult((pParams->IntegralGain), InputError) >> (pParams->IntegralGainScale + 1);

17

第三届全国大学生智能汽车大赛
/* integral portion in step k + integral portion in step k-1 */ IntegralPortion=L_add(IntegralPortion, L_deposit_l(pParams->IntegralPortionK_1));

/* integral portion limitation */ if(IntegralPortion>(pParams->PositivePIDLimit)) (pParams->IntegralPortionK_1)=(pParams->PositivePIDLimit); else if(IntegralPortion<pParams->NegativePIDLimit) pParams->IntegralPortionK_1=pParams->NegativePIDLimit; else pParams->IntegralPortionK_1=extract_l(IntegralPortion);

/*-------------------------------------------------------------------------------------------------*/ /* derivative portion calculation */ PIDoutput=L_sub(L_deposit_l(InputError),L_deposit_l(pParams->InputErrorK_1)); /* [e(k) - e(k-1)] - 32bit range */ pParams->InputErrorK_1=InputError; /* e(k-1) = e(k) */ if(PIDoutput>MAX_16) */ InputError=MAX_16; else if(PIDoutput<MIN_16) InputError=MIN_16; else InputError=extract_l(PIDoutput); /* [e(k) - e(k-1)] - 16bit range */ /* [e(k) - e(k-1)] is less than 0xffff7fff = -32768 - 32bit range */ /* [e(k) - e(k-1)] = max. positive 16 bit signed value - 16 bit range */ /* [e(k) - e(k-1)] is greater than 0x00007fff = 32767 - 32bit range

/* [e(k) - e(k-1)] = min. negative 16 bit signed value - 16 bit range */

/* drivative portion in step k - integer */ PIDoutput=L_mult((pParams->DerivativeGain),InputError)>>(pParams->DerivativeGainScale+1);

18

第三届全国大学生智能汽车大赛

/*-------------------------------------------------------------------------------------------------*/ /* controller output calculation */ PIDoutput=L_add(PIDoutput, ProportionalPortion); /* derivative portion + proportional portion */ PIDoutput=L_add(PIDoutput, L_deposit_l(pParams->IntegralPortionK_1)); /* + integral portion = controller output */

/* controller output limitation */ if(PIDoutput>pParams->PositivePIDLimit) PIDoutput=pParams->PositivePIDLimit; else if(PIDoutput<pParams->NegativePIDLimit) PIDoutput=pParams->NegativePIDLimit;、

初始化程序
void RTI_Init(void) { /* setup of the RTI interrupt frequency */ /* adjusted to get 1 millisecond (1.024 ms) with 16 MHz oscillator */ RTICTL = 0x1f;//5*2^16:48.8hz //0x1f // set RTI prescaler ::晶振 16384 分频;(低四位+1)*(2^(高三位 +9)) CRGINT = 0x80; } void SET_PLL(void) { CLKSEL=0x00; // enable RTI interrupts; //低四位:1-7,不可为零,否则分频器不工作

19

第三届全国大学生智能汽车大赛
PLLCTL=0xe1; SYNR=2; REFDV=1; PLLCTL=0x60; asm NOP; asm NOP; asm NOP; while((CRGFLG&0x08)==0); CLKSEL=0x80; } /*锁相环程序*/

void ATD_Init(void) { ATD0CTL2=0xc0;//不开中断 2; ////上电,标志位快速清零 ... 0; ATD 队列转换完成中断使能

ATD0CTL3=0x00;//sequence length:8 ATD0CTL4=0x85;

//转换队列长度 8,非 FIFO 存储模式,

//8 位精度,AD 时钟为 bus_clk/(2*(5+1))

ATD0CTL5=0x90; //右对齐,无符号数,单次转换队列模式,ch 1 begin,6 channels;多通道 8 路,从通 道 0 开始

ATD1CTL2=0xc0;//ADPU,fast flag clear ATD1CTL3=0x30;//sequence length:6,not fifo mode, ATD1CTL4=0x85;//8 bit decision,ATD clock:bus_clk/(2*(5+1)) ATD0CTL5=0x90; //右对齐,无符号数,单次转换队列模式,ch 1 begin,6 channels;多通道 8 路,从通 道 0 开始 } /*ATD 初始化程序*/

void Servo_Init(void)

//舵机 16 位 PWM 控制

20

第三届全国大学生智能汽车大赛
{ PWME_PWME1=0; PWMPRCLK|= 0x03; PWMCLK|=0x00 ; //disable PWM1 //CLKA:8 分频 //这就是默认值//通道 1 用 clock A 时钟源 //24MHZ/8=3M PWMPOL_PPOL1 = 1; //先高电平 servo

PWMCAE=0x00;

//对齐方式默认 左对齐

PWMCTL_CON01 = 1; //通道 1:16BIT 连接 PWMPER01 = 30000;//30000:10ms;;;30000//舵机的周期是 10ms //1ms 脉冲 到 2ms 脉冲 //1.5ms 脉冲对应 0 度 PWMDTY01 =4500;//4500:1.5ms; //控制 3500 左极限 5500 右极限 PWMCNT01 通道时会从此值? = 0; 4500 正中央 1/3M * x=1/100

//写计数寄存器,会使 PWMDTYx,PWMPERx 进入锁存器,同时使能

PWME_PWME1= 1; //PWM 通道 1 输出 } /*舵机初始化程序*/

void Forward_Init(void) // 假定前进方向,初始化函数 { // PWM3:IN1 // PWM5:IN2 // PWM7:EN // DDRP = 0xff; //控制输出 =1

21

第三届全国大学生智能汽车大赛
PWME_PWME3= 0; PWME_PWME5= 0; PWMPRCLK|= 0x20; //clock b 总线频率的 4 分频 //通道 3 用 clock B 时钟源 // 24MHZ/4=6M PWMPOL_PPOL5 = 0; //low electrical level first,,high mc33886 disabled electrical level first ,but high level makes

//对齐方式默认 左对齐 PWMCAE PWMCTL_CON45 = 1; //16BIT 连接 PWMPER45 PWMDTY45 PWMCNT45 = 750; //电机频率 8k Hz 1/1.5M*x=1/2KHz

= 500; // 占空比精度 1/750 = 0; //启动 PWM

PWME_PWME5 =1; }

//PWM 通道 3 输出

/*电机初始化程序*/ void ECT_Init(void) { TSCR1_TFFCA=1; TSCR2 = 0x87; TIOS_IOS0=0; //automatically clear flag //ECT 初始化,使用输入捕捉功能

//Timer Overflow interrupt open,TCNT prescaler:24MHZ/128=187.5kHz 计数频率 //The corresponding channel acts as an input capture // ON CH0 PT0;

TCTL4_EDG0A=1; TCTL4_EDG0B=0; TIE_C0I=1; TSCR1_TEN=1;

//

capture on rising edge only on channel 0

// Enable Ch1 Interrupts //ENABLE TIMER

22

第三届全国大学生智能汽车大赛
}

主程序
#include <hidef.h> /* common defines and macros */ /* derivative information */

#include <mc9s12dg128.h>

#pragma LINK_INFO DERIVATIVE "mc9s12dg128b" #include "pid.h" #include"init.h"

#define AD_LEVEL 130 #define MID 4785 750

#define MAXTURN #define DC_Limit 600 #define KP1 #define KI1 (-40) 0

#define KD1 (0) #define SPEED 70

//变量定义 int times,exit,exit1,exit_flag;//停车用变量 char zanshi=0;//调速 int Sensor=4785;//舵机 int int ave_weight[3]={0,0,0}; count0=0;

int AD_Value[14]; int i; int atd_value[14];

23

第三届全国大学生智能汽车大赛
char boma=0; int zhidao_speed=0; int wangdao_speed=0; int chongchu_speed=0;//速度设定 int cha0,cha1;//不完全微分 volatile unsigned int IC0Counter=0; volatile unsigned int IC0Counter_1=0; volatile unsigned int stop_flag=0; volatile int NowSpeed; volatile unsigned int GearWidth[4]={0} ; volatile unsigned int GearIndex=0; //2.083ms one int //拨码开关

unsigned long GearWidthSum; unsigned long AveGearWidth ; unsigned long AveSpeed ;//测速 unsigned int pulse_counter=0; //计数 int DCDuty; int Object_Speed=SPEED; int stop_stop=0xff,stop_stop1=0; /******************转弯 PID 函数********************/ int pid1(int a,int b,int c) { int x=0; x=(KP1*(a-b)+KI1*a+KD1*(a-2*b+c)); return (x); } /*********************主函数*********************/ void main(void) //100cm/s

24

第三届全国大学生智能汽车大赛
{ SpdPID.ProportionalGain=30000;//1.52 0.15 0.05 0.94 1.84 24903 SpdPID.ProportionalGainScale=13; //0.76 的系数(0-1):GainScale=14 //(0-2):gainscale=13 //(0-4) 0-8 0-16 0-32 0-64 0-128 0-256 .. //.0-32768--不能取最后的那个数,可以有小数,随 着数的增大,小数数减少,从 15 位到 0 位 //精度 1/32768----1

SpdPID.IntegralGain=25000;//20480;15000 SpdPID.IntegralGainScale=14;//14;//0.625 的系数 SpdPID.DerivativeGain=20000;// 0 SpdPID.DerivativeGainScale=14; SpdPID.PositivePIDLimit=DC_Limit; SpdPID.NegativePIDLimit=0; SpdPID.IntegralPortionK_1=0;//=0 SpdPID.InputErrorK_1=0;//=0 1.25 1.45(pian da) 0.925 0.45 0.15 0.85

RTI_Init(); SET_PLL(); ATD_Init(); Servo_Init(); Forward_Init(); ECT_Init();

DDRT=0x00; boma=PTIT;//读入拨码开关; boma>>=4;

25

第三届全国大学生智能汽车大赛
boma&=0b00001111;

zhidao_speed=90+7*boma; wangdao_speed=75+4*boma; chongchu_speed=50;//60+boma;

EnableInterrupts;

for(;;) { /////////////////////调速///////////////////// if(abs(ave_weight[2])<3) { Object_Speed=zhidao_speed; } else if(abs(ave_weight[2])<14) Object_Speed=wangdao_speed; else Object_Speed=chongchu_speed;

/////////////////////转弯///////////////////// cha1=pid1(ave_weight[2],ave_weight[1],ave_weight[0]); cha1=(cha1*100+cha0*0)/100; cha0 =cha1; Sensor=4785-38*ave_weight[2];//pid1(ave_weight[2],ave_weight[1],ave_weight[0]); if(Sensor>MID+MAXTURN) {

26

第三届全国大学生智能汽车大赛
Sensor=MID+MAXTURN; } if(Sensor<MID-MAXTURN) { Sensor=MID-MAXTURN; } PWMDTY01=Sensor;

ave_weight[0]=ave_weight[1]; ave_weight[1]=ave_weight[2]; count0=0; }

}

#pragma CODE_SEG NON_BANKED /**********************定时 1ms 中断************************/ void interrupt 7 RTI_int() { int i,j,k,l,m; static int pulse_t; CRGFLG|=0x80; pulse_t++; if(pulse_t>5) { pulse_t=0; DDRA=0xff;

27

第三届全国大学生智能汽车大赛
PORTA_BIT0=1; for(i=0;i<1500;i++); ATD0CTL5=0x90;//启动一个新的转换 ,ch0 begin ATD1CTL5=0x90; while(!(ATD0STAT0&0x80)); //等待队列转换结束

AD_Value[0]=ATD0DR0L;//ATD0DR0L; //读取相应结果寄存器值清相应转换完成通道标志 ATD0STAT1 AD_Value[1]=ATD0DR1L; AD_Value[2]=ATD0DR2L; AD_Value[3]=ATD0DR3L; AD_Value[4]=ATD0DR4L; AD_Value[5]=ATD0DR5L; AD_Value[6]=ATD0DR6L; AD_Value[7]=ATD0DR7L;

//begin ATD1,ch0 begin while(!(ATD1STAT0&0x80));//等待 ATD1 队列转换结束 AD_Value[8]=ATD1DR0L; AD_Value[9]=ATD1DR1L; AD_Value[10]=ATD1DR2L; AD_Value[11]=ATD1DR3L; AD_Value[12]=ATD1DR4L; AD_Value[13]=ATD1DR5L;//ATD1DR5L;

PORTA_BIT0=0; for(i=0;i<14;i++) {

28

第三届全国大学生智能汽车大赛
if(AD_Value[i]>AD_LEVEL) { atd_value[i]=1; count0++; } else atd_value[i]=0; } if(count0==0) { exit1=3000; ave_weight[2]=ave_weight[1]; } else if(count0>6 && count0<14) { } else { exit1=3000; //检测到的个数

ave_weight[2]=((atd_value[0]*(-13)+atd_value[1]*(-11)+atd_value[2]*(-9)+atd_value[3]*(-7)+atd_value[4]*(-5) +atd_value[5]*(-3)+atd_value[6]*(-1)+atd_value[7]*(1)+atd_value[8]*(3)+atd_value[9]*(5)+atd_value[10]*7+atd _value[11]*9+atd_value[12]*11+atd_value[13]*13)/count0); } }

for(i=0;i<3;i++){ if(atd_value[i]==1){

29

第三届全国大学生智能汽车大赛
for(j=i;j<7;j++){ if(atd_value[j]==0){ for(k=j;k<9;k++){ if(atd_value[k]==1){ for(l=k;l<12;l++){ if(atd_value[l]==0){ for(m=l;m<14;m++){ if(atd_value[m]==1){ exit_flag=1; }else exit_flag=0; } }else exit_flag=0; } }else exit_flag=0; } }else exit_flag=0; } }else exit_flag=0; } if(exit_flag==1) { exit1++; if(exit1>3003) { // // if(stop_stop<4&&stop_stop>=0) { exit++;

30

第三届全国大学生智能汽车大赛
// // } exit1=0; if(exit>2)exit=2; } } zanshi++; if(zanshi>5) { zanshi=0; DCDuty=DC_Limit-CaiXinBoPIDController(Object_Speed,(int)AveSpeed,&SpdPID);// if(DCDuty<1) if(DCDuty>DC_Limit) if (exit==2) DCDuty=0; DCDuty=DC_Limit; stop_stop=0xff;

DCDuty=1;

PWMDTY45=DCDuty; //change Motor PWM duty]

}

} /**********************定时器溢出中断*********************/ void interrupt 16 TIMER_OVERFLOW(void)//187.5khz counter freq.349.5ms overflow once { int i; i=TCNT; if(stop_flag==1) { if(exit<2)

31

第三届全国大学生智能汽车大赛
PWMDTY45=DC_Limit; } stop_flag=1;//in IC0_int ,clearing it } /**********************ECT 捕捉中断************************/ void interrupt 8 IC0_ISR(void) { // // { // // // // { // // // } stop_flag=0; IC0Counter=TC0;//获得当前 IC0 的计数值 ,clearing C0F flag pulse_counter=IC0Counter-IC0Counter_1; IC0Counter_1=IC0Counter; GearWidth[3]=pulse_counter; stop_stop=stop_stop1; stop_stop1=0; } else if(exit_flag==0) stop_stop1++; if(exit_flag==1) //when speed is 2.4m/s,15 rounds per sec,15*32=480 int per sec

for(GearIndex=0;GearIndex<4;GearIndex++) { GearWidthSum=GearWidthSum+(unsigned long)GearWidth[GearIndex]; }

32

第三届全国大学生智能汽车大赛
AveGearWidth=GearWidthSum/4; AveSpeed=93750L/AveGearWidth; NowSpeed=(int)AveSpeed; GearWidthSum=0; GearWidth[0]=GearWidth[1];; GearWidth[1]=GearWidth[2]; GearWidth[2]=GearWidth[3]; }

33


赞助商链接

基于51单片机的红外遥控智能小车源程序(C语言)

基于51单片机的红外遥控智能小车源程序(C语言)_电子/电路_工程科技_专业资料。此源程序包含红外解码程序,小车控制程序,调速测速程序等。 ...

简易智能小车_源程序

简易智能小车——2003 年全国大学生电子设计竞赛, c51 源程序 系统的单片机程序 #include "reg52.h" #define det_Dist 2.55 //单个脉冲对应的小车行走距离,其...

智能循迹小车源程序

智能循迹小车源程序_电子/电路_工程科技_专业资料。智能循迹小车的源程序 #include<reg52.h> sbit lsig=P2^4; sbit msig=P2^5; sbit rsig=P2^6; sbit ...

智能小车源代码 避障 寻迹 寻光 遥控_图文

智能小车源代码相信看到文档的朋友都想做一个智能小车,我最近也在做这个项目,并...有基础的朋友都看得懂的,在那代码 的基础上,成功地合成了一个程序。 里面...

智能小车-电机源代码

智能小车-电机源代码_信息与通信_工程科技_专业资料。智能小车-电机源代码直流...智能车源程序+很详细 34页 免费 基于单片机的多功能智能... 48页 1下载券 ...

基于51单片机的智能小车控制源代码(毕业设计)

基于51单片机的智能小车控制源代码(毕业设计)_计算机软件及应用_IT/计算机_专业资料。基于89C51单片机ide智能小车控制源代码,强大的辨识功能,简洁的算法灵活控制智能...

自动追光自动避障智能小车的源代码

自动追光自动避障智能小车的源代码_电子/电路_工程科技_专业资料。#include<reg...(2); } } } } /*** 小车避障程序 ***/ // 标志值 障碍物 避障方案...

成功实现手机蓝牙控制智能小车机器人!视频+程序源代码(...

成功实现手机蓝牙控制智能小车机器人!视频+程序源代码(Android) - 上次成功实现了通过笔记本电脑蓝牙来控制智能小车机器人的运动, 但是通过电脑控制毕竟 不方便,于是...

飞思卡尔智能车 智能车源代码光电组(有注解)

飞思卡尔智能车 智能车源代码光电组(有注解)_工学_高等教育_教育专区。飞思卡尔...学做智能车,挑战飞思卡尔... 58页 免费 智能车源程序+很详细 34页 免费©...

arduino循迹小车源程序

arduino循迹小车源程序_电子/电路_工程科技_专业资料。arduino,循迹小车,避障小车,测试技术,程序 int led1=0,led2=0,led3=0,led4=0,led5=0,led6=0,led7...