智能车课程设计.docx

上传人:b****6 文档编号:8624657 上传时间:2023-02-01 格式:DOCX 页数:14 大小:285.04KB
下载 相关 举报
智能车课程设计.docx_第1页
第1页 / 共14页
智能车课程设计.docx_第2页
第2页 / 共14页
智能车课程设计.docx_第3页
第3页 / 共14页
智能车课程设计.docx_第4页
第4页 / 共14页
智能车课程设计.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

智能车课程设计.docx

《智能车课程设计.docx》由会员分享,可在线阅读,更多相关《智能车课程设计.docx(14页珍藏版)》请在冰豆网上搜索。

智能车课程设计.docx

智能车课程设计

二○一四~二○一五学年第一学期

信息科学与工程学院

技术报告书

 

课程名称:

智能汽车设计与实践

班级:

自动化1204班

学号:

20129157043

姓名:

田野

指导教师:

章政   

二○一四年十二月

 

对红外寻迹型智能汽车

1、制作技术的整体方案

智能汽车竞赛是在规定的模型汽车平台上,使用STC12微控制器作为核心控制模块,通过增加红外传感器、电机驱动电路以及编写相应软件,制作一个能够自主识别道路的模型汽车,按照规定路线行进,以完成时间最短者为优胜。

制作智能汽车所涉及的专业知识包括控制、模式识别、传感技术、汽车电子、电气、计算机、机械等多个学科。

所有电路进行模块化分为:

电源接口模块,传感器模块,测速模块,电机驱动模块,数据传输与上位机模块等。

然后通过接口连接在一起,实现工作稳定的智能车硬件电路。

通过使用传感器,编码电机,无线模块,稳压管等作为重要的任务器件。

实现了赛道识别,速度测控,赛车数据传输,电源稳压,速度控制等功能。

相关知识:

1.单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,

2.舵机内部结构

–舵盘、齿轮组、位置反馈电位计、直流电机、控制电路板,等。

•工作原理

–脉宽信号给定参考位置,舵机内部电路通过反馈控制调节舵盘角位。

–舵盘角位由PWM控制信号的脉宽决定。

•三线连接方式

–红线:

电源线+6V–蓝线:

地线

–黑线:

PWM控制信号

3.红外传感器

光电传感器一般有两个部分组成:

发射管和接收管。

发射管发射光线,光线经过赛道的反射,由接收管接受,用过不同的光强接收管的状态不同,实施赛道信息的采集,应为白色和黑色对于光线反射的系数不同,放射会傀儡的光线的强度不一样,被不同的接收单元接收后表现出不同的反应状态(电阻的变化,电流电压的变化等)

2、设计思路

1.硬件设计部分

A.单片机及其接口

B.传感器

C.红外管比较器

D.L298电机驱动

E.电源开关

F.单片机、红外管、舵机模块供电

2.软件设计部分

//晶振12MHz1T模式总线频率12MHz,一个指令1/12us

#include"STC12C5A60S2.H"//STC12C5A60S2的头文件

#defineucharunsignedchar//宏定义

#defineuintunsignedint

#defineT0_HIGH0xff//T0计时器寄存器初值

#defineT0_LOW0x7d//溢出计数120个,120*(1/12)定时周期10us

//为了保证主程序正常运行,定时器计数最好不要小于80

#defineMOTOR_MAX_PWM_COUNT100//PWM计数器最大值10us*100=1ms,1000Hz

#defineSERVO_MAX_PWM_COUNT2000//10us*2000=20ms,50HZ//舵机控制高电平0.5~2.5ms对应PWM的50~250

//舵机控制频率在50~100Hz之间,这里选50Hz

#defineMOTOR_MAX_PWM100//电机PWM最大最小值

#defineMOTOR_MIN_PWM50//

#defineSERVO_LEFT_MAX_PWM90//min90//舵机左打最大角度时的PWM

#defineSERVO_RIGHT_MAX_PWM150//max150//这个值需要自己根据舵机实际角

度调试

#defineSERVO_MID_PWM120//舵机中心值

//注意,舵机打角过大会打在底盘上,请立即断电,以免

损害舵机

#defineERROR_HISTORY_NUM3

//#defineTHRESHOLD170//区分红外管状态的阀值,红外管的AD值小于这个值时

为白,大于为黑

//具体情况需要根据电路确定

//阀值大小可用万用表测出红外管电压的最大和最小值后

确定

//阀值`相当于比较电压

sbitLEFT_MOTOR_PWM_PORT=P3^7;//电机PWM控制端口

sbitRIGHT_MOTOR_PWM_PORT=P3^6;

sbitSERVO_PWM_PORT=P3^5;//舵机PWM控制端

//--------------------------

bitcontrol_period_finished=0;//控制周期结束标志位,控制周期选择20ms

//也可自己确定控制周期,但是要保证主程序在控制周

期内可以运行完

