资源描述
微机原理和接口技术课程设计汇报
基于51单片机步进电机控制系统
学号
姓名
班级 级电子2班
华侨大学电子工程系
摘要
步进电机是将电脉冲信号变换成角位移或直线位移实施部件。步进电机能够直接用数字信号驱动,使用很方便。步进电动机角位移量和输入脉冲个数严格成正比,在时间上和输入脉冲同时,所以只要控制输入脉冲数量、频率及电动机绕组通电相序,便可取得所需转角、转速及转动方向。在没有脉冲输入时,在绕组电源激励下气隙磁场能使转子保持原有位置处于定位状态。所以很适合于单片机控制。它运行速度和步距不受电源电压波动及负载影响, 所以被广泛应用于数模转换、速度控制和位置控制系统。本课程设计以STC89C52单片机作为微控制器,使用混合式步进电机驱动芯片ULNAN进行驱动,实现了对步进电机运行状态简单控制,并将其运行状态用LCD1602液晶显示。此次设计能实现功效有电机运行、停止,设置运行圈数,调整转速,电机正反转,点动等。
关键词:STC89C52单片机,28BYJ-48步进电机,ULNAN驱动芯片,LCD1602显示,电机控制,点动
第一章 总体设计方案
此次课程设计本课程设计以STC89C52单片机作为微控制器,使用混合式步进电机驱动芯片ULNAN进行驱动,实现了对步进电机运行状态简单控制,并将其运行状态用LCD1602液晶显示。此次设计能实现功效有电机运行、停止,设置运行圈数,调整转速,电机正反转,点动等。
系统步骤图以下:
第二章 硬件原理
一、 STC89c52单片机
2.1、STC89c52芯片介绍
STC89C52是一个低功耗,高性能CMOS 8位单片机,片内含8k Bytes ISP(In-system programmable)可反复擦写1000次Flash只读程序存放器,器件采取ATMEL企业高密度、非易失性存放技术制造,兼容标准MCS-51指令系统及STC89C52引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存放单元,功效强大微型计算机STC89C52可为很多嵌入式控制应用系统提供高性价比处理方案。
STC89C52含有以下特点:40个引脚,8k Bytes Flash片内程序存放器,256 bytes随机存取数据存放器(RAM),32个外部双向输入/输出(I/O)口,5个中止优先级2层中止嵌套中止,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
2.2、STC89c52芯片引脚功效说明
STC89C52RC引脚图
STC89C52RC引脚功效说明
VCC(40引脚):电源电压
VSS(20引脚):接地
P0端口(P0.0~P0.7,39~32引脚):P0口是一个漏极开路8位双向I/O口。作为输出端口,每个引脚能驱动8个TTL负载,对端口P0写入“1”时,能够作为高阻抗输入。在访问外部程序和数据存放器时,P0口也能够提供低8位地址和8位数据复用总线。此时,P0口内部上拉电阻有效。在Flash ROM编程时,P0端口接收指令字节;而在校验程序时,则输出指令字节。验证时,要求外接上拉电阻。
P1端口(P1.0~P1.7,1~8引脚):P1口是一个带内部上拉电阻8位双向I/O口。P1输出缓冲器可驱动(吸收或输出电流方法)4个TTL输入。对端口写入1时,经过内部上拉电阻把端口拉到高电位,这是可用作输入口。P1口作输入口使用时,因为有内部上拉电阻,那些被外部拉低引脚会输出一个电流()。
P2端口(P2.0~P2.7,21~28引脚):P2口是一个带内部上拉电阻8位双向I/O端口。P2输出缓冲器能够驱动(吸收或输出电流方法)4个TTL输入。对端口写入1时,经过内部上拉电阻把端口拉到高电平,这时可用作输入口。P2作为输入口使用时,因为有内部上拉电阻,那些被外部信号拉低引脚会输出一个电流()。
在访问外部程序存放器和16位地址外部数据存放器(如实施“MOVX @DPTR”指令)时,P2送出高8位地址。在访问8位地址外部数据存放器(如实施“MOVX @R1”指令)时,P2口引脚上内容(就是专用寄存器(SFR)区中P2寄存器内容),在整个访问期间不会改变。
在对Flash ROM编程和程序校验期间,P2也接收高位地址和部分控制信号。
P3端口(P3.0~P3.7,10~17引脚):P3是一个带内部上拉电阻8位双向I/O端口。P3输出缓冲器可驱动(吸收或输出电流方法)4个TTL输入。对端口写入1时,经过内部上拉电阻把端口拉到高电位,这时可用作输入口。P3做输入口使用时,因为有内部上拉电阻,那些被外部信号拉低引脚会输入一个电流()。
在对Flash ROM编程或程序校验时,P3还接收部分控制信号。
,以下表所表示:
引脚号
复用功效
P3.0
RXD(串行输入口)
P3.1
TXD(串行输出口)
P3.2
(外部中止0)
P3.3
(外部中止1)
P3.4
T0(定时器0外部输入)
P3.5
T1(定时器1外部输入)
P3.6
(外部数据存放器写选通)
P3.7
(外部数据存放器读选通)
RST(9引脚):复位输入。当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机复位初始化操作。看门狗计时完成后,RST引脚输出96个晶振周期高电平。特殊寄存器AUXR(地址8EH)上DISRTO位能够使此功效无效。DISRTO默认状态下,复位高电平有效。
ALE/(30引脚):地址锁存控制信号(ALE)是访问外部程序存放器时,锁存低8位地址输出脉冲。在Flash编程时,此引脚()也用作编程输入脉冲。
在通常情况下,ALE以晶振六分之一固定频率输出脉冲,可用来作为外部定时器或时钟使用。然而,尤其强调,在每次访问外部数据存放器时,ALE脉冲将会跳过。
假如需要,经过将地址位8EHSFR第0位置“1”,ALE操作将无效。这一位置“1”,ALE仅在实施MOVX或MOV指令时有效。不然,ALE将被微弱拉高。这个ALE使能标志位(地址位8EHSFR第0位)设置对微控制器处于外部实施模式下无效。
(29引脚):外部程序存放器选通信号()是外部程序存放器选通信号。当AT89C51RC从外部程序存放器实施外部代码时,在每个机器周期被激活两次,而访问外部数据存放器时,将不被激活。
/VPP(31引脚):访问外部程序存放器控制信号。为使能从0000H到FFFFH外部程序存放器读取指令,必需接GND。注意加密方法1时,将内部锁定位RESET。为了实施内部程序指令,应该接VCC。在Flash编程期间,也接收12伏VPP电压。
XTAL1(19引脚):振荡器反相放大器和内部时钟发生电路输入端。
XTAL2(18引脚):振荡器反相放大器输入端。
二、 28BYJ-48步进电机
2.2.1步进电机工作原理
步进电机是一个将电脉冲转化为角位移实施机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定方向转动一个固定角度(及步进角)。能够经过控制脉冲个来控制角位移量,从而达成正确定位目标;同时能够经过控制脉冲频率来控制电机转动速度和加速度,从而达成调速目标。
此次设计是采取步进电机28BYJ48型四相八拍电机,电压为DC5V—DC12V。当对步进电机施加一系列连续不停控制脉冲时,它能够连续不停地转动。每一个脉冲信号对应步进电机某一相或两相绕组通电状态改变一次,也就对应转子转过一定角度(一个步距角)。当通电状态改变完成一个循环时,转子转过一个齿距。四相步进电机能够在不一样通电方法下运行,常见通电方法有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)
其相序分配表以下:
2.2.2 步进电机24BYJ48相关电气参数
1.额定电压:12VDC(另有电压:5V、6V、24V)
2.相数:4
3.减速比:1/64(另有减速比:1/16、1/32)
4.步距角:5.625°/64
5.驱动方法:4相8拍
6.直流电阻:200Ω±7%(25℃)(按用户要求而定:80、130欧姆)
7.空载牵入频率:≥600Hz
8.空载牵出频率:≥1000Hz
9.牵入转矩:≥34.3mN.m(120Hz)
10.自定位转矩:≥34.3mN.m
11.绝缘电阻:>10MΩ(500V)
12.绝缘介电强度:600VAC/1mA/1S
13.绝缘等级:A
14.温升:<50K(120Hz)
15.噪音:<40dB(120Hz)
16.重量:大约40g
17.未注公差按:GB1804-m
18.转向:CCW
2.2.3 步进电机基础术语
2.2.3.1 相数
产生不一样对极N、S磁场激磁线圈对数,常见m表示。
2.2.3.2 拍数
完成一个磁场周期性改变所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,比如说此次设计中使用24BYJ48有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)
2.2.3.3 步距角
对应一个脉冲信号,电机转子转过角位移用θ表示。θ=360度(转子齿数J*运行拍数),以常规二相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/(50*4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50*8)=0.9度(俗称半步)。
2.2.3.4 信号分配
四相步进电机根据其通电方法不一样,能够分为单四拍,双四拍和双八拍三种工作方法。单四拍和双四拍步距角相等,均为11.25度,而八拍步距角则是单四拍和双四拍二分之一,5.625度。单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍 (A-AB-B-BC-C-CD-D-DA-A。。。)。这里选择是双相八拍工作方法。
三、 ULN达林顿陈列芯片
步进电机驱动采取ULN芯片。
ULN 是高耐压、大电流达林顿陈列, 由七个硅 NPN 达林顿管组成。 ULN 每一对达林顿全部串联一个 2.7K 基极电阻 , 在 5V 工作电压下它能和 TTL 和 CMOS 电路直接相连, 能够直接处理原先需要标准逻辑缓冲器来处理数据。 ULN 工作电压高, 工作电流大, 灌电流可达 500mA , 而且能够在关态时承受 50V 电压, 输出还能够在高负载电流并行运行。
其引脚及内部原理图以下:
本设计中试验1、2、3、4脚做输入端,16、15、14、13做相对应输出端,起到放大作用,以驱动电机。
四、 LCD1602液晶
1602液晶也叫1602字符型液晶 它是一个专门用来显示字母、数字、符号等点阵型液晶模块 它有若干个5X7或5X11等点阵字符位组成,每个点阵字符位全部能够显示一个字符。现在市面上字符液晶绝大多数是基于HD44780液晶芯片,控制原理是完全相同,所以基于HD44780写控制程序能够很方便地应用于市面上大部分字符型液晶。
其各引脚功效见下图:
其经典接口电路以下图:
其基础操作时序为:
读状态 输入:RS=L,RW=H,E=H
输出:DB0~DB7=状态字
写指令 输入:RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码
输出:无
读数据 输入:RS=H,RW=H,E=H
输出:DB0~DB7=数据
写数据 输入:RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据
输出:无
第三章 电路设计
一、单片机最小系统和LCD1602接口电路
本电路模块包含单片机最小系统,即51单片机、时钟电路、复位电路、上电开关等,和1602液晶接口电路。
模块电路原理图以下:
各子模块电路以下:
(1) 时钟产生电路
用于产生单片机控制时钟,实际使用时采取11.0592M晶振。
(2) 复位电路
用于单片机手动复位。
(3) 1602液晶接口电路
用于连接1602液晶,P2.0—P2.2分别接RS、RW、EN,P0口接数据指令输入口。
二、步进电机驱动及接口电路
本电路模块用于单片机对步进电机控制及使用ULN芯片对步进电机进行驱动。
原理图以下:
因为所选24BYJ48步进电机为四相步进电机,故只需4个单片机IO口控制,此处使用单片机IO口P1.0-P1.3,使用ULN引脚1-4做输入,16-13引脚做输出口。
三、按键电路
此次设计为了便于以后功效扩展使用了8个按键。
原理图以下:
第四章 程序设计
进入主程序后首优异行LCD初始化和定时器中止初始化,以后进行依次对按键进行扫描,当检测到对应按键按下时,即实施对应功效。
系统步骤图以下:
第五章 系统调试
经过对程序反复修改,调试以后,系统能够实现电机运行、停止,设置运行圈数,调整转速,电机正反转,点动等功效,同时液晶显示对应状态。
第六章 心得体会
为其近30天单片机课程设计结束了,在这30天中我收获了很多,感到很有意义。
早在大二自学单片机时我就注意到步进电机这种器件,但当初只是略作了解,没有学习它原理和编程控制,这次借课程设计机会,我得以对步进电机进行了较为深入了解和学习。
在课设前期我经过查阅了很多资料,学习了步进电机工作原理。以后我开始考虑整体硬件电路设计,显示、驱动电路设计,最终选择使用28BYJ48型步进电机、ULN驱动芯片、1602液晶显示。在这以后我开始考虑要实现电机功效,最终决定实现电机运行、停止,设置运行圈数,调整转速,电机正反转,点动等功效。在完成了原理图和PCB图绘制、电路元件焊接后,我开始着手进行程序设计。经过查阅资料我了解到控制步进电机关键是利用定时器中止控制脉冲快慢、次序来调整电机转速、正反转等状态。以此为基础我开始了程序设计和调试,在这个过程中我碰到过部分困难,最终经过深入学习、不停修改程序和同学帮助最终得四处理。最终,此次课程设计完成了预想对步进电机几项基础控制功效。
步进电机调速系统适用多种现场自动化控制,尤其应用于小功率负载控制;含有成本底,性能稳定,可靠性高等优点。我认为经过这次课程设计我对步进电机基础控制得到了掌握,这对以后我在学习、工作很多应用场所中很可能会有用武之地。
另外,在这次课设过程中包含LCD1602控制等内容也对我很有帮助。经过此次课设我对51单片机编程控制、定时器中止等知识也得到了充足复习巩固。
总而言之,这次课设让我受益匪浅,感谢邱应强老师一学期来单片机课程悉心教导,这些是我完成此次课设基础和关键。
附件
一、 电路原理图
二、 电路PCB图
三、 电路实物图
四、 源程序
#include <reg52.h>
#include <intrins.h> //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //正转相序编码
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};
sbit K1 = P3^0; //运行和停止
sbit K2 = P3^1; //设圈数
sbit K3 = P3^2; //方向转换
sbit K4 = P3^3; //转速加
sbit K5 = P3^4; //点动
sbit K6 = P3^5;
sbit K7 = P3^6;
sbit K8 = P3^7;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
bit on_off=0,on_off1=0; //运行和停止标志
bit direction=1; //方向标志
bit rate_dr=1; //速率标志
bit snum_dr=1; //圈数标志
uchar code cdis1[ ] = {" STEPPING MOTOR "};
uchar code cdis2[ ] = {"CONTROL PROCESS"};
uchar code cdis3[ ] = {" STOP "};
uchar code cdis4[ ] = {"NUM: RATE: "};
uchar code cdis5[ ] = {" RUNNING "};
uchar code cdis6[ ] = {" DIAN DONG "};
uchar m,v=0,q=0,q1;
uint number=0,number1=0;
uchar snum=10,snum1=10,number2=0; //预设定圈数
uchar rate=2,rate_ctr; //预设定速率
uchar data_temp,data_temP1,data_temp2;
/********************************************************/
/*
/* 延时t毫秒
/* 11.0592MHz时钟,延时约1ms
/*
/********************************************************/
void delay(uint t) //tms
{
uchar k;
while(t--)
{
for(k=0; k<125; k++)
{ }
}
}
/********************************************************/
void delayB(uchar x) //x*0.14MS
{
uchar i;
while(x--)
{
for (i=0; i<13; i++)
{ }
}
}
/********************************************************/
/********************************************************/
/*
/*检验LCD忙状态
/*lcd_busy为1时,忙,等候。为0时,闲,可写指令和数据。
/*
/********************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/********************************************************/
/*
/*写指令数据到LCD
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
/*
/********************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/********************************************************/
/*
/*写显示数据到LCD
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
/*
/********************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/********************************************************/
/*
/* LCD初始化设定
/*
/********************************************************/
void lcd_init()
{
delay(30);
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //写入新数据后光标右移
delay(5);
lcd_wcmd(0x01); //清除LCD显示内容
delay(5);
}
/********************************************************/
/*
/* 设定显示位置
/*
/********************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/********************************************************/
/*
/* LCD1602初始显示子程序
/*
/********************************************************/
void LCD_init_DIS()
{
delay(10); //延时
lcd_init(); //初始化LCD
lcd_pos(0); //设置显示位置为第一行第1个字符
m = 0;
while(cdis1[m] != '\0')
{ //显示字符
lcd_wdat(cdis1[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis2[m] != '\0')
{
lcd_wdat(cdis2[m]); //显示字符
m++;
}
delay(3000); //延时
lcd_pos(0); //设置显示位置为第一行第1个字符
m = 0;
while(cdis3[m] != '\0')
{ //显示字符
lcd_wdat(cdis3[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis4[m] != '\0')
{
lcd_wdat(cdis4[m]); //显示字符
m++;
}
for(m=0;m<2;m++)
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3e);
}
}
/********************************************************/
/*
/*数据转换子程序
/*
/********************************************************/
void data_conv()
{
data_temP1=data_temp/10; //高位
if(data_temP1==0)
{data_temP1=0x20;} //高位为0不显示
else
{data_temP1=data_temP1+0x30;}
data_temp2=data_temp%10; //低位
data_temp2=data_temp2+0x30;
}
/********************************************************/
/*
/*数据显示子程序
/*
/********************************************************/
void data_dis()
{
data_temp = snum; //显示圈数
data_conv();
lcd_pos(0x44);
lcd_wdat(data_temP1);
lcd_pos(0x45);
lcd_wdat(data_temp2);
data_temp = rate; //显示速率
data_conv();
lcd_pos(0x4d);
lcd_wdat(data_temP1);
lcd_pos(0x4e);
lcd_wdat(data_temp2);
}
/********************************************************
/*
/* 显示运行方向符号
/*
/********************************************************/
void motor_DR()
{
if(direction==1) //正转方向标志
{ for(m=0;m<2;m++)
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3e);
}
}
else
{ for(m=0;m<2;m++) //反转方向标志
{
lcd_pos(0x0c+m); //显示方向符号
lcd_wdat(0x3c);
}
}
}
/********************************************************
/*
/* 显示运行状态
/*
/********************************************************/
void motor_RUN()
{
if(on_off==1)
{ TR0=1;
lcd_pos(0); //设置显示位置为第一行第1个字符
m = 0;
while(cdis5[m] != '\0')
{ lcd_wdat(cdis5[m]); //RUNNING
m++; }
motor_DR(); //
}
else
{ TR0=0; P1 =0x0f;
lcd_pos(0); //设置显示位置为第一行第1个字符
m = 0;
while(cdis3[m] != '\0')
{ lcd_wdat(cdis3[m]); //STOP
m++; }
motor_DR(); //
snum=snum1; //
number1=0; //清圈数计数器
}
}
void motor_RUN1()
{
if(on_off1==1)
{ TR1=1;
rate_ctr=0;
lcd_pos(0); //设置显示位置为第一行第1个字符
m = 0;
while(cdis6[m] != '\0')
{ lcd_wdat(cdis6[m]); //DIANDONG
展开阅读全文