51单片机自动壁障小车设计,附原理图程序全套制作资料
大家好,欢迎关注电气技术微课堂!
在科学探索及紧急抢险中经常要对一些危险或人类不能直接到达的地域进行探测,这就需要用机器人来完成。而机器人在复杂地形行进时自动避障是一项必不可少也是最基本的功能。避障功能在日常生活中也是比较常见的,像是风靡一时的自动清扫机器人,只需放在地上一会就可以将你的屋子打扫干净,这里面的最基本功能也是避障,当它检测到前方有障碍就会绕开。这样就可以躲避家具将你的地板清理干净了。因此,自动避障系统的研发就应运而生。
MCS-51《单片机原理及接口技术》是中职院校电气自动化专业开设的 一门必修课程,该课程主要是通过对单片机的内部结构、相关外围电路及编程语言的学习,使学生掌握用单片机进行开发设计一些实用电子电路的能力,自动避障小车就是基于这一系统开发而成的。自动避障小车可以作为地域探索机器人和紧急抢险机器人的运动系统,让机器人在行进中自动避过障碍物。
一、本设计任务和主要内容本设计是对以单片机STC89C52RC为核心的系统根据感测模块传输的前方路面信息,控制小车行驶走向的软、硬件设计开发。系统要能够做到准确及时监测前方路面信息并传输给主控模块,做到根据前方路面信息及时调整小车的走向,做到显示小车的走向和小车已经行驶过的路程。
壁障小车的主要功能是:
① 感测模块实时监测路面情况并及时将障碍物的位置传输给单片机;
② 单片机核心模块根据感测模块给予的信息控制小车两电机转动;
③ 电机驱动模块驱动两电机转动,实现转向与行走。
二、系统主要硬件电路设计根据设计要求,我们的自动避障小车主要由五个模块构成:车体框架、电源及稳压模块、主控模块、探测模块、电机驱动模块组成。 各模块分述如下:
图1 系统模块组成框图
2.1 小车避障原理分析
小车车头处装有三个红外探头,中间一个光电开关对向正前方,两侧的红外探头向两边各分开30度,(如图2所示)。小车在行进过程中由红外探头向前方发射出红外线,当红外线遇到障碍物时发生漫反射,反射光被光电开关接收。小车根据三个探头接受信号的情况来判断前方障碍物的分布并做出相应的动作。
图2 自动避障小车车体及避障原理图
红外探头选用的是E12-D15NK型红外避障传感器,这是一种集发射与接收于一体的光电传感器,发射光经过调制后发出,接收头对反射光进行解调输出。有效的避免了可见光的干扰。分别探测正前方,前右侧,前左侧障碍物信息,在特殊地形(如障碍物密集地形)可将正前方的光电开关移置后方进行探测。E12-D15NK光电开关平均有效探测距离0~30cm可调,且抗外界背景光干扰能力强,可在日光下正常工作(理论上应避免日光和强光源的直接照射)。我们小车换档调速后的最大制动距离不超过30cm,一般在10~20cm左右,因而探测距离满足我们的小车需求示意图如下:
图4 红外避障传感器原理图
电气特性:
红色:VCC;黑色:GND;黄色:信号输出;白色:和红线一起外接电位器。
工作电压:5VDC
工作电流:10-15mA
驱动电流:100mA
感应距离:1-15CM
机械特性:
颜色:橙黄色
直径:12MM
长度:35MM
引线长度:25CM(不含接头)
2.2电源模块
方案一: 采用交流电经直流稳压处理后供电 采用交流电提供直流稳压电源,电流驱动能力及电压稳定性最好,且负载对电源影响也最小。但由于需要电线对小车供电,极大影响了壁障小车行动的灵活性及地形的适应能力。而且壁障小车极易把拖在地上的电线识别为障碍物,人为增加了不必要的障碍。故我放弃了这一方案。
方案二: 采用蓄电池供电 蓄电池具有较强的电流驱动能力和较好的电压稳定性能,且成本低廉。可采用蓄电池经7812芯片稳压后给电机供电,再经过降压接7805芯片给单片机及其他逻辑单元供电。但蓄电池体积相对庞大,且重量过大,造成电机负载过大,不适合我们采用的小车车架(玩具电动车车架)。故我放弃了这一方案。
方案三: 采用干电池组进行供电 采用四节干电池降压至5V后给单片机及其他逻辑单元供电,另取六节干电池为电机及光电开关供电。这样电机启动及制动时的短暂电压干扰不会影响到逻辑单元和单片机的工作。干电池用电池盒封装,体积和重量较小,同时玩具车底座可以安装四节干电池,正好可为单片机及其他逻辑单元供电。在稳压方面,起始时考虑使用7805芯片对6V的电池电压进行降压稳压。但考虑到这样使得7805芯片消耗大量能量,降低电池寿命;同时,由于STC89C51、光电开关、小车电机对于供电电压要求并不苛刻,故我们将6V电池电压接一个二极管降压后直接给单片机及其他逻辑单元供电。而电机和光电开关的电源不做稳压处理。这样只需在小车主板上加两个调速按钮,根据电池电量选择合适功率即可,甚至于可直接在软件里设置自动换挡。 综合考虑,我采用方案三。
2.3主控模块 3.1、STC89C52RC单片机最小系统
我采用的是STC公司的51内核单片机STC89C52RC,单片机最小系统及概述如下:STC89C52RC单片机介绍
STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。
主要特性如下:
1. 增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意选择,指令代码完全兼容传统8051.
2. 工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机)
3. 工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可达48MHz
4. 用户应用程序空间为8K字节
5. 片上集成512字节RAM
6. 通用I/O口(32个),复位后为:P1/P2/P3/P4是准双向口/弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。
7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程序,数秒即可完成一片
8. 具有EEPROM功能
9. 具有看门狗功能
10. 共3个16位定时器/计数器。即定时器T0、T1、T2
11. 外部中断4路,下降沿中断或低电平触发电路,Power Down模式可由外部中断低电平触发中断方式唤醒
12. 通用异步串行口(UART),还可用定时器软件实现多个UART
13. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)
14. PDIP封装
在探测模块和单片机中断接口之间、独立按键与单片机中断接口之间,需要经过电平的逻辑处理进行连接。主要涉及到一个三输入或非门和一个二输入与门。这两个逻辑关系我们直接选用74HC系列的集成芯片实现。 由于三输入或非门在市场上很难购买到,我们采用了两个二输入或非门和一个二输入与门完成了三输入或非门。由于我们采用的74HC08(四二输入与门)、74HC02(四二输入或非门)均为四二输入的,各提供四个二输入与门和四个二输入或非门,我们用各用一片芯片即可实现所需逻辑功能。
2.4电机驱动模块
本系统采用了L298N芯片来驱动电机 ,L298N是一个具有高电压大电流的全桥驱动芯片,输出电压最高可达50V,可以直接通过电源来调节输出电压;可以直接用单片机的IO口提供信号,而且带有使能端,方便PWM调速,电路简单,性能稳定,使用比较方便。L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,正好符合我们小车两个二相电机的驱动要求。 综合考虑,我采用L298N芯片驱动小车电机。
最终方案如下: 使用干电池组对系统供电,改造玩具电动车作为小车底座,采用STC89C52RC作为主控芯片,采用E12-D15NK光电开关进行障碍物探测,使用L298N驱动直流电机。逻辑关系处理使用74HC系列芯片完成。
2.5 总电路图
图5 总电路图设计
三、系统软件设计
3.1程序流程图
本系统设计流程图如下
图6 系统软件主流程图
3.2系统程序清单
#include <reg51.h>
#define uchar unsigned char
#define uintunsigned int
/********************
端口定义
*********************/
sbit IN1=P1^0; //P10与电机驱动IN1相连
sbit IN2=P1^1 //P11与电机驱动IN2相连
sbit IN3=P1^2; //P12与电机驱动IN3相连
sbit IN4=P1^3; //P13与电机驱动IN4相连
uchar INS=P2; //P2端口的^0、P2^1、P2^2分别与左、中、右红外模块输出信号线线相连
uint D=200;//定义延迟函数的参数
/************************
各个子函数定义
***********************/
void Go(void)
{
IN1=0;
IN2=0;
IN3=1;
IN4=0;
}
void Back(void)
{
IN1=0;
IN2=0;
IN3=0;
IN4=1;
}
void Go_left(void)
{
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
void Go_right(void)
{
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}
void Stop(void)
{
IN1=IN2=IN3=IN4=0;
}
/***
void Back_left(void)
{
IN1=1;
IN2=0;
IN3=0;
IN4=1;
}
void Back_right(void)
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
}
***/
void Delay(uint n)
{
uint i,j;
i=j=n;
for(;i>0;i--)
for(;j>0;j--);
}
void Be_move(void)
{
uchar temp;
temp=INS&0x07;
switch(temp)
{
case 0x01:Go_right();Go();Delay(D);break;
case 0x02:
case 0x03:
case 0x07:Back();Delay(D);Go_right();Go();Delay(D);break;
case 0x06:Back();Delay(D);Go_left();Go();Delay(D);break;
case 0x04:Go_left();Go();Delay();break;
case 0x05:Go();Delay();break;
default:Stop();Delay();break;
}
}
void main()
{
uchar temp;
while(1)
{
temp=INS&0x07;
if(temp==0x00) Go();
else Be_move();
}
}
C51 单片机 7
前面我们用的延时都是非精确延时,我们可以用一种比较精确的方法,单片机自带的定时器中断模块,89C52RC 带2个定时器中断,ET0 和ET1,中断的工作模式有4种,
定时器0为例,定时器0和定时器1是一样的都在TMOD中,
TMOD 中有8位 0000 0000 前4位是定时器1的控制选择 后4位是定时器0的控制选择,
4位中的后2位是模式选择
(1) 模式0 后两位是00 13位计数模式 不需要了解,平时都是用定时器1.
(2) 模式1 后两位是01 16位计数模式最大65535 分位高8位TH0,低八位TL0
(3) 模式2 后两位是10 自动装填模式 主要用在 串行通讯时计算 波特率
(4) 模式3 后两位是11 变成2个最大255的计数器
我们先用模式1 怎么计算定时值呢?
我们用12M举例 单片机有个12分频,也就是晶振动作12次,就是单片机执行一条程序所用的时间 12M=12 000 000 除以12= 1 000 000 这是单片机1秒所能执行的程序条数
那1秒执行1000000次,一条程序需要1秒除以1000000=0.000001秒=1us
我们模式1计数最大65535,再加就是满溢为0, 65533 65534 65535 0 1 2 3
65535按照1us一条最大定时65毫秒=65000微秒如果我们定时1秒怎么定时呢?
我们可以先定时10毫秒就是65536-10000=55536转成16进制等于D8EF
将D8送入 TH0 (T在应用中时间的首字母,H是高的首字母,0是定时器0的意思)
将EF送入 TL0 (T在应用中时间的首字母,L是低级的首字母,0是定时器0的意思)
EA 是所有中断的总开关的意思
ET0是定时器0的开关(不开这个开关,定时器0可以工作,我们就需要时时观察TR0为1还是为0)
TR0 是定时器0开始运行的开关(TR0=1开始工作,=0停止工作,当满溢时自动变0)
我们试试让一个小灯1秒一亮,一秒一熄灭。
#include<reg52.h>
sbit LED=P2^0;
void main( )
{
EA=1; // 开总开关
TMOD=0x01; //让定时器0工作在模式1 16位计数方式
TH0=0xD8; //高8位
TL0=0xEF; / /低8位
ET0=1; //开定时器0的开关
TR0=1; //开始运行定时器0
LED=0; 小灯亮
while (1); //这里我们让循环在这里一直等待,
让定时器0去控制小灯的亮 灭
}
void dingshiqi0() interrupt 1 这里后面的interrupt 1 时定时器0的固定写法
下面解释一下
{
static unsigned char i=0; //static时静态变量的意思 只在这个子程序中运行
TH0=0xD8; // 重新给高字节赋值
TL0=0xEF; //重新给低字节赋值
i++; // i 中数每次加1
if(i>=100) //如果i加到100就是100个10毫秒就是1秒
{
i=0; //让i从0开始
LED=~LED // 每经过1秒 LED转换一次状态,亮 灭
}
}
我们用的变量分为全局变量和静态变量,局部变量,
全局变量是说在所有的子程序都可以用这个变量。公用的物品
局部变量是只有这个函数或者称子程序才可以用,你自己家的洗衣机
不过局部变量执行完这个程序跳到别的程序的时候,再进这个程序局部变量变成初始值,
静态变量=静态局部变量,就是和局部变量一样只有这个程序能用,但是可以保留上一次运行完的值。
咱们的中断是有顺序的,
外部中断0 是第0个中断 优先级最高
定时器0 是第1个中断
外部中断1 是第2个中断
定时器1 是第3个中断
串行通讯中断 是第4个中断
我们用的是定时器0,所以就写成 interrupt 1
相关问答
一个 c51 程序只能有一个什么?一个c51程序只能有一个主函数。对于一个C51单片机的应用code有且只能有一个mian主函数,因为编译器需要识别主函数入口,并编译成二进制程序的入口,程序开始运...
c51单片机 分为哪几个模块?C51最小系统包括时钟电路、复位电路、电源电路、程序下载电路等几个模块。C51单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有处理事件的中央处...
C51单片机 怎么用C语言实现数值的开方和平凡运算?首先,楼主要明白,C51是基于标准的C语言扩展而来的,所以,标准C语言能做的东西,C51也可以。平方运算,自不必说,就是两个数相乘:例如:floata,b,c;c=a...首...
c51单片机 中断响应的四个步骤?单片机一旦响应中断请求,就由硬件完成以下功能:(1)根据响应的中断源的中断优先级,使相应的优先级状态触发器置1;(2)执行硬件中断服务子程序调用,并把...
c51单片机 编程?南邻更可念,布破冬未赎。白毛浮绿水,红掌拨清波。窗含西岭千秋雪,门泊东吴万里船。月下飞天镜,云生结海楼。月出惊山鸟,时鸣春涧中.千山鸟飞绝,万径人...
C51单片机 编程题:编写一个C语言函数,该函数能产生0~10的随机数?软件没办法产生真随机数的,你可以加一个AD采集电路,采集信号噪声,作为随机种子产生随机数软件没办法产生真随机数的,你可以加一个AD采集电路,采集信号噪声,作...
C51单片机 程序的中断过程是什么样的?程序不全,看不出问题在什么地方,这几段程序问题不大,不过一般不要在中断里面加延时。程序不全,看不出问题在什么地方,这几段程序问题不大,不过一般不要在中断...
c51单片机 上电之后完全没有反应,灯都不亮是不是坏了-ZOL问答C51讨论回答(8)请问你有没有烧程序进去,如果没有就烧一段LED灯打开的程序测试...(1)单片机芯片坏了,是否电源过高导致单片机损坏?(2)晶振不工作;(3)电路板...
c51单片机 怎么连?C51单片机(也称为8051单片机)可以通过以下步骤进行连接:1.编写C程序并使用C语言编译器进行编译。您可以使用KeilC51、SDCC等常用的编译器来编写程序。2...
c51单片机 中断系统应用介绍?c51单片机中断系统就是打断当前要做的事,转而去执行别的事情。单片机中断就是当单片机正在执行程序的时候,突然某个按键按下了(产生外部中断),单片机就必须...