charmotor_PWM_counter=0;//生成电机PWM的计数器

charleft_motor_PWM=0;//左右电机的PWM占空比//由于数值在128以内,所以定义为char

charright_motor_PWM=0;

intservo_PWM_counter=0;//生成舵机PWM的计数器

intservo_PWM=0;//舵机PWM//超过char型变量的范围

inttemp=0;

interror=0;//本次偏差

interror_array[3];

interror_history[ERROR_HISTORY_NUM-1]={0};

intservo_P=50;

intservo_I=10;

intservo_D=40;

intPID_out=0;//PID输出

intP2H=0;

intlasterror=0;//历史偏差

intpreverror=0;

charspeed_expect=70;//给定速度

charspeed_counter=0;

//-----------------------------------------------------------------------

voidsys_init(void)//系统初始化

{

//------IO口设置------------

P0M1=0x00;//推挽输出

P0M0=0x00;

P0=0xff;

P1M1=0x00;//准双向口

P1M0=0x00;

P1=0xff;//初始化为高电平

P2M1=0x00;//指示灯,设置为输出

P2M0=0x00;

P2=0xff;

P3M1=0x04;//模拟PWM,设置为输出

P3M0=0xfb;

P3=0x00;

LEFT_MOTOR_PWM_PORT=0;//PWM口设为低电平,电机不转

RIGHT_MOTOR_PWM_PORT=0;

left_motor_PWM=0;//占空比设置为0

right_motor_PWM=0;

servo_PWM=SERVO_MID_PWM;//舵机打角到中心

//------定时器设置------------

AUXR=AUXR|0x80;//定时器0不分频

TMOD=0x11;//定时器方式1

TH0=T0_HIGH;//定时器赋初值

TL0=T0_LOW;

TR0=1;//定时器运行

ET0=1;//开定时器中断

IT0=1;

EX0=1;

EA=1;//开总中断

}

//-----------------------------------------------------------------------

intABS(inti)//绝对值函数

{

if(i>=0)returni;

elsereturn-i;

}

//-----------------------------------------------------------------------

voiddelay(unsignedinti)//延时函数

{

unsignedcharj;

for(;i>0;i--)

for(j=0;j<250;j++);

}

//------------------------------------------------------------------------

intjudge_sign(inta)//判断误差误差绝对值大于1位正

{

if(error<=-16||error>=16)

a=1;

elseif(error<-12||error>=12)

a=-1;

else

a=0;

returna;

}

//-----------------------------------------------------------------------

voidget_black_position(void)//寻找黑线位置

{

P2H=P0&0xc0;

P2H=P2H<<2;

P2H=P2H+P2;

switch(P2H&0x3ff)

{

case0x001:

error=26;break;//0000000000010x001//右

case0x003:

error=24;break;//0000000000110x003

case0x002:

error=21;break;//0000000000100x002

case0x006:

error=18;break;//0000000001100x006

case0x004:

error=15;break;//0000000001000x004

case0x00c:

error=12;break;//0000000011000x00c

case0x008:

error=10;break;//0000000010000x008

case0x018:

error=7;break;//0000000110000x018

case0x010:

error=5;break;//0000000100000x010

case0x030:

error=3;break;//0000001100000x030

case0x020:

error=0;break;//0000001000000x020//中

case0x060:

error=-3;break;//0000011000000x060

case0x040:

error=-7;break;//0000010000000x040

case0x0c0:

error=-10;break;//0000110000000x0c0

case0x080:

error=-14;break;//0000100000000x080

case0x180:

error=-18;break;//0001100000000x180

case0x100:

error=-21;break;//0001000000000x100

case0x300:

error=-24;break;//0011000000000x300

case0x200:

error=-26;break;//0010000000000x200//左

case0x000:

error=lasterror;break;//0000000000x000

default:

error=lasterror;break;//其他情况时,保持上一次偏差

}

}

//-----------------------------------------------------------------------

voidservo_control(void)//舵机控制

