智能小车.docx

上传人:b****8 文档编号:28330674 上传时间:2023-07-10 格式:DOCX 页数:52 大小:358.04KB
下载 相关 举报
智能小车.docx_第1页
第1页 / 共52页
智能小车.docx_第2页
第2页 / 共52页
智能小车.docx_第3页
第3页 / 共52页
智能小车.docx_第4页
第4页 / 共52页
智能小车.docx_第5页
第5页 / 共52页
点击查看更多>>
下载资源
资源描述

智能小车.docx

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

智能小车.docx

智能小车

摘要:

本设计以AT89S52单片机为小车的主控芯片,用步进电机作为小车的动力机构,由下位机AT89S52单片机直接控制,用LN298驱动步进步进电机,双机之间采用异步并行通信。

利用超声波检测前方障碍物,并用舵机控制超声波检测方位,红外接近开关探测路面状况。

LCD18624液晶用于显示小车运行状态。

传感器,单片机,步进电机构成一个闭环控制系统,让小车实现自动壁障、避悬功能。

1.1系统方案

根据设计目的整个系统由:

障碍物检测模块即超声波与舵机模块,路面检测模块即红外模块,显示模块,主控器模块,步进电机模块组成。

其中电机模块由包括下位机主控器模块,电机驱动模块及电机组成。

(逻辑电路模块)

图1.1.1小车基本模块方框图

1.1.1超声波模块

选用集成的超声波测距模块,测距范围为3cm-300cm,图1..1.2为超声波控制时序图,先将TRIG引脚送一个10us高电平,然后在接收端口产生一个脉冲,脉冲的宽度即为超声波放送至返回的时间s1,所测距离为

(m)。

本设计中将控制信号发射口接在上位机P1^7,返回信号接收口接在上位机的P1^6端口。

图1.1.2超声波时序图

1.1.2舵机模块

为了能使超声波测距能在前180度范围内测距,选用舵机作为其支架。

本设计采用MG996全金属数字舵机,经测试该舵机实际可调范围约为120度,由于单片机资源速度有限,很难让小车在行进中对前方180度范围内不断扫描并且处理数据,所以在本设计中只用舵机控制三个测距方向即正前方,右前方,左前方。

控制脉冲周期为20ms,三个方向的控制脉宽分别为:

500us、1400us、2500us。

程序设计中用定时器2通过修改定时器的初值来生成控制舵机的方波,利用全局变量实现对舵机方向的实时控制。

1.1.3红外模块

红外模块主要功能是检测路面的平坦状况,只需进行定性测量,故在本设计中采用红外接近开关,实测该模块的最小探测距离为10cm,当探测到距离大于10cm是输出信号端输出TTL高电平。

由于车体速度慢,对实时性要求不高,为了提高人的可控性即软件的可控制性,不直接将输出信号送往硬件逻辑电路,而是让单片机对该信号端口不断扫描,然后将扫描到的数据处理后在送往硬件逻辑电路。

1.1.4显示模块

由于上位机需要不断地处理传感的数据,所以在此设计中不宜采用动态显示模块,选有LCD1624液晶显示模块不需要主控器CPU实时控制,并且显示信息量大,虽然该模块需要占据单片机很多IO口,但采用口线分时利用的方法可以解决模块间口线共用冲突问题。

1.1.5逻辑电路模块

由于52单片机只有两个外部中断源,而传感器有多个,因此利用逻辑电路进行中断资源的扩展。

图1.1.3为逻辑电路图。

图中A1-A2为传感器信号输入端口,即中断信号申请接口,B1-B2为单片机扫描端口。

INT0为上位机外部中断0的端口。

由于车体反应速度远小于传感器的反应速度,加之每次车体位置的调整

 

图1.1.3外部中断扩展逻辑电路

不可能百分之百到位,传感器信号需要不断申请中断,所以上位机的中断触发方式设置为低电平有效,故上述的逻辑电路设计为四输入或非逻辑结构,只要输入端有一个高电平输出的即为低电平。

由于中断后单片机需要扫描中断申请信号,为了避免单片机本身IO口电平对A1—A2信号的干扰,A1-A2的信号只能单向传递给单片机,所以在A1-A4端口到B1-B4的端口用非门作为信号的缓冲级,起到信号的单向传递作用(手头无光耦原器件数量有限只能如此了)。

1.1.6步进电机及驱动模块

为了提高小车方向的可控性,选用42BYGH801-11六线两相混合式步进电机。

该电机静力矩3800CM.N,定位力矩220G.N。

相电阻30Ω额定,相电流0.4A。

整步步距角1.8度。

电机工作时采用整步双拍工作方式,两个电机正常工作时需提供的额定电流:

,由于电流很大选用LN298驱动芯片。

图1.1.4为驱动电路图。

图中左端为控制信号输入端口,右端接步进电机,由于步进电机需要不断的启停,所以在输入信号端接入4N25光耦器件,进行信号隔离避免电机对下位机造成影响。

 

图1.1.4LN298步进电机驱动

