本设计介绍了一种基于51单片机的步进电机控制系统,该设计采用STC89C51单片机为主控芯片,步进电机由ULN2003A驱动跟单片机相连接,LCD显示屏实时显示步进电机信息。步进电机采用八拍运行方式,由单片机发出脉冲信号控制步进电机的通电顺序,从而达到控制步进电机运转的目的。开启后,通过矩阵键盘向单片机输入脉冲控制信号,以此来实现步进电机的正反转、加减速、角度设置,最终基本达到了预期目标。
利用单片机,实现用键盘控制步进电机的运转,包括设定步进电机运转的角度,方向及速度,并显示其信息。
主控模块使用STC89C51单片机来作为控制芯片。
输入模块的选择中,考虑到需要设置步进电机运转角度和其他的功能以及单片机接口的限制,独立键盘的按键数量不能满足要求,所以本设计中采用4×4矩阵键盘;只需占用一个I/O口,就可以提供16个按键。
显示模块的选择,有LED和LCD两种显示方式可供选择,但考虑到需要显示的内容较多,LED显示需要许多的LED数码管;这样会占用大量的控制芯片的资源使得显示模块的实现极为复杂。考虑到这些因素,本次设计中采用LCD的显示方式,对比了几款LCD显示屏,最终选择了LCD1602作为显示模块。LCD1602可以显示16×2个字符,可以满足设计需求。
驱动模块的选择,因控制芯片发出的控制信号过于微弱,无法直接驱动被控单元;所以必须在控制芯片与被控单元之间加入一个信号放大模块,经过几种信号放大方式的对比,最终决定采用最为可靠的ULN2003A作为驱动模块。ULN2003A具有很高的直流电流增益,可以很好的驱动步进电机。
被控单元的选择,本设计采用了常见的28-BYJ-48步进电机。它是一款永磁式、减速型,四相八拍步进电机,有三种工作模式可供选择。
经过不断的对比选择,最终采用了以下方案完成设计;STC89C51单片机作为主控芯片,4×4矩阵键盘输入步进电机控制信息,步进电机采用28-BYJ-48步进电机。因单片机无法直接驱动起电机,所以我们采用ULN2003A驱动芯片来驱动电机,步进电机的运行信息由最后由LCD1602液晶显示屏显示。
单片机最小系统,也叫做单片机最小应用系统,是指用最少的原件组成单片机可以工作的系统。单片机最小系统的三要素就是电源、时钟电路、复位电路,电源可使用外部稳定的5V电源供电模块供给。 复位电路分为按键复位和上电复位。上电复位通常在复位引脚RST上连接一个电容到VCC,再连接一个电阻到GND,由此形成一个RC充放电回路保证单片机在上电时RST脚上有足够时间的高电平进行复位,在RST引脚上加两个周期的高电平即可使单片机复位,随后回归到低电平进入正常工作状态,这个电阻和电容的典型值为10K和10uF。按键复位就是在复位电容上并联一个开关,当开关按下时电容被放电、RST也被拉到高电平,而且由于电容的充电,会保持一段时间的高电平来使单片机复位。 因单片机内部带有振荡电路,所以外部只要连接一个晶振和两个电容即可,电容容量一般在15pF至30pF之间。电容的作用是帮助晶振起振,并维持振荡信号的稳定。 图3.1 单片机最小系统原理图 LCD1602是一种工业字符型液晶,能够同时显示16x2即32个字符。LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。 LCD1602主要参数:显示容量16×2个字符;芯片工作电4.5—5.5V;工作电流2.0mA,模块最佳工作电压5.0V。
与单片机的连接:D0-D7并行连接单片机的P0口,作为数据传输;RS,RW,E分别连接单片机P2.5,P2.6,P2.7。RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
3.3 驱动模块
ULN2003A是高耐压、大电流复合晶体管阵列,由七个硅NPN 复合晶体管组成,每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。ULN2003A 具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动的系统。 图3.3 ULN2003A模块图 3.4 矩阵键盘原理及电路图矩阵键盘又称行列键盘,如图3.4所示,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4×4个。使用矩阵键盘时我们用扫描法识别按键,按键按下时,与此键相连的行线与列线导通,行线在无按键按下时处在高电平。如果
所有的列线都处在高电平,则按键按下与否不会引起行线电平的变化,因此必须使所有列线处在电平。这样当有按键按下时,该键所在的行电平才会由高变低,才能判断相应的行有键按下。 图3.4 矩阵键盘 表3-4矩阵键盘说明表
4 系统软件设计
4.1 系统软件流程图系统软件设计是本次系统设计的重要组成部分,基于硬件电路条件,整个程序细分为若干个功能模块来完成,主要有显示程序模块、按键程序模块、步进电机模块。 STC89C51单片机的P1口用来连接矩阵键盘,P0口与P2口的P2^5、P2^6、P2^6连接LCD602、最后由P3口借助一个驱动芯片ULN2003与步进电机连接。单片机程序中的主函数完成对LCD1602显示屏初始化之后,依次调用显示函数、按键查询函数、角度设置函数。主程序流程图如图4.1所示。 4.2 LCD1602显示流程图本设计用LCD1602液晶屏作为显示,主要是将步进电机的角度、速度、方向等信息在LCD1602上面显示出来,以便于用户操作。如图4.2所示为液晶屏显示控制子程序流程图。
测试结果及其分析
在模拟仿真阶段,本设计采用了kile与proteus联合仿真调试,确保所写程序可以实现本设计所需要的功能。经过不断的调试和仿真,在仿真环境下实现了预期的功能。随后,利用开发板搭建了电路,经过测试ULN2003模块可以正常驱动电机;下载程序之后,矩阵键盘可以正常输入控制信息,LCD1602液晶显示正常,步进电机按输入控制信息能够正常运转。但因步进电机减速比的影响,显示角度与电机实际角度存在误差。
本文设计了一种基于单片机的步进电机控制系统,采用4×4矩阵键盘作为输入,使用LCD1602显示信息,如运转的角度,方向及速度。可通过键盘输入让步进电机运转的角度,方向和运转速度。采用了ULN2003驱动模块,可以很好的驱动步进电机。实现了对步进电机较为精确的控制。
单片机源程序如下:
- #include<stdio.h>
- #include<reg51.h>
- #include<lcd1602.h>
- #define Motor P3
- void SetAngle(uint angle);
- uchar keyscan();
- uchar code Motortab[]={0x03,0x02,0x06,0x04,0x0c,0x08,0x09,0x01};
- uchar flag=2;
- uint T=5;
- void main()
- {
- static int keyvalue=0;
- static int num=0;
- Init();
- printf("Angle=%5d",0);
- while(1)
- {
- keyvalue=keyscan();
- if(keyvalue)
- {
- if(keyvalue>=0&&keyvalue<=10)
- {
- if(keyvalue==10)
- keyvalue=0;
- num=num*10+keyvalue;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ");//角度输入
- }
- else if(keyvalue==15)
- {
- T--;
- if(T<1)
- T=10;
- SetRowCol(1,6);
- printf("speed=%2d%s",T," ");
-
- }
- else if(keyvalue==16)
- {
- T++;
- if(T>10)
- T=0;
- SetRowCol(1,6);
- printf("speed=%2d%s",T," ");
-
- }
- else if(keyvalue==11) //开始
- {
- if(flag==0)
- {
- SetRowCol(1,0);
- printf("STRAT");
- SetAngle(-(num)*11.5);
- SetRowCol(1,0);
- printf("END ");
- SetRowCol(1,4);
- printf("NAngle=%d%s",-num," ");
- num=0;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ");
- flag=2;
- }
- else if(flag==1)
- {
- SetRowCol(1,0);
- printf("STRAT");
- SetAngle(num*11.5);
- SetRowCol(1,0);
- printf("END ");
- SetRowCol(1,4);
- printf("NAngle=%s%d%s"," ",num," ");
- num=0;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ");
- flag=2;
- }
- else
- {
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ");
- flag=2;
- }
- }
- else if(keyvalue==12) //输入清零
- {
- num=0;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ");
- SetRowCol(1,0);
- printf(" ");
- }
- else if(keyvalue==13) //正反转
- {
- flag=!flag;
- if(flag==0)
- {
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," FZ");
-
- }
- else if(flag==1)
- {
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ZZ");
- }
- }
- else if(keyvalue==14)//点动
- {
- if(flag==0)
- {
- num--;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," FZ");
- SetAngle(num*11.5);
- }
- else if(flag==1)
- {
- num++;
- SetRowCol(0,0);
- printf("Angle=%5d%s",num," ZZ");
- SetAngle(num*11.5);
- }
- }
-
- }
- }
- }
- void SetAngle(uint angle)
- {
- static uint FirAngle=0;
- static uint i=0;
- int d;
- uint j;
- d=angle-FirAngle;
- if(d>0)
- {
- for(j=0;j<d;j++)
- {
- i++;
- i=(i&0x0007);
- Motor=Motortab[i];
- delay(T);
- }
- FirAngle=angle;
- }
- else
- {
- for(j=0;j<-d;j++)
- {
- i--;
- i=i&0x0007;
- Motor=Motortab[i];
- delay(T);
- }
- FirAngle=angle;
- }
- }
复制代码
以上图文的Word格式文档下载(内容和本网页上的一模一样,方便大家保存):
基于51单片机的步进电机控制系统.docx
(391.54 KB, 下载次数: 48)
|