基于AT89S52单片机的巡线小车
基于AT89S52单片机的巡线小车
组员:潘伟裕、马李、梁海洋
目录
摘要 (2)
一、电路设计方案的分析 (2)
1.1电源模块 (2)
1.2红外传感模块 (3)
1.3控制模块 (4)
1.4电机驱动模块 (5)
二、硬件设计 (6)
三、程序编写·····································
四、设计失败的分析及补救方案················
五、心得体会································
摘要:
本作品以AT89S52为核心,采用红外光传感器收集信号,再经LM339处理传输,采用双电机,利用“H桥”驱动。
本次项目设计,目的是促进小组成员之间的沟通,增进小组成员之间的感情,提高动手能力。通过这次项目培训,我们的成员相互沟通交流、相互帮助学习,锻炼了我们的动手能力,促进了相互间的交流认识。
一、电路设计方案的分析
1.1电源模块
用12v电池供电,12v经“H桥”驱动电机,同时经过7805输出稳定的5v电压为红外系统、控制系统供电。电路如图(1.1):
1.2红外传感模块
本车子用5个红外传感器,每个红外发射管接1K电阻限流,接收管则串联一个6.8k电阻和一个10k可调电阻,以适应不同的光线环境(注:6.8k后改为250k,10k可调电阻失去作用)。电路如图1.2:
图1.2 红外传感电路
红外传感器由left_21、left_11、middle、right_11、right_21输出
感应信号。由于信号若直接输给单片机,单片机没法辨认,故经比较器LM339处理,再传给单片机,电路如图1.3
图1.3 LM339电路
(注:图中R1_1、R1_2、R1_3、R1_4后改为每个LM339接10k 可调电阻)图中两芯片的“in+4”脚没有用做红外信号的输入,但直接接vcc,是为了不让管脚悬空,利于芯片工作的稳定。LM339的输出管脚以被外界拉低,故接上拉电阻,再接到单片机管脚。
1.3控制模块
控制模块使用AT89S52单片机,用P2.0、P2.1、P2.2、P2.3、P2.4接收信号,用管脚P1.0、P1.1、P1.2、P1.3控制电机的驱动。电路如图1.4:
图1.4 单片机电路
1.4电机驱动模块
采用双电机驱动,”H桥”可双向驱动电机。电机调速由单片机输出的方波实现,频率为30HZ左右,脉宽占空比大,则电机转速
大。电路如图1.5:
图1.5 电机驱动电路
图中“电机1_1”、“电机1_2”是一个电机的两个接口。另外一个电机的驱动电路与之相同。
二、硬件设计
三、程序编写
实现程序如下:
#include
#define uchar unsigned char
#define run_right() {left_f=1;left_b=0;right_f=1;right_b=1;} #define run_left() {left_f=1;left_b=1;right_f=0;right_b=1;} #define forward() {left_f=1;left_b=0;right_f=0;right_b=1;}
sbit left_2=P2^0;
sbit left_1=P2^1;
sbit mid=P2^2;
sbit right_1=P2^3;
sbit right_2=P2^4;
sbit left_f=P1^0;
sbit left_b=P1^1;
sbit right_b=P1^2;
sbit right_f=P1^3;
/******************延时函数*********************/
void delay(int x)
{
int a;
for(;x>0;x--)
for(a=30;a--;);
}
/***********************************************/
/*****************电机控制*********************/
void for_left_2() //车子要右转,速度最慢
{
while(1)
{
run_right(); delay(4);
run_left();delay(1); //右转脉宽大于左转脉宽,实现右拐弯if(!mid)
{
delay(20);
if(!mid)
{
run_left();delay(20);//调整车身至压线
forward();
break;
}
}
}
}
void for_left_1()//车子要右转,速度较慢
{
while(1)
{
run_right(); delay(3);
run_left();delay(2); //右转脉宽大于左转脉宽,实现右拐弯if(!mid)
{
delay(20);
if(!mid)
{
run_left();delay(20);//调整车身至压线
forward();
break;
}
}
}
}
void for_right_1() //车子要左传,速度较慢
{
while(1)
{
run_left();delay(3);
run_right();delay(2);//左转脉宽大于右转脉宽,实现左拐弯if(!mid)
{
delay(20);
if(!mid)
{
run_right();delay(20);//调整车身至压线
forward();
break;
}
}
}
}
void for_right_2() //车子左转,
{
while(1)
{
run_left();delay(4);
run_right();delay(1);//左转脉宽大于右转脉宽,实现左拐弯if(!mid)
{
delay(20);
if(!mid)
{
run_right();delay(20);//调整车身至压线
forward();
break;
}
}
}
}
void for_mid()
{
forward();
}
/***********************************************/
/*******************读取、处理信号***************/ void get_deal()
{
if(!left_2||(!left_2&&!left_1))
{ delay(1);if(!left_2||(!left_2&&!left_1)) for_left_2();}
if(!left_1||(!left_1&&!mid))
{delay(1);if(!left_1||(!left_1&&!mid)) for_left_1(); } if(!mid)
{delay(1);if(!mid) for_mid();}
if(!right_1||(!right_1&&!mid))
{delay(1);if(!right_1||(!right_1&&!mid)) for_right_1();}
if(!right_2||(!right_2&&!right_1))
{delay(1); if(!right_2||(!right_2&&!right_1)) for_right_2(); delay(1);} }
/***********************************************/
void main()
{
forward();
while(1)
{
get_deal();
}
}
四、设计失败的分析及补救方案:
该设计最终不能实现预期效果,主要出现以下问题:1、红外传感器对自身到地面的距离相当敏感,地面折皱
对其影响比较大。另外,电路中“6.8K的电阻+10k
可调电阻”对红外接收的信号几乎不起任何作用,
后改为250k,信号才明显,但此时10k可调电阻不
能工作了,故LM339处参考电压改用10k可调电阻
实现,以代替红外接收管所串联的10k可调电阻的
工作任务。改过后,信号能够正确传到单片机。
2、驱动电机的“H桥”本可以正常工作,接上LM339模
块后失常(单片机控制电机的管脚被拉高)。同时
7805的输出电压也失常,红外模块也没法正常工作。
经检测,当12v电源用大功率电源,电机会不受单
片机控制而转动,同时“H桥”中的8550三极管发
烫(经检测,无烧坏);当用限流300mA的电源时,
电机低速转动,三极管不发烫,但7805输出电压为
0,红外传感、控制模块不工作,单片机从实验板上
输信号控制(共地)才正常。原因可能有二:一是
“H桥”错误,偏置电阻不正确;二是驱动电机时,
电源输出的功率几乎被电机吃掉,以致7805不正常
工作,单片机不断掉电复位。
补救方案:
1、把电源部分修改为:双电源供电,12v直接驱动“H桥”,
5v电源供电给其他模块(两电源共地),仍然不能正常
工作。放弃该方案。
2、把电路简化,利用继电器控制电机,由单片机P1.0、P1.1
分别控制两电机的开关。比较器改用LM324,使用其中
3组比较,红外改用三个(左中右)。可以实现车子沿
着简单的路线行走。(因直接用万用板焊接,故暂无电路图。)其实现程序如下:
#include
sbit right=P1^1;
sbit left=P1^0;
sbit R=P2^3;
sbit center=P2^2; sbit L=P2^0;
#define uchar unsigned char
#define uint unsigned int //"宏定义标志位"
uchar temp;
uchar i;
void delay10ms(uchar t) {
uchar i,j,k;
for(k=0;k for(i=75;i>0;i--) for(j=60;j>0;j--); } void turn() { if(R==1) { delay10ms(10); if(R==1) { while(center==1) { right=0; } } } if(L==1) { delay10ms(10); if(L==1) { while(center==1) {right=1; left=0; } } } } void searching() { if(center==1) { right=1; } else { turn(); } } void main() { while(1) { searching(); } } 六、心得体会 本次项目设计没有实现项目要求,其中有很多细锁的问题考虑 不周。但通过这次动手,我们学了很多知识,熟悉了用Altium Designer6.6画电路图、做PCB图并做出电路板;学会了用Solid Works画实物图。更重要的是,这次项目设计让我们与小组成员相互交流、合作学习、增进感情;并且与其他同学的联系紧密了许多,从他们身上学到很多知识。