1.1.6主控器模块

图1.1.5双机主控器电路图

图1.1.5为双机主控器电路,图中左端为上位机,右端为控制电机的下位机。

双机之间采用异步并行通信方式。

上位机P2^1-P2^7口接下位机P0^1-P0^7端口。

上位机WR端口接下位机INT0断口用于中断申请通信,上位机RD端口接下位机TO端口,由于检测下位机是否将上一个指令执行完,T0为1是表示下位机还在执行上位机传给他的指令。

(传感器速度远高于小车的反应速度)

1.2控制流程

1.2.1系统控制流程

图1.2.1系统控制流程图

1.1.2避障路径选择

图1.2.2避障路径选择

1.2.2软件控制流程

图1.2.2上位机主程序流成图

图1.2.3上位机外部中断0程序流程图

图1.2.4下位机主程序

图1.2.5下位机外部中断0服务程序流程图

/******************************************************/

/************************2010-10-25********************/

/*************************TLZ团队**********************/

/**************下位机之步进电机控制程序****************/

/*高四位控制步进电机1即左轮,低四位控制电机2即右轮***/

/*规定:

代码0x99-0x33-0x66-0xcc为正转方向,*********/

/*代码0x99-0xcc-0x66-0x33为反转方向,*********/

/*电机型号--35BGY401-01运行方式--两相四拍运行********/

/*******************************************************/

#include

#include

#defineuintunsignedint

#defineucharunsignedchar

/**************前进后退转向函数(8种)********************/

/***********电机转过的角度=uint*90度(待定)***********/

//voidadvance(uint);//前进

//voidfall_back(uint);//后退

//voidturn_right0(uint);//以轮轴为中心原地右转弯,电机1,2相反运行

//voidturn_right1(uint);//以右轮为中心向右转弯,左电机运行,右电机停止(左轮前进)

//voidturn_back_left2(uint);//以右轮为中心向右左转弯,左电机运行,右电机停止(左轮后退)

//voidturn_left0(uint);//以轮轴为中心原地左转弯,电机1,2相反运行

//voidturn_left1(uint);//以左轮为中心向左转弯,右电机运行,左电机停止(右轮前进)

//voidturn_back_right2(uint);//以左轮为中心向右转弯,右电机运行,左电机停止(右轮后退)

/*******************延时函数***************************/

voiddelaytime(void);

voiddelaytime1(void);

voiddelaytime2(void);

/******************全局变量*****************************/

ucharturn=0x33;

uchartemp=0xcc;//中断中的变量,设为全局变量,减少执行中断程序时从进入中断到扫描端口所需的时间

uintg=0x00;

uchartemp1;

uchartemp2;

ucharflag1;

ucharnu=0;

/********************************************************/

sbitRII=P2^7;//红外信号输入端口

sbitLII=P2^6;

sbitOUTR=P2^5;

sbitOUTL=P2^4;//红外信号中转口OUTROUTL分别接上位机P0^0P0^10.

/****@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@******************/

/***************子函数定义******************************/

/****@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@******************/

/************可重入函数********/

/*一个脉冲电机转动1.8度,车轮前进(后退)0.1025cm/

/************前进*************/

voidadvance(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<2;d++)//两个电机同步反转一圈

{P1=0x99;

delaytime();

P1=0x33;

delaytime();

P1=0x66;

delaytime();

P1=0xcc;

delaytime();

//P1=0x99;

//delaytime();//内层循环2次车轮前进1cm2*5*0.1025=1cm(此两行会造成电机抖动,注意循环,0x99后面又是代码0x99,电机会有停滞不能流畅的运行)

}

}

//P1=0x00;//每次执行完后电机断电但车体有惯性

}

/*************后退*********************/

voidfall_back(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<2;d++)//两个电机同步反转一圈

{P1=0x99;

delaytime();

P1=0xcc;

delaytime();

P1=0x66;

delaytime();

P1=0x33;

delaytime();

//P1=0x99;

//delaytime();//内层循环一次车轮后退1cm

}

}

//P1=0x00;

}

/**************原地右转**************/

voidturn_right0(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)//近似估算,外层循环一次车体转向10度

{for(d=0;d<3;d++)//左电机前进,有电机后退循环三次车轮理论滚过的距离1.5cm(启动时可能有失步打滑的问题,需要一定融冗余度,以便减小失步误差(超调量))

{P1=0x99;

delaytime();

P1=0x3c;

delaytime();

P1=0x66;

delaytime();

P1=0xc3;

delaytime();

//P1=0x99;

//delaytime();//车体转向10度,车轮需前进(后退1.57cm)

}

}

//P1=0x00;

}

/*************右转1*****************/

voidturn_right1(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<5;d++)//实测修正值内层循环4次最佳

{P1=0x90;//近似估算,车体转向10度,车轮需滚动3.12cm

delaytime();

P1=0x30;//左电机前进,右电机停止

delaytime();

P1=0x60;

delaytime();

P1=0xc0;

delaytime();

//P1=0x90;

//delaytime();//五个脉冲等效距离为0.5cm

}

}

