资源描述
目录
摘要 1
1设计任务与要求 2
1、1设计目得 2
1、2设计要求与设计指标 2
2方案分析 3
3系统硬件部分 4
3、1主控模块 4
3、2键盘输入模块 7
3、3电机模块 8
3、4显示模块 11
4系统软件部分 13
4、1整体流程图及主程序 13
4、2按键流程图及程序 14
4、3显示模块程序 19
4、4电动机模块流程图及程序 20
4、5中断程序 22
5仿真运行 24
6心得体会 25
参考文献 26
附录一:Protues硬件仿真图 27
附录二:系统程序 28
摘要
步进电机在控制系统中具有很广泛得应用。它可以把脉冲信号转换成角位移,并且可用作电磁制动轮、电磁差分器或角位移发生器等。
步进电机就就是将电脉冲信号转变为角位移或线位移得开环控制元步进电机件。在非超载得情况下,电机得转速、停止得位置只取决于脉冲信号得频率与脉冲数,而不受负载变化得影响,当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定得方向转动一个固定得角度,称为“步距角”,它得旋转就就是以固定得角度一步一步运行得。可以通过控制脉冲个数来控制角位移量,从而达到准确定位得目得;同时可以通过控制脉冲频率来控制电机转动得速度与加速度,从而达到调速得目得。
此次设计使用C语言作为编程语言。C语言就就是一种计算机程序设计语言,它既具有高级语言得特点,又具有汇编语言得特点。它得应用范围广泛,具备很强得数据处理能力,不仅仅就就是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件、三维、二维图形与动画,具体应用例如单片机以及嵌入式系统开发 。
硬件部分使用89C51作为主控芯片,并使用ULN2003A将单片机得信号放大以控制步进电机,同时使用4位数码管显示转动角度及次数。
关键词:步进电机 C语言 AT89C51 ULN2003A 转动角度
1设计任务与要求
1、1设计目得
设计制作与调试一个由8086组成步进电机角度测控系统。通过这个过程学习熟悉键盘控制与七段数码管得使用,掌握步进电机得角度控制与角度显示方法。
1、2设计要求与设计指标
1、在显示器上显示任意四位十进制数
2、将8个键定义键值为0~7,按任意键在显示器上显示对应键值
3、实现:
(1)定义键盘按键:5个为数字键1~5;3个功能键:设置SET、清零 CLR、开始START;
(2)显示器上第一位显示次数,后三位显示每次行走得角度;
(3)通过键盘得按键,设置步进电机各次得角度值;第一位设置次数,后三位设置角度值。
(4)按START键启动步进电机开始转动,按SET键停止;按CLR键清零。
2方案分析
课程设计要求设计一个直流电机微型计算机角度控制系统,定义8个键盘按键:5个为数字键1~5;3个功能键:设置SET、清零 CLR、开始START;显示器上得四位可显示转动次数与每次转动角度;通过键盘得按键,设置步进电机转动次数与每次转动角度;按START键启动电机开始转动,按SET键停止;按CLR键清零。
综合分析之后,我们应该将电路实现利用键盘按键通过89C51得P3口实现输入功能,并通过89C51得P0口与P1口实现对数码管显示得控制。同时我们可以通过P2口控制ULN2003A驱动电动机运行。
我们可以将整体电路设计成几个相对独立而又有机结合得模块,来逐一进行分析。
通过分析我们可以画出系统图,如图2-1所示。
图2-1 系统图
3系统硬件部分
3、1主控模块
3、1、1 AT89C51芯片
本次设计就就是使用AT89C51作为主控芯片,AT89C51就就是一种带4K字节闪烁可编程可擦除只读存储器得低电压、高性能CMOS8位微处理器,俗称单片机。单片机得可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准得MCS-51指令集与输出管脚相兼容。由于将多功能8位CPU与闪烁存储器组合在单个芯片中,ATMEL得AT89C51就就是一种高效微控制器,89C2051就就是它得一种精简版本。89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉得方案。
AT89C51得40个引脚主要有一下几种
(1)VCC:供电电压。
(2)GND:接地。
(3)P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口得管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址得低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
(4)P1口:P1口就就是一个内部提供上拉电阻得8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这就就是由于内部上拉得缘故。在FLASH编程与校验时,P1口作为低八位地址接收。
(5)P2口:P2口为一个内部上拉电阻得8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口得管脚被外部拉低,将输出电流。这就就是由于内部上拉得缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址得高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器得内容。P2口在FLASH编程与校验时接收高八位地址信号与控制信号。
(6)P3口:P3口管脚就就是8个带内部上拉电阻得双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这就就是由于上拉得缘故。
P3口还有其她一些特殊功能,本事设计没有使用,故在此不做叙述。
(7)RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期得高电平时间。
(8)ALE/PROG:当访问外部存储器时,地址锁存允许得输出电平用于锁存地址得地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变得频率周期输出正脉冲信号,此频率为振荡器频率得1/6。因此它可用作对外部输出得脉冲或用于定时目得。然而要注意得就就是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE得输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令就就是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
(9)/PSEN:外部程序存储器得选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效得/PSEN信号将不出现。
(10)/EA/VPP:当/EA保持低电平时,则在此期间为外部程序存储器(0000H-FFFFH),不管就就是否有内部程序存储器读取外部ROM数据。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,单片机读取内部程序存储器。(扩展有外部ROM时读取完内部ROM后自动读取外部ROM)。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
(11)XTAL1:反向振荡放大器得输入及内部时钟工作电路得输入。
(12)XTAL2:来自反向振荡器得输出
图3-1 AT89C51芯片
3、1、2时钟电路及复位电路
在本次课程设计中,我们用到AT89C51单片机。而她需要一些特定得控制电路得控制才能更好地工作。具体到本次课设中,我们需要时钟电路、防抖电路、复位电路等。
如图3-2所示就就是我们得时钟电路,由电容C1、C2以及晶振组成。
图3-2 时钟电路
如图3-3所示就就是我们得复位电路。
图3-3 复位电路
3、2键盘输入模块
在微机化仪器仪表中,键盘就就是最常用得一种输入设备,用于输入数据与命令。键盘得每一个按键都被赋予一个代码,称为键码。键盘系统得主要工作包括及时发现有键闭合,求闭合键得键码。根据这一过程得不同,键盘可以分为两种,即全编码键盘与非编码键盘。全编码键盘多就就是商品化得计算机输入设备,自动提供对应于被安检得ASCII码,且能同时产生一个控制信号通知微处理器。此外,这种键盘具有处理抖动与多键串键得保护电路,具有使用方便、价格较贵、体积较大、按键较多等特点。非编码键盘恰如一组开关,一般组成行与列矩阵。其全部工作过程,如按键得识别、键得代码获取、防止串键及消抖等问题,都靠程序完成。因此,它所需要得硬件少,价格便宜,一般作为单板机、智能仪表等简单得输入设备。
键盘电路常用得有两种,一种就就是独立式键盘电路,另一种就就是矩阵式键盘。独立式键盘每个按键独占一根I/O线。因此键识别软件非常简单。对于只有几个按键得系统,常采用这种电路。对于多按键系统来讲,这种电路忧郁将占用更多得I/O线而变得无法实用。
矩阵式键盘电路将I/O口线得一部分作为行线,另一部分作为列线,按键设置在行线与列线得交叉点上,这就构成了行列式键盘。行列式键盘中按键得数量可达行线数n乘以列线数m。由此可以瞧到行列式键盘在按键较多时,可以节省I/O线。按键开关得两端分别接在行线与列线上。行线通过一个电阻接到+5V电源上,在没有键按下时,行线处于高电平状态。
判断就就是否有键按下得方法就就是:向所有得列线I/O口输出低电平,然后将行线得电平状态读入累加器中,若无键按下,行线仍保持高电平状态,若有键按下,行线至少应有一条为低电平。当确定有键按下后,即可进行求键码得过程。其方法就就是:依次从一条列线上输出低电平,然后检查各行线得状态,若全为高电平,说明闭合键不在该列;若不全为1,则说明闭合键在该列,且在变为低电平得行得交点上。
在键盘处理程序中,每个键都被赋予了一个键号,由从列线I/O口输出得数据与从行线I/O口读入得数据可以求出闭合键得键号。
图3-4键盘模块原理图
3、3电机模块
3、3、1步进电机结构及工作原理
步进电机又叫脉冲电机,它就就是一种将电脉冲信号转换为角位移得机电式数模转换器。在开环数字程序控制系统中,输出控制部分常采用步进电机作为驱动元件。步进电机控制线路接受计算机发来得指令脉冲,控制步进电机作为驱动元件。步进电机控制线路接收计算机发来得指令脉冲,控制步进电机做相应得转动。在非超载得情况下,电机得转速、停止得位置只取决于脉冲信号得频率与脉冲数,而不受负载变化得影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系得存在,加上步进电机只有周期性得误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变得非常得简单。
步进电机得驱动电路根据控制信号工作,控制信号由8086通过8255A产生。
此次设计采用四相式步进电机。
图3-5 步进电机励磁线圈
(1) 步进电机工作原理说明
步进电机由转子与定子组成。转子由一个永久磁铁构成,定子分别由四组绕组组成。步进电机组成与电气连接分别如图3-6与3-7所示。
图3-6 转子与定子示意图 图3-7 电气连接示意图
当S1连通电源后,定子磁场将产生一个靠近转子为N极,远离转子为S极才磁场,这样得定子磁场与转子得固有磁场发生作用,转子就会转动,正确地S1、S4得送电次序,就能控制转子旋转得方向。
例如:若送电得顺序为S1闭合断开S2闭合断开S3闭合断开S4闭合断开,周而复始得循环,在定子与转子共同作用下,电机就瞬时针旋转:
若送电得顺序为S4闭合断开S3闭合断开S2闭合断开S1闭合断开,周而复始得循环,则电机就逆时针旋转,原理同理。
3、3、2 电机驱动ULN2003A简介
ULN2003就就是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。ULN2003 就就是高压大电流达林顿晶体管阵列系列产品,具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动得系统。ULN2003A管脚如图3-8所示。
图3-8 ULN2003A管脚图
ULN2003 得每一对达林顿都串联一个2、7K 得基极电阻,在5V 得工作电压下它能与TTL 与CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理得数据。ULN2003工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V 得电压,输出还可以在高负载电流并行运行。 ULN2003内部还集成了一个消线圈反电动势得二极管,可用来驱动继电器。它就就是双列16脚封装,NPN晶体管矩阵,最大驱动电压=50V,电流=500mA,输入电压=5V,适用于TTL S,由达林顿管组成驱动电路。ULN就就是集成达林顿管IC,内部还集成了一个消线圈反电动势得二极管,它得输出端允许
通过电流为200mA,饱与压降VCE约1V左右,耐压BVCEO约为36V。用户输出口得外接负载可根据以上参数估算。采用集电极开路输出,输出电流大,故可直接驱动继电器或固体继电器,也可直接驱动低压灯泡。通常单片机驱动ULN2003时,上拉2K得电阻较为合适,同时,引脚应该悬空或接电源。ULN2003就就是一个非门电路,包含7个单元,单独每个单元驱动电流最大可达350mA,9脚可以悬空。
由于ULN2003有这些特点,所以经常作为显示驱动、继电器驱动、照明灯驱动、电磁阀驱动、伺服电机、步进电机驱动等电路中。
ULN2003A内部结构如图3-9所示。
图3-9 ULN2003A内部结构图
图3-10 电机模块原理图
3、4显示模块
数码管就就是数码显示器得俗称。常用得数码显示器有半导体数码管,荧光数码管,辉光数码管与液晶显示器等。译码与数码显示电路就就是将数字钟与计时状态直观清晰得反映出来,被人们得视觉器官所接受。显示器件采用七段数码管。在译码显示电路输出得驱动下,显示出直观、清晰得数字符号。本设计所采用得就就是半导体数码管,就就是用发光二极管(简称LED)组成得字形来显示数字,七个条形发光二极管排列成七段组合字形,便构成了半导体数码管。半导体数码管有共阳极与共阴极两种类型,共阳极数码管得七个发光二极管得阳极连在一起,而七个阴极则就就是独立得。共阴极数码管与共阳极数码管相反,七个发光二极管得阴极连在一起,而阳极就就是独立得。
当共阳极数码管得某一阴极接低电平时,相应得二极管发光,可根据字形使某几段二极管发光,所以共阳极数码管需要输出低电平有效得译码器去驱动。共阴极数码管则需要输出高电平有效得译码器去驱动。七段显示数码管得外部引线排列如图3-11,共阳极数码管结构示意图如图3-12所示。
图3-11 数码管外引线排列
图3-12 共阳极数码管结构示意图
在多位LED显示时,为了节省I/O口线,简化电路,降低成本,一般采用动态显示方式。动态显示方式就就是一位一位地分时轮流各位显示器,对每一位显示器来说,每隔一段时间轮流点亮一次,形成动态显示。
图3、13 显示模块原理图
4系统软件部分
4、1整体流程图及主程序
系统得整体软件流程图如图4-1所示
图4-1 系统流程图
主程序如下:
void main() ﻩ ﻩ //主函数
{
ﻩTMOD=0x01; ﻩ //T0工作方式1
ﻩTH0=0xd8; ﻩ //设初值,0、01秒触发一次
TL0=0xf0; ﻩ
ﻩTR0=0;ﻩﻩ //关闭T0定时器
ET0=1;ﻩﻩﻩ //允许T0定时器中断
EA=1;ﻩ ﻩ //开启总中断允许
ﻩP2=0x03;
ﻩwhile(1)
ﻩ{
ﻩﻩscan();
ﻩshow();
ﻩﻩif(num1==0)ﻩﻩ //若电机运行次数已达到设定值,则关时器
ﻩ { ﻩ ﻩ //并将状态位置0
ﻩﻩﻩTR0=0;
ﻩ status=0;
ﻩﻩ}
ﻩ}
}
4、2按键流程图及程序
按键流程图如图4-2所示
图4-2 按键模块流程图
按键模块程序如下:
void scan() ﻩ ﻩﻩﻩ //按键扫描
{
if(START==0&&status==0)ﻩﻩ //开始键:只有当电机不运行时才有效,且将状态位置1;
{ﻩﻩﻩﻩ //并开启定时器(电机重新开始转动)。
ﻩdelay(10);
ﻩ if(START==0&&status==0)
ﻩﻩ{
ﻩﻩﻩstatus=1;
ﻩﻩﻩTR0=1; ﻩ //开定时器0
ﻩ num1=num;
ﻩ }
}
if(SET==0&&status==1) //停止键:只有当电机运行就就是有效,将状态位置0;
{ ﻩﻩ ﻩ //并关闭定时器(电机停止转动)。
ﻩﻩdelay(10);
ﻩif(SET==0&&status==1)
ﻩ {
ﻩﻩ status=0;
ﻩ ﻩTR0=0; //关定时器0
ﻩﻩ}
}
if(CLR==0&&status==0)ﻩ //清零键:只有当电机不运行时,清零键才有效
ﻩ{
ﻩdelay(10);
ﻩif(CLR==0&&status==0)
ﻩﻩ{
ﻩ ﻩP1=0;
ﻩﻩ P0=0xff;
ﻩﻩsh=0;
ﻩ }
}
if(k1==0&&status==0)ﻩﻩ //数字键1:设置为3 045。只有当电机不运行时,数字键才有效
ﻩ{
delay(10);
ﻩif(k1==0&&status==0)
{
ﻩ num=3;
ﻩﻩnum1=3;
ﻩbai=0;
ﻩ shi=4;
ﻩ ge=5;
ﻩﻩsh=1;
ﻩﻩ key=1;
}
ﻩ}
ﻩif(k2==0&&status==0) ﻩ //数字键2:设置为4 090
ﻩ{
ﻩ delay(10);
ﻩ if(k2==0&&status==0)
ﻩ {
num=4;
ﻩﻩﻩnum1=4;
ﻩ ﻩbai=0;
ﻩﻩshi=9;
ge=0;
ﻩﻩsh=1;
ﻩﻩ key=2;
ﻩ}
}
if(k3==0&&status==0) ﻩ //数字键3:设置为5 090
ﻩ{
ﻩﻩdelay(10);
ﻩif(k3==0&&status==0)
ﻩﻩ{
ﻩﻩnum=5;
ﻩ num1=5;
ﻩ ﻩbai=0;
ﻩshi=9;
ﻩﻩﻩge=0;
ﻩ sh=1;
ﻩﻩkey=2;
ﻩﻩ}
ﻩ}
ﻩif(k4==0&&status==0)ﻩ //数字键4:设置为6 045
{
delay(10);
ﻩif(k4==0&&status==0)
ﻩﻩ{
ﻩ num=6;
ﻩnum1=6;
ﻩﻩﻩbai=0;
ﻩ ﻩshi=4;
ﻩge=5;
sh=1;
ﻩkey=1;
}
}
ﻩif(k5==0&&status==0)ﻩ //数字键5:设置为7 090
{
ﻩdelay(10);
if(k5==0&&status==0)
{
ﻩ ﻩnum=7;
ﻩnum1=7;
bai=0;
ﻩshi=9;
ﻩﻩge=0;
ﻩﻩﻩsh=1;
ﻩﻩﻩkey=2;
ﻩ}
}
}
4、3显示模块程序
由于使用得就就是4为数码管,每一位需要显示不同得数字,故让各位数码管按照一定得顺序轮流显示,只要扫描频率足够高,由于人眼得“视觉暂留”现象,就能连续稳定得显示。
程序如下:
void show()ﻩﻩﻩ ﻩﻩ //数码管显示
{
if(sh==1)
ﻩ{
ﻩP1=0x01;ﻩ ﻩ //显示第一位
P0=smg[num];
ﻩ P0=0xff;
P1=0x02; ﻩﻩ //显示第二位
ﻩﻩP0=smg[bai];
P0=0xff;
ﻩﻩP1=0x04;ﻩ //显示第三位
ﻩ P0=smg[shi];
ﻩﻩP0=0xff;
P1=0x08;ﻩﻩﻩ //显示第四位
ﻩ P0=smg[ge];
ﻩ P0=0xff;
}
}
4、4电动机模块流程图及程序
要就就是步进电机模块按一定方向转动,需要轮流给P2、0~P2、3口脉冲,故采用移位得方法实现,流程图如图4-3所示。(X初始值为0x01,Y初始值为0x02)
图4-3电机模块流程图
电机模块程序如下:
void motor() ﻩ ﻩ //电机运行
{
ﻩif(key==1)ﻩ ﻩ//每次转动角度为45度时
ﻩ{
ﻩ if(c%2==0)
{
ﻩx=_crol_(x,1);
ﻩﻩ x=x|_crol_(x,4);ﻩ
ﻩ }
ﻩ else
ﻩ{
ﻩﻩy=_crol_(y,1);
ﻩﻩ y=y|_crol_(y,4);
ﻩﻩ}
c=c+1;
P2=x|y;
ﻩ}
ﻩif(key==2) ﻩ ﻩﻩ //每次转动角度为90度时
ﻩ{ ﻩ
x=_crol_(x,1);
ﻩx=x|_crol_(x,4);
ﻩ y=_crol_(y,1);
ﻩy=y|_crol_(y,4);
P2=x|y;
ﻩ}
}
4、5中断程序
每次设计采用定时器来完成步进电机得转动速度,每次中断便就就是计数存储器加一,当计数存储器达到设定值时便使电机转动一次。
中断程序如下:
void time0(void) interrupt 1 //中断处理程序
{
TR0=0;
ﻩTH0=0xd8;
TL0=0xf0;
clk++;
ﻩif(clk==100) ﻩ ﻩﻩ //每一秒电机运转一次
ﻩ{
ﻩclk=0;
ﻩﻩnum1--;
ﻩﻩmotor();ﻩﻩﻩ ﻩ //调用电机运行程序
}
TR0=1;
}
ﻬ5仿真运行
(1)按下数字键后数码管显示数字
图5-1 数码管显示
(2)按下开始键后,电机开始运行
图5-2 电机运行图
(3)按下停止键后,电机停止运行
(4)按下清零键后,数码管被清零。
图5-3 电机停止运转
6心得体会
在我们得大三即将结束得时候,我进行了《步进电机微型计算机角度控制系统得设计》。总体来说,本次训练主要就就是针对《计算机控制技术》所学理论知识得检测以及对protues软件得学习与使用。
随着不断深入得学习,我感受到了这个软件得强大。以前我们学习《计算机控制技术》,需要绞尽脑汁得计算分析各电路。而使用这种方法,不但计算量大、分析不太准确、结果准确性差、费时费力,通过学习protues,并通过使用protues,非常方便准确得得到了仿真电路得正确连线方法以及最优化电路。分析起来又快又准确。大大促进了我们得学习效率。
这次课程设计不仅锻炼了我们得自学能力以及我自己得耐力。而且我也深切得感受到了计算机控制技术在日常生活中得广泛应用,作为工科生我们更要加强理论联系实际,为以后成为一名技术人才奠定坚实得理论实践基础。
参考文献
[1] 郭天祥、 新概念51单片机C语言教程、北京:电子工业出版社,2009
[2] 周润景、基于PROTEUS 得电路及单片机系统设计与仿真、北京:北京航空航天出版社,2006
[3] 陈伯石、电力拖动自动控制系统、北京:机械工业出版社,2003、
[4] 李光飞、单片机课程设计实例指导、北京:北京航空航天出版社,2004
[5] 陈光东、单片微型计算机原理与接口技术(第二版)、武汉:华中科技大学出版社,1999
附录一:Protues硬件仿真图
附录二:系统程序
#include"reg51、h"
#include"intrins、h"
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit k4=P3^3;
sbit k5=P3^4;
sbit START=P3^5;
sbit SET=P3^6;
sbit CLR=P3^7;
int smg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int status=0,sh=0;
int num,bai,shi,ge,num1,key=0;
int clk=0;
int c=0,x=0x1,y=0x2;
void delay(int a);
void scan();
void show();
void motor();
void delay(int a) ﻩﻩ //延时程序
{
int i,j;
ﻩfor(i=a;i>0;i--)
ﻩﻩfor(j=1000;j>0;j--);
}
void scan()ﻩﻩ ﻩ //按键扫描
{
ﻩif(START==0&&status==0) ﻩ //开始键:只有当电机不运行时才有效,且将状态位置1;
{ﻩ ﻩ ﻩﻩ //并开启定时器(电机重新开始转动)。
ﻩﻩdelay(10);
ﻩif(START==0&&status==0)
{
ﻩ status=1;
ﻩ TR0=1; ﻩ //开定时器0
ﻩﻩ num1=num;
ﻩ}
}
ﻩif(SET==0&&status==1) ﻩ //停止键:只有当电机运行就就是有效,将状态位置0;
ﻩ{ﻩﻩ ﻩ ﻩ //并关闭定时器(电机停止转动)。
delay(10);
ﻩ if(SET==0&&status==1)
ﻩ {
ﻩ ﻩstatus=0;
TR0=0; //关定时器0
ﻩ}
}
ﻩif(CLR==0&&status==0) ﻩ //清零键:只有当电机不运行时,清零键才有效
ﻩ{
delay(10);
if(CLR==0&&status==0)
ﻩ{
ﻩﻩP1=0;
ﻩ ﻩP0=0xff;
sh=0;
ﻩﻩ}
}
ﻩif(k1==0&&status==0)ﻩﻩ //数字键1:设置为3 045。只有当电机不运行时,数字键才有效
ﻩ{
ﻩﻩdelay(10);
ﻩ if(k1==0&&status==0)
ﻩﻩ{
ﻩﻩﻩnum=3;
ﻩﻩﻩnum1=3;
ﻩ bai=0;
ﻩ shi=4;
ﻩge=5;
sh=1;
ﻩ key=1;
ﻩ}
}
ﻩif(k2==0&&status==0)ﻩ //数字键2:设置为4 090
{
ﻩﻩdelay(10);
if(k2==0&&status==0)
{
ﻩnum=4;
ﻩﻩﻩnum1=4;
ﻩ ﻩbai=0;
ﻩﻩ shi=9;
ﻩﻩ ge=0;
ﻩ ﻩsh=1;
ﻩﻩ key=2;
ﻩ}
}
if(k3==0&&status==0)ﻩﻩ //数字键3:设置为5 090
{
ﻩ delay(10);
ﻩ if(k3==0&&status==0)
ﻩ{
num=5;
num1=5;
ﻩﻩ bai=0;
shi=9;
ﻩge=0;
ﻩﻩsh=1;
key=2;
ﻩ }
}
ﻩif(k4==0&&status==0) //数字键4:设置为6 045
ﻩ{
delay(10);
ﻩif(k4==0&&status==0)
ﻩ {
ﻩ num=6;
ﻩﻩﻩnum1=6;
ﻩ ﻩbai=0;
ﻩshi=4;
ﻩ ge=5;
ﻩﻩﻩsh=1;
ﻩﻩkey=1;
}
}
if(k5==0&&status==0)ﻩﻩ //数字键5:设置为7 090
{
ﻩﻩdelay(10);
ﻩﻩif(k5==0&&status==0)
ﻩ{
ﻩ ﻩnum=7;
ﻩ num1=7;
ﻩ bai=0;
shi=9;
ﻩﻩﻩge=0;
ﻩﻩ sh=1;
ﻩﻩﻩkey=2;
}
ﻩ}
}
void show()ﻩﻩ ﻩ //数码管显示
{
ﻩif(sh==1)
ﻩ{
ﻩP1=0x01;
ﻩﻩP0=smg[num];
ﻩP0=0xff;
ﻩﻩP1=0x02;
ﻩ P0=smg[bai];
ﻩ P0=0xff;
P1=0x04;
P0=smg[shi];
ﻩ P0=0xff;
ﻩP1=0x08;
P0=smg[ge];
P0=0xff;
ﻩ}
}
void motor() ﻩ ﻩﻩﻩ//电机运行
{
if(key==1)ﻩ ﻩ //每次转动角度为45度时
ﻩ{
if(c%2==0)
ﻩ{
ﻩx=_crol_(x,1);
ﻩ x=x|_crol_(x,4);
ﻩ}
else
ﻩ{
ﻩ y=_crol_(y,1);
ﻩ y=y|_crol_(y,4);
}
ﻩﻩc=c+1;
ﻩﻩP2=x|y;
}
if(key==2) ﻩﻩ //每次转动角度为90度时
{
x=_crol_(x,1);
ﻩx=x|_crol_(x,4);
ﻩﻩy=_crol_(y,1);
ﻩﻩy=y|_crol_(y,4);
P2=x|y;
}
}
void main()ﻩﻩﻩ ﻩ //主函数
{
ﻩTMOD=0x01;ﻩ ﻩ //T0工作方式1
ﻩTH0=0xd8;ﻩ ﻩ //设初值,0、01秒触发一次
ﻩTL0=0xf0; ﻩ
TR0=0;ﻩ //关闭T0定时器
ﻩET0=1;ﻩ ﻩ //允许T0定时器中断
EA=1;ﻩﻩ ﻩ //开启总中断允许
ﻩP2=0x03;
while(1)
{
scan();
ﻩ show();
ﻩﻩif(num1==0)ﻩﻩﻩﻩ //若电机运行次数已达到设定值,则关定时器
ﻩ{ﻩﻩ ﻩ ﻩ //并将状态位置0
ﻩﻩﻩTR0=0;
ﻩﻩ status=0;
}
}
}
void time0(void) interrupt 1 //中断处理程序
{
TR0=0;
TH0=0xd8;
TL0=0xf0;
clk++;
ﻩif(clk==100)ﻩ ﻩ //每一秒电机运转一次
ﻩ{
ﻩﻩclk=0;
num1--;
motor();ﻩﻩ ﻩﻩ //调用电机运行程序
}
TR0=1;
}
展开阅读全文