{

chari=0;

if(ABS(error-lasterror)>200)//如果两次的偏差过大,则保持上一次的偏差

error=lasterror;//防止不确定情况(如红外管冲出跑道)造成的偏差跳变

//根据偏差计算舵机角度输出

PID_out=(servo_P*error//比例

+servo_I*lasterror//积分

+servo_D*preverror)/100//微分

;//这里使用乘以一个大的系数再除以一个数的方法

//将小数计算转换成整数计算,如*0.1可转换为*10/100。

以减轻单片机的负担

servo_PWM=SERVO_MID_PWM+PID_out;//控制舵机

if(servo_PWM

servo_PWM=SERVO_LEFT_MAX_PWM;//防止舵机超过极限值

if(servo_PWM>SERVO_RIGHT_MAX_PWM)

servo_PWM=SERVO_RIGHT_MAX_PWM;

preverror=lasterror;

lasterror=error;

error_array[0]=error;

for(i=2;i>0;i--)

{

error_array[i]=error_array[i-1];

}

}

//-----------------------------------------------------------------------

voidmotor_control(void)//电机控制

{

intstate=0;

inti;

for(i=0;i<3;i++)

{

state=state+judge_sign(error_array[i]);

}

switch(state)

{

case0:

speed_expect=70;break;

case3:

speed_expect=35;break;

case-3:

speed_expect=35;break;

default:

break;

};

left_motor_PWM=speed_expect+PID_out;//速度控制

right_motor_PWM=speed_expect-PID_out;//可以直接给定,也可以根据赛道情况计算得出

if(left_motor_PWM>MOTOR_MAX_PWM)//限幅

left_motor_PWM=MOTOR_MAX_PWM;

if(left_motor_PWM

left_motor_PWM=MOTOR_MIN_PWM;

if(right_motor_PWM>MOTOR_MAX_PWM)

right_motor_PWM=MOTOR_MAX_PWM;

if(right_motor_PWM

right_motor_PWM=MOTOR_MIN_PWM;

}

//-----------------------------------------------------------------------

voidmain(void)

{

sys_init();//初始化;

while

(1)

{

KeyScan();

get_black_position();//判断黑线位置

servo_control();//控制舵机

motor_control();//控制电机

LCD_write_int(65,4,speed_counter);

while(control_period_finished==0);//等待控制周期20ms到达,保证每次控制的时间间隔都相同

{

control_period_finished=0;//标志位清零

//temp=temp++;

//if(temp>100)

//speed_counter=0;

}

}

}

//-----------------------------------------------------------------------

voidTIME_BASE(void)interrupt1using1//定时器生成PWM//不清楚的可以参考PWM的定义

{

TH0=T0_HIGH;//赋初值

TL0=T0_LOW;

motor_PWM_counter++;//计数器+1,每+1表示10us

servo_PWM_counter++;

if(motor_PWM_counter>MOTOR_MAX_PWM_COUNT)//PWM比较、生成

{

motor_PWM_counter=1;//从1开始计数

}

if(servo_PWM_counter>SERVO_MAX_PWM_COUNT)//PWM比较、生成

{

servo_PWM_counter=1;//从1开始计数

control_period_finished=1;//20ms控制周期到达,标志位置1,这里借用了舵机控制周期20ms(50Hz),

//如果更改主程序控制周期,可定义一个类似于servo_PWM_counter的计数器计时

}

if(left_motor_PWM>=motor_PWM_counter)//左右PWM

LEFT_MOTOR_PWM_PORT=1;//端口输出高电平

else

LEFT_MOTOR_PWM_PORT=0;//端口输出低电平

if(right_motor_PWM>=motor_PWM_counter)

RIGHT_MOTOR_PWM_PORT=1;

else

RIGHT_MOTOR_PWM_PORT=0;

if(servo_PWM>=servo_PWM_counter)//舵机PWM

SERVO_PWM_PORT=1;

else

SERVO_PWM_PORT=0;

}

voidexint()interrupt0

{

EX0=0;

speed_counter++;

EX0=1;

}

三、问题与调试

最初部分是焊接原件,通过比照电路图说明,将各个原件焊接上去,这是考验的我们的焊板子的能力,自动化的学生必然会遇到很多焊接的问题。

而红外探测的时候则是看着pcb原理图焊接的,自己设计联系最终做成的稳定的w行探测电路。

将原始程序修改一部分之后烧到单片机中,发现舵机无法自动对中,经过老师的测试后发现是舵机问题,舵机坏掉了,更换舵机后再次进行调中,这次总算成功了。

接着是上调经跑道的测试,程序中比较重要的两个参数是PID和error,P是比例,error为偏差,error乘以一个参数是舵机调整的角度,先在固定跑道上测试红外灯、传感器以及舵机的转向,发现舵机始终不能在中线上,就讲error=0的从五六号灯改到七号灯,使舵机的转向正常,能辨识到中间。

随后就是修改PID,舵机转向过于灵敏,此时就将P值改小,而用参数D提高响应做一个辅助作用。

此时却发现一侧电机会时不时的在摩擦力过大时停止转动,当时感觉是pwm波的最小值的问题,虽然不了解具体原因,修改最小值为50之后能就不会再出现电机停止的问题,但是再改小之后仍会发生,所以最小值只能用50。

最后,赛车可以正常的跑完室内赛道,但是冲出跑道的时候无法停止,速度闭环最终还是没有写出。

在最后的比赛时,车子由于出现问题,最后只是以很慢的速度跑完全程,留下遗憾。

4、心得体会

这次做车的过程让我了解到传感器的使用,以及舵机电机的pwm控制机理,通过编程了解我们专业的控制过程,通过算法实现对智能车的PID控制以及反馈控制,使我们的专业知识与实践充分结合,对我们以后的学习也会有更大的好处。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1