//P1=0x00;

}

/*************右转2*******************/

voidturn_back_right2(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<6;d++)//与右转2算法相同,电机工作方式不同10度

{P1=0x09;

delaytime();/左电机停止,右电机后退

P1=0x0c;

delaytime();

P1=0x06;

delaytime();

P1=0x03;

delaytime();

//P1=0x09;

//delaytime();

}

}

//P1=0x00;

}

/**************原地左转***************/

voidturn_left0(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)//(原地右转相同)

{for(d=0;d<3;d++)//左电机后退,右电机前进

{P1=0x99;

delaytime();

P1=0xc3;

delaytime();

P1=0x66;

delaytime();

P1=0x3c;

delaytime();

//P1=0x99;

//delaytime();

}

}

//P1=0x00;

}

/*************左转1********************/

voidturn_left1(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<5;d++)//左电机停止,右电机前进

{P1=0x09;

delaytime();

P1=0x03;

delaytime();

P1=0x06;

delaytime();

P1=0x0c;

delaytime();

//P1=0x09;

//delaytime();//左转10度

}

}

//P1=0x00;

}

/************左转2******************/

voidturn_back_left2(uintk)//reentrant

{uintnu=0;

uintd;

for(nu=k;nu>0;nu--)

{for(d=0;d<6;d++)//左电机后退,右电机停止

{P1=0x90;

delaytime();

P1=0xc0;

delaytime();

P1=0x60;

delaytime();

P1=0x30;

delaytime();

//P1=0x90;

//delaytime();

}

}

//P1=0x00;

}

/***********延时子函数********************/

voiddelaytime()

{uinti,j;

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

for(j=50;j>0;j--);

}

voiddelaytime1()

{uinti,j;

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

for(j=50;j>0;j--);

}

voiddelaytime2()//能将delaytime定义为可重入函数么?

{uinti,j;

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

for(j=50;j>0;j--);

}

/************************************************/

/*****************主函数*************************/

voidmain()

{//delaytime1();

T0=1;//树立忙的标志,系统初始化后方可接受指令P3^4口

EA=1;

INT0=1;//中断请求信号初始化

IT0=0;//中断信号低电平有效

P1=0xff;

P0=0xff;//先拉高并行通信端口(上位机P2口,本机下位机P0

RII=1;

LII=1;

OUTR=1;

OUTL=1;//红外数据中转端口初始化

ET0=1;

PT0=1;

TH0=0x00;

TL0=0x00;

TMOD=0x01;//定时器0防止通信时下位机进入死循环(没有接受到如没有接受到0xee通信起始信号)

flag1=0;

while(P0!

=0xaa);/上电后等待上位机0xaa开始信号协议的来只有接收到0xaa后下位机在开始工作

EX0=1;//开分中断,允许通信

T0=0;//系统初始化完成,

while

(1)//一直前进,等待中断(遇到障碍物)

{P1=0x99;

delaytime2();

P1=0x33;

delaytime2();

/*RII=1;//红外接近开关数据中转

LII=1;

temp1=RII;

temp2=LII;

OUTR=temp1;

OUTL=temp2;//为减少此处对步进电机的影响此处执行要短*/

P1=0x66;

delaytime2();

P1=0xcc;

delaytime2();

//如果在此处调用advance这个函数,中断函数可能还要调用此函数,形成有递归调用,如要保持相关参数不变,advance需要定义为reentrant重入函数,问题定义为重入函数后,若中断中调用此函数就会一直调用次函数?

}

/*{advance(40);

delaytime1();

fall_back(40);

delaytime1();

turn_right0(24);

delaytime1();

turn_right1(24);

delaytime1();

turn_back_right2(13);

delaytime1();

turn_left0(13);

delaytime1();

turn_left1(24);

delaytime1();

turn_back_left2(24);

delaytime1();}

//P1=0x11;

while

(1);*/

}

/**********************中断服务程序******************/

/**转向通信协议(P0端口)

/*00000001-0x01:

后退10cm

00000010-0x02:

后退20cm

00000011-0x03;后退50cm

00000100-0x04:

后退100cm

10000001-0x11:

前进10cm

10000010-0x12:

前进20cm

10000011-0x13:

前进50cm

10000100-0x14:

前进100cm

10100001-0xA0;原地右转10度

10100010-0xA1;原地右转30度

10100011-0xA3;原地右转90度

10100100-0xA4;原地右转180度

10110000-0xB0;向右转10度(以右轮为中心转向,左轮前进)

10110001-0xB1;向右转30度

10110010-0xB2;向右转90度

10110011-0xB3;向右转180度(U型转弯)

11000000-0xC0;后右转10度(与左轮为中心,右轮后撤)

11000001-0xC1;后右转30度

11000010-0xC2;后右转90度

11000011-0xC3;后右转180度

11010000-0xD0;原地左转10度

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

当前位置:首页 > 总结汇报 > 学习总结

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

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