基于单片机的电动伸缩门控制系统设计.docx
《基于单片机的电动伸缩门控制系统设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电动伸缩门控制系统设计.docx(27页珍藏版)》请在冰豆网上搜索。
基于单片机的电动伸缩门控制系统设计
单片机原理与应用课程设计说明书
题目:
基于单片机的电动伸缩门控制系统设计
*********
学号:
***********
院(系):
职业教育师范学院
专业:
电子信息工程
**********
2014年12月12日
1选题背景
随着科技的发展,人们的生活水平不断的提高,各种方便人们生活的自动控制系统开始进入人们的生活。
为了使自动伸缩门能够更好的为人们和各种企业单位服务,需要得到一种电路简单,软件功能完善,控制系统可靠,性价比较高的自动伸缩门系统。
以单片机为核心的自动门系统就是其中之一,本文设计了基于单片机的自动伸缩门控制系统。
该系统以单片机为主体,步进电机为控制实体,实现伸缩门的自动控制。
电动机与人的生活息息相关,密不可分。
电动伸缩门是广泛使用在人员进出流动比较频繁的各个单位、住宅小区以及公园景点的入口处。
随着社会的不断发展,人们拥有自己的汽车的情况越来越普遍,交通堵塞的问题比较严重,有了电动伸缩门的帮助可以使得我们容易对大量的车流控制系统开始进入人们的生活以单片机为核心的自动门系统就是其中之一本文设计了基于单片机的自动伸缩门控制系统该系统以单片机为主体,实现伸缩门的自动控制。
本设计要求制作完成一个电动伸缩门控制系统。
电动伸缩门控制系统即通过按键实现门的自动开启和关闭,以及其安全性等方面的要求。
故电动伸缩门控制系统的关键在于对门开启和关闭条件的检测和对电机的控制。
具体要求如下:
(1)用遥控器或者红外遥控器控制电动伸缩门的运行;
(2)系统运行时显示时钟信息和“您好欢迎光临陕西科技大学”等字样;
(3)设计时应考虑电动门的运行速度以及安全性等因素;
(4)以单片机的最小系统为基础硬件,用汇编或者C语言编写程序;
(5)有人或者汽车靠近时门应该打开;自动伸缩门上的LCD显示屏显示相对应的汉字。
此外,该系统设计充分发挥了单片机的性能,具有较好的可靠性和实用性。
2方案论证
电动伸缩门控制系统主要基于硬件和软件的要求。
硬件方面采用简单高效的AT89C52单片机系统板来实现。
在电机的选取上,由于直流电机相比较步进电机更加简单方便,并在一定程度上可以实现所要求的功能,所以在此选取直流电机控制伸缩门的工作。
我们采用小车的前进后退和停止模拟电动伸缩门的运行,通过对速度开关的调节,实现小车加速减速达到控制速度的目的。
基于安全性的考虑,当有人或车辆突然经过伸缩门时,设置中断停止按键使行进中的伸缩门立即停止,起到保护的效果。
时间显示方面采用LCD液晶显示,并设置时间调节按键设置显示时间。
3过程(设计或实验)论述
3.1硬件设计
硬件方面包括LCD1602的引脚和DS1302时钟芯片的引脚连接以及按键设置。
用小车的前进后退模拟伸缩门的运动。
3.1.1LCD液晶显示
(1)元件说明
模块组建内部主要由LCD显示屏、控制器、列驱动器和偏压产生电路构成。
控制器接受来自MPU的指令和数据,控制着整个模块的工作,由CGROM、CGRAM和DDRAM等字符存储区域、以及与MPU和列驱动器的I/O接口、指令寄存和译码机构、地址计数器等部分组成。
在控制器的控制下,模块通过数据总线DB0~DB7和E、R/W、RS三个输入控制端与MPU接口。
这三根控制线按照规定的时序相互协调作用,使控制器通过数据总线DB接受MPU发送来的指令和数据,从CGROM中找到欲显示字符的字符码,送入DDRAM,在LCD显示屏上与DDRAM存储单元对应的规定位置显示出该字符。
控制器还可以根据MPU的指令,实现字符的显示、闪烁和位移效果。
下面是其引脚图:
图3-1引脚图
(2)模块应用
LCD数据输入输出口是与P0口相连,寄存器选择输入端与单片机P2.6相连,读写控制输入端接P2.5,使能端接P2.7。
将显示屏初始化,使“年、月、日、时钟等信息”通过LCD显示屏显示出来,并通过按键对日期时间进行调整,其中第一行显示“年、月、日、星期”,第二行显示“时、分、秒”的信息,下图为其仿真图:
图3-2LCD仿真图
3.1.2直流电机模块
(1)直流电机驱动电路
L293D采用16引脚DIP封装,其内部集成了双极型H-桥电路,L293通过内部逻辑生成使能信号。
H-桥电路的输入量可以用来设置马达转动方向,使能信号可以用于脉宽调整(PWM)。
另外,L293将2个H-桥电路集成到1片芯片上,这就意味着用1片芯片可以同时控制2个电机。
每1个电机需要3个控制信号EN12、IN1、IN2,其中EN12是使能信号,IN1、IN2为电机转动方向控制信号,IN1、IN2分别为1、0时,电机正转;反之,电机反转。
选用一路PWM连接EN12引脚,通过调整PWM的占空比可以调整电机的转速。
以下为L293驱动电机的逻辑图和内部仿真图:
表3-1驱动电机逻辑图
ENA(B)
IN1(IN3)
IN2(IN4)
电机运行情况
H
H
L
正转
H
L
H
反转
H
同IN2(IN4)
同IN1(IN3)
快速停止
L
X
X
停止
(2)直流电机仿真图
本设计采用一路直流电机实现其正转、反转和停止,IN1和IN2分别接到单片机的P2.0,P2.1口,使能端EN1接到单片机的P2.2口,当使能端有效,输入端分别为不同电平时,电机可实现正反转和停止。
图3-3直流电机仿真图
3.1.3按键控制时间显示电路
P1.0~P1.2控制LCD时间显示的调整。
其中触发P1.0按键,停止DS1302计数,LCD光标闪烁显示调节位置,表示开始调节时间。
P1.1按键实现增加显示时间,P1.2按键实现减小时间。
3.1.4键盘控制电机工作电路
设置三个按键实现电机的正转、反转和停止,三个按键分别接至P3.0,P3.1,P3.2口,再设置调节速度开关,将其连接在P1.3引脚上。
当一直按下正转键,小车前进,若此时有速度调节按键按下时,执行调节速度后的程序,否则,执行未调节速度后的程序;当一直按下反转键时,小车就会后退,速度调节时,执行调节速度后的程序。
如果遇到突然发生的情况,比如当有行人或者车辆通过正在运行的电动伸缩门时,就需要电动伸缩门立即停止,这时可以按下P1.3口连接的按键,使正在行驶中的小车立即停下。
图3-4按键和键盘控制仿真图
3.1.5DS1302时钟芯片电路
(1)DS1302芯片说明
DS1302慢速充电时钟芯片包括实时时钟/日历提供秒﹑分﹑时﹑日﹑周﹑月和年等信息。
对于小于31天的月,月末的日期就会自动进行调整,同时还包括了闰年校正的功能。
时钟的运行可以采用24小时制或者带AM(上午)或PM(下午)的12小时格式。
使用同步串行通信,简化了DS1302与微处理器的通信。
数据可以以每次一个字节或者多达31个字节的多字节形式传送至时钟/RAM或从其中送出。
(2)工作原理
串行时钟芯片的组成部分有:
位移寄存器﹑控制逻辑﹑振荡器﹑实时时钟以及RAM。
为了初始化任何的数据传送,把RST置为高电平且并把提供地址和命令信息的8位装入到移位寄存器。
数据在SCLK的上升沿串行输入。
下图为引脚排列:
图3-5引脚排列
无论是读周期还是写周期发生,也无论传送方式是单字节传送还是多字节传送,开始8位指定40个字节中的哪个将被访问。
在开始8个时钟周期把命令字装入移位寄存器之后,另外的时钟在读操作时输出数据,在写操作时输入数据。
以下为引脚说明:
表3-2引脚说明
X1,X2
32.768kHz晶振引脚
GND
地
RST
复位
I/O
数据输入/输出
SCLK
串行时钟
Vcc1,Vcc2
电源引脚
(3)DS1302的仿真图
将DS1302芯片的片选端,数据信号端,时钟信号端分别接至P3.5,P3.4,P3.6口,通过软件设置,实现地址和数据的传送。
在时间修改的时候,按下功能键,DS1302停止计时。
当修改时间完毕后,重新恢复DS1302的工作,将地址和数据送入DS1302中,计数器开始计时,LCD1602开始显示。
以下是DS1302的仿真图:
图3-6DS1302仿真图
3.1.6总设计仿真图
下图为电动伸缩门的总仿真图:
图3-7总仿真图
3.2软件设计
软件设计包括主程序的设计以及各个子程序的设计。
主程序主要实现了小车的运行,子程序实现了LCD液晶的显示,具体如下:
3.2.1主程序
主程序主要实现电机的正转、反转、停止和安全性实现,首先将液晶显示和DS1302时钟芯片进行初始化,对时间调节按键进行扫描,确定有无按键按下,当功能键按下时光标显示,进行时间调节,并将调节后的时间送入LCD1602进行显示。
当一直按小车前进键时,判断是否进行伸缩门调速,若需要则执行调速后的前进程序,否则执行未调速程序,当一直按小车后退键时,其原理同上。
在伸缩门安全性实现上,当模拟开门或者关门工作时,若遇到突发状况,比如有行人或者车辆通过时,按下停止按钮,执行中断程序,伸缩门停止工作。
3.2.2DS1302时钟芯片程序与LCD1602显示程序设计
该模块程序分为以下子程序,分别为写命令与数据函数,写时分秒、年月日的日期函数,对LCD1602的初始化函数。
程序见附录:
3.2.3按键扫描程序
首先定义三个调节按键,分别为功能键,增大键,减小键,当功能键按下1次时,LCD光标显示在“年”位置处,表明开始调节时间,液晶停止从DS1302读数据,记录按下功能键次数,分别将其定位到LCD不同位置处。
当功能键按下8次后,表明已调节完毕,不显示光标,将调解后的日期写入DS1302,并让液晶从中读取数据显示。
当功能键定位在某一位置,按下增大键,相应数据加1,并将调整后的数据送入DS1302。
减小键与增大键的原理相同。
部分程序见附录:
4结果分析
本次设计主要实现了小车运行,包括前进、后退和停止,以及时间日期的显示,结果分析主要从LCD显示和电动伸缩门的运行两个方面考虑。
4.1LCD液晶显示模块
将程序烧入单片机中,LCD显示日期与时间,第一行显示年、月、日和星期,第二行显示时、分、秒,当对时间显示进行调节时,按下功能键光标定位在年的位置,实现时间调节的增大与减小,当功能键按到第8次,即已经将时间调整完毕后,调节后的时间即可通过LCD显示出来。
4.2电动伸缩门控制
在未调节速度按钮前,一直按下前进键,小车前进,小车后退同上。
在调节速度后,按下前进与后退键,小车速度有明显改变。
当遇到突发情况时,按下停止键,小车能在运行的情况下立即停止,实现其安全性能。
由于小车自身存在机械缺陷,该部分功能显示不太明显。
5归纳和总结
此次有关自动伸缩门的控制系统的设计,让我感觉到了单片机的复杂深度性,它并不是想象中的那么简单,也并非是无法克服的堡垒。
首先设计硬件之前,要收集好有关的基础性资料,应备有良好的应用类参考书和专业类参考书。
对于有关的科技期刊和专利文献,也要经常阅读以便了解最新的发展情况,借鉴现成的经验,避免重复劳动。
在设计中,要充分了解所用芯片的使用条件及输入输出的特性,这样才能避免因使用错误而多走弯路。
电路设计部分应该有的精神就是广集资料。
只凭借自己头脑中的知识是远远不够的。
哪里出现了问题,就要翻书本,或上网查资料。
当然也要开动自己的脑筋怎样使系统电路更完美。
例如我的设计题目是基于单片机的自动伸缩门控制系统设计。
有自动门,自然会用到电动机,每种电机都有不同的特性和功能,这就要进行选择了。
例如对电机的选择,就要选择我所熟悉的,所了解的。
在电路设计时,应充分发挥单片机的记忆运算、判断控制能力,避免采用复杂的、稳定性较差的模拟电路。
本设计程序以汇编语言语言编写,易于读写、易于调试和修改,同时汇编语言用来编制系统软件和过程控制软件,其目标程序占用内存空间少,运行速度快。
为了使微机控制系统各种硬件设备能够正常运行,有效地实现电机各个控制环节的实时控制和管理,除了要设计合理的硬件电路,还必须要有高质量的软件支持。
因此用汇编语言编写电机单片机实施控制的应用程序,使整个系统中十分重要的内容。
一直以来,都在强调单片机对专业的重要性,但也只是了解了大概,在这次课程设计中,才真正认识到它功能的强大,同时也对单片机设计的工程产生了浓厚的兴趣。
这次设计虽然只是一个很小的系统,但运用了单片机开发板上的多个功能,让我有机会学习到这些知识,同时整个设计的实现,也为我今后想要继续这方面的学习打下了基础,比如要首先清楚每个器件的功能作用,看懂它的资料说明,才能更好的运用。
另外在软件的编写过程中,也查阅了各类资料,丰富了我其他方面的知识。
这次课程设计虽然结束了,但我却将它作为以后学习的起点,要想真正提高自己的动手能力还需要不断的学习与实践。
我想在自己的努力下,一定会有所收获。
附录:
#include
#include
#include
#include
Sbitdj_2=P2^1;//电机2
Sbitdj_en=P2^2;//电机使能端
Sbitopen=P3^0;
Sbitclose=P3^1;
Sbitbiasu=P1^3;
unsignedcharii;
unsignedcharjj;
inta,b;
voiddelaynumbers(unsignedintn)//延时函数
{
unsignedcharii;
while(n--)
{
for(ii=0;ii<150;ii++);
}
}
voiddooropen(void)//开门
{
dj_1=1;
dj_2=0;
if(biansu==0)
{dj_en=0;//使dj_en产生PWM波
delaynumbers(10);
dj_en=1;
delaynumbers(90);}
else
{dj_en=0;//使dj_en产生PWM波
delaynumbers(30);
dj_en=1;
delaynumbers(70);}
}
voiddoorclose(void)//关门
{
dj_1=0;
dj_2=1;
if(biansu==0)
{dj_en=0;//使dj_en产生PWM波
delaynumbers(10);
dj_en=1;
delaynumbers(90);}
else{dj_en=0;//使dj_en产生PWM波
delaynumbers(30);
dj_en=1;
delaynumbers(70);}
}
voidstop(void)
{
dj_en=1;//使能端有效控制停转
dj_1=dj_2=0;
}
voidmain()
{
LCD_INITIAL();//液晶初始化
INITIAL_1302();//DS1302初始化
while
(1)
{
Keyscan();//按键扫描
if(flag==0)//当标志位为0,允许读取DS1302数据,将数据送入液晶显示{
second=READ_1302(0x81);
LCD_WRITE_SFM(10,second);//从DS1302读取秒送入液晶显示
minute=READ_1302(0x83);
LCD_WRITE_SFM(7,minute);//从DS1302读取分送入液晶显示
hour=READ_1302(0x85);
LCD_WRITE_SFM(4,hour);//从DS1302读取时送入液晶显示
week=READ_1302(0x8b);
LCD_WRITE_WEEK(week);//从DS1302读取星期送入液晶显示
day=READ_1302(0x87);
LCD_WRITE_NYR(9,day);//从DS1302读取日送入液晶显示
month=READ_1302(0x89);
LCD_WRITE_NYR(6,month);//从DS1302读取月送入液晶显示
year=READ_1302(0x8d);
LCD_WRITE_NYR(3,year);//从DS1302读取年送入液晶显示
LCD_WRITE_NYR(汉字);//从DS1302读取汉字送入液晶显示
}
if(!
open)//开门
{
EX0=1;
EA=1;
TCON=0x01;
Dooropen();
}
else
{
EX0=0;
EA=0;
stop();
}
if(!
close)//关门
{
EX0=1;
EA=1;
TCON=0x01;
Doorclose();
}
else
{
EX0=0;
EA=0;
stop();
}
}
}
voidmyint0(void)interrupt0//外部中断0
{
stop();
Delaynumbers(5000);
EX0=0;
EA=0;
}
(1)地址数据发送子函数
voidWRITE_1302(unsignedcharadd,unsignedchardate)//地址、数据发送子程序
{
unsignedchari,temp;
RST=0;//RST引脚为低,数据传送中止
SCLK=0;//清零时钟总线
RST=1;//RST引脚为高,逻辑控制有效
for(i=8;i>0;i--)//发送地址,循环8次移位
{
SCLK=0;
temp=add;
DIO=(bit)(temp&0x01);//每次传送低字节
add>>=1;//右移一位
SCLK=1;
}
for(i=8;i>0;i--)//发送数据
{
SCLK=0;
temp=date;
DIO=(bit)(temp&0x01);
date>>=1;
SCLK=1;
}
RST=0;
}
(2)读取数据函数
unsignedcharREAD_1302(unsignedcharadd)//读取数据
{
unsignedchari,temp,date1,date2;
RST=0;
SCLK=0;
RST=1;
for(i=8;i>0;i--)//循环8次移位
{
SCLK=0;
temp=add;
DIO=(bit)(temp&0x01);//每次传送低字节
add>>=1;//右移一位
SCLK=1;
}
for(i=8;i>0;i--)
{
ACC_7=DIO;
SCLK=1;
ACC>>=1;
SCLK=0;
}
RST=0;
date1=ACC;
date2=date1/16;//数据进制转换
date1=date1%16;//十六进制转十进制
date1=date1+date2*10;
return(date1);
}
voidLCD_WRITE_COM(unsignedcharcom)//写命令函数
{
LCD_RS=0;
LCD_RW=0;
LCD_E=1;
P0=com;
delay(5);
LCD_E=0;
}
voidLCD_WRITE_DATA(unsignedchardate)//写数据函数
{
LCD_RS=1;
LCD_RW=0;
LCD_E=1;
P0=date;
delay(5);
LCD_E=0;
}
voidLCD_WRITE_SFM(unsignedcharadd,unsignedchardate)//写时分秒函数
{
unsignedcharsh,g;
sh=date/10;
g=date%10;//分解2位数的十位和个位
LCD_WRITE_COM(0x80+0x40+add);//设置显示位置
LCD_WRITE_DATA(0x30+sh);//送去液晶显示十位
LCD_WRITE_DATA(0x30+g);//送去液晶显示个位
}
voidLCD_WRITE_NYR(unsignedcharadd,unsignedchardate)//写年月日函数
{
charsh,g;
sh=date/10;
g=date%10;//分解2位数的十位和个位
LCD_WRITE_COM(0x80+add);//设置显示位置
LCD_WRITE_DATA(0x30+sh);//送去液晶显示十位
LCD_WRITE_DATA(0x30+g);//送去液晶显示个位
}
voidLCD_WRITE_WEEK(unsignedcharweek)//写液晶星期显示函数
{
LCD_WRITE_COM(0x80+12);//设置显示位置
switch(week)
{
case1:
LCD_WRITE_DATA('M');delay(5);
LCD_WRITE_DATA('O');delay(5);;
LCD_WRITE_DATA('N');break;
case2:
LCD_WRITE_DATA('T');delay(5);
LCD_WRITE_DATA('U');delay(5);
LCD_WRITE_DATA('E');break;
case3:
LCD_WRITE_DATA('W');delay(5);
LCD_WRITE_DATA('E');delay(5);
LCD_WRITE_DATA('D');break;
case4:
LCD_WRITE_DATA('T');delay(5);
LCD_WRITE_DATA('H');delay(5);
LCD_WRITE_DATA('U');break;
case5:
LCD_WRITE_DATA('F');delay(5);
LCD_WRITE_DATA('R');delay(5);
LCD_WRITE_DATA('I');break;
case6:
LCD_WRITE_DATA('S');delay(5);
LCD_WRITE_DATA('A');delay(5);
LCD_WRITE_DATA('T');break;
case7:
LCD_WRITE_DATA('S');delay(5);
LCD_WRITE_DATA('U');delay(5);
LCD_WRITE_DATA('N');break;
}
}
voidLCD_INITIAL()//液晶初始化函数
{
unsignedchari;
LCD_WRITE_COM(0x38);//设置16*2显示,5*7点阵,8位数据接口
LCD_WRITE_COM(0x0c);//设置开显示,不显示光标
LCD_WRITE_COM(0x06);//写一个字符后地址指针加1
LCD_WRITE_COM(0x80);//液晶第一行显示
for(i=0;i<16;i++)
{
LCD_WRITE_DATA(str1[i]);
delay(5);
}
LCD_WRITE_COM(0x80+0x40);//液晶第二行显示
for(i=0;i<16;i++)
{
LCD_WRITE_DATA(str2[i]);
delay(5);
}
}
LCD_WRITE_COM(0x80