武汉理工大学课程设计报告书
实验课程名称计算机接口技术
开课学院计算机科学与技术学院
指导老师姓名李宁
学生姓名
学生专业班级软件1004
2012 —2013学年第二学期
目录
基于ARM的步进电机接口驱动控制设计 (1)
摘要 (1)
关键词 (1)
1.ARM处理器 (2)
1.概念; (2)
2.特点: (2)
3.指令结构 (3)
2.步进电机 (4)
1.步进电机概念 (4)
2.步进电机特性 (4)
3.硬件电路设计 (6)
1.硬件电路设计思路 (6)
2.总体框图设计 (6)
4.外围电路设计分析 (7)
1.步进电机驱动电路 (7)
2.步进电机控制系统图 (9)
5.软件设计 (11)
1.软件设计思路 (11)
2.程序流程图 (11)
6.功能实现及相应代码 (13)
1.主程序: (13)
2. IRQ_UART0() (14)
3. UART0_SendByte() (15)
4. UART0_SendStr() (15)
5. UART0_SendBuf() (16)
6. UART0_Init() (17)
7. IRQ_Eint0() (18)
8. IRQ_Eint3() (18)
9. main() (19)
10. DelayNS() (21)
11. MOTO_Mode1() (22)
12. MOTO_Mode2() (22)
13. MOTO_Mode3() (23)
14. MOTO_Mode4() (25)
15. MOTO_Mode5() (26)
16. MOTO_Mode6() (27)
7. 应用示例 (29)
8.总结 (30)
参考文献 (31)
《计算机接口技术》设计任务
任务:完成一个简单驱动程序的设计,并给出应用示例。
报告格式要求如下:
题目(基于****处理器的****接口驱动设计与实现)
设计任务(建议介绍设计任务)
****处理器(简要介绍该处理器的特点)
****接口(简要介绍该接口的功能特点、使用范围)
硬件设计(给出原理图,并做说明和分析,能给出详细设计最好)
驱动软件设计(给出软件设计说明,包含哪些函数,并详细说明各自功能)
应用示例(给出相应的应用示例,1个或者几个例子都可)
总结(设计中遇到的问题,如何解决的?得与失)
参考文献
本科课程论文评阅表(论点、论据、论证等部分根据自己论文内容填写)
评分标准:
优秀:独立完成,设计完整正确,图、表、代码完整且规范,报告格式规范、条理清晰。
良好:独立完成,设计基本正确,图、表、代码基本规范,报告格式规范、条理清晰。
中等:独立完成,设计内容存在少量缺陷,图、表、代码基本规范,报告完整。及格:基本完成,设计内容存在较大缺陷,图、表、代码不规范,报告内容基本完整。
不及格:未能完成、抄袭他人或设计基本错误。
基于ARM的步进电机接口驱动控制设计
摘要
随着微电子和计算机技术的发展,步进电机的需求量与日俱增,它广泛用于打印机、电动玩具等消费类产品以及数控机床、工业机器人、医疗器械等机电产品中,其在各个国民经济领域都有应用。研究步进电机的控制系统,对提高控制精度和响应速度、节约能源等都具有重要意义。
本控制系统的设计,包括主程序以及各个模块的控制程序,最终实现对步进电机转动方向及转动速度的控制,并且将步进电机的转动速度动态显示在LED数码管上。本系统具有智能性、实用性及可靠性的特点。
关键词
ARM 驱动接口
1.ARM处理器
1.概念;
ARM(Advanced RISC Machines)处理器是Acorn计算机有限公司面向低预算市场设计的第一款RISC微处理器。更早称作Acorn RISC Machine。
ARM处理器本身是32位设计,但也配备16位指令集。一般来讲比等价32位代码节省达35%,却能保留32位系统的所有优势。
ARM的Jazelle技术使Java加速得到比基于软件的Java虚拟机(JVM)高得多的性能,和同等的非Java加速核相比功耗降低80%。CPU功能上增加DSP指令集提供增强的16位和32位算术运算能力,提高了性能和灵活性。ARM还提供两个前沿特性来辅助带深嵌入处理器的高集成SoC器件的调试,它们是嵌入式ICE-RT逻辑和嵌入式跟踪宏核(ETMS)系列。
2.特点:
ARM处理器的三大特点是:耗电少功能强、16位/32位双指令集和合作伙伴众多。
1、体积小、低功耗、低成本、高性能;
2、支持Thumb(16位)/ARM(32位)双指令集,能很好的兼容8位/16位器件;
3、大量使用寄存器,指令执行速度更快;
4、大多数数据操作都在寄存器中完成;
5、寻址方式灵活简单,执行效率高;
6、指令长度固定。
(3)体系结构:
① CISC(Complex Instruction Set Computer,复杂指令集计算机)
在CISC指令集的各种指令中,大约有20%的指令会被反复使用,占整个程序代码的80%。而余下的80%的指令却不经常使用,在程序设计中只占20%。
② RISC(Reduced Instruction Set Computer,精简指令集计算机)
RISC结构优先选取使用频最高的简单指令,避免复杂指令;将指令长度固定,指令格式和寻地方式种类减少;以控制逻辑为主,不用或少用微码控制等RISC体系结构应具有如下特点:
1 采用固定长度的指令格式,指令归整、简单、基本寻址方式有2~3种。
2 使用单周期指令,便于流水线操作执行。
3 大量使用寄存器,数据处理指令只对寄存器进行操作,只有加载/ 存储指令可以访问存储器,以提高指令的执行效率。
(4)寄存器结构
ARM处理器共有37个寄存器,被分为若干个组(BANK),这些寄存器包括:
①31个通用寄存器,包括程序计数器(PC指针),均为32位的寄存器。
②6个状态寄存器,用以标识CPU的工作状态及程序的运行状态,均为32位,目前只使用了其中的一部分。
3.指令结构
ARM微处理器的在较新的体系结构中支持两种指令集:ARM指令集和Thumb指令集。其中,ARM指令为32位的长度,Thumb指令为16位长度。Thumb指令集为ARM指令集的功能子集,但与等价的 ARM代码相比较,可节省30%~40%以上的存储空间,同时具备32位代码的所有优点。本实验采用ARM中ARM7引系列的LPC2131
2.步进电机
1.步进电机概念
步进电机是一种能够将电脉冲信号转换成角位移或线位移的机电元件,它实际上是一种单相或多相同步电动机。单相步进电动机有单路电脉冲驱动,输出功率一般很小,其用途为微小功率驱动。多相步进电动机有多相方波脉冲驱动,用途很广。
使用多相步进电动机时,单路电脉冲信号可先通过脉冲分配器转换为多相脉冲信号,在经功率放大后分别送入步进电动机各相绕组。每输入一个脉冲到脉冲分配器,电动机各相的通电状态就发生变化,转子会转过一定的角度(称为步距角)。
正常情况下,步进电机转过的总角度和输入的脉冲数成正比;连续输入一定频率的脉冲时,电动机的转速与输入脉冲的频率保持严格的对应关系,不受电压波动和负载变化的影响。由于步进电动机能直接接收数字量的输入,所以特别适合于微机控制。
2.步进电机特性
步进电机转动使用的是脉冲信号,而脉冲是数字信号,这恰是计算机所擅长处理的数据类型。从20世纪80年代开始开发出了专用的IC驱动电路,今天,在打印机、磁盘器等的OA装置的位置控制中,步进电机都是不可缺少的组成部分之一。总体上说,步进电机有如下优点:
①不需要反馈,控制简单。
②与微机的连接、速度控制(启动、停止和反转)及驱动电路的设计比较简单。
③没有角累积误差,停止时也可保持转距。
④没有转向器等机械部分,不需要保养,故造价较低。
⑤即使没有传感器,也能精确定位。
⑥根椐给定的脉冲周期,能够以任意速度转动。但是,这种电机也有自身的缺点。
⑦难以获得较大的转矩
⑧不宜用作高速转动
⑨在体积重量方面没有优势,能源利用率低。
⑩超过负载时会破坏同步,高速工作时会发出振动和噪声。
实验所用电机:28BYJ-48步进电机
步进电机28BYJ48型四相八拍电机,电压为DC5V—DC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)
由于步进电机的驱动电流较大,单片机不能直接驱动,一般都是使用ULN2003达林顿阵列驱动,当然,使用下拉电阻或三极管也是可以驱动的,只不过效果不是那么好,产生的扭力比较小。
3.硬件电路设计
1.硬件电路设计思路
步进电机控制系统共分为四个模块:ARM模块、控制模块、数码显示模块、步进电机驱动模块。
ARM最小系统主要由复位电路和时钟电路组成。复位电路为ARM系统提供可靠复位,使ARM能正常启动。时钟电路采用外部时钟方式,保证ARM个功能部件都是以时钟频率为基准,有条不紊地一拍一拍地工作。
步进电机驱动模块选用八NPN达林顿连接晶体管2803为步进电机提供脉冲信号,驱动步进电机转动。该模块与ARM的P1.22—P1.25相连。
2.总体框图设计
总体设计框图如图2-1所示:
图2-1总体设计框图
说明如下:
(1) ARM接受按键信息,改变系统内部变量值。
(2) ARM输出脉冲信号,控制步进电机转动。
4.外围电路设计分析
1.步进电机驱动电路
本系统的设计目的为了高效控制步进电机的转动,因此需要将脉冲转化为步进角度,才能控制步进电机转动,我们在这里采用ULN2003为步进电机提供脉冲信号。管脚如图3-1所示:
图3-1内部管脚图
ULN2003内部集成了一个消线圈反电动势的二极管,可用来驱动继电器。它是双列16脚封装,NPN晶体管矩阵,最大驱动电压=50V,电流=500mA,输入电压=5V,适用于TTL COMS,由达林顿管组成驱动电路。 ULN是集成达林顿管IC,内部还集成了一个消线圈反电动势的二极管,它的输出端允许通过电流为200mA,饱和压降VCE 约1V左右,耐压BVCEO 约为36V。采用集电极开路输出,输出电流大,故可直接驱动继电器或固体继电器,也可直接驱动低压灯泡。通常单片机驱动ULN2003时,上拉2K的电阻较为合适,同时,COM引脚应该悬空或接电源。
ULN2003是一个非门电路,包含7个单元,单独每个单元驱动电流最大可达350mA,9脚可以悬空。比如1脚输入,16脚输出,你的负载接在VCC与16脚之间,不用9脚。
ULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。可直接驱动继电器等负载。输入5VTTL电平,输出可达500mA/50V。
ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。该电路的特点如下: ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作
电压下它能与TTL和CMOS电路直接相连,可以直接处理原先需要标准逻辑缓冲器。
ULN2003 是高压大电流达林顿晶体管阵列系列产品,具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动的系统。引脚如图3-7所示:
图3-7 ULN2003芯片引脚图
ULN2003芯片引脚介绍:
引脚1:CPU脉冲输入端,端口对应一个信号输出端。
引脚2:CPU脉冲输入端。
引脚3:CPU脉冲输入端。
引脚4:CPU脉冲输入端。
引脚5:CPU脉冲输入端。
引脚6:CPU脉冲输入端。
引脚7:CPU脉冲输入端。
引脚8:接地。
引脚9:该脚是内部7个续流二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。用于感性负载时,该脚接负载电源正极,实现续流作用。如果该脚接地,实际上就是达林顿管的集电极对地接通。
引脚10:脉冲信号输出端,对应7脚信号输入端。
参考接法如图3-8所示:
图3-8 参考电路接法
引脚11:脉冲信号输出端,对应6脚信号输入端。
引脚12:脉冲信号输出端,对应5脚信号输入端。
引脚13:脉冲信号输出端,对应4脚信号输入端。
引脚14:脉冲信号输出端,对应3脚信号输入端。
引脚15:脉冲信号输出端,对应2脚信号输入端。
引脚16:脉冲信号输出端,对应1教信号输入端。
驱动电路如图3-9所示:
图3-9 步进电机驱动原理图
2.步进电机控制系统图
通过上述对步进电机控制系统设计与分析,步进电机控制系统总体设计电路如图3-2所示:
图3-2 步进电机控制系统总体设计电路图
5.软件设计
1.软件设计思路
步进电机控制系统的软件需要同时完成读取按键、处理键盘、控制步进电机转动等任务,这就必须通过查询技术来实现。
在本设计中,主程序采用查询方式扫描键盘端口,检测按键动作是否发生,若有按键动作则处理键盘,根据按键实现键盘的实时处理功能。查询控制步进电机的转动。
2.程序流程图
步进电机控制系统的主程序在对整个系统初始化后主要完成读键盘和处理键盘的功能,如图4-1所示:
图4-1 步进电机控制系统主程序流程图
系统上电复位后,先调用初始化子程序,对步进电机各端口,相关参数进行初始化。初始化完成后,步进电机处于停止状态,然后循环扫描按键是否被按下。如果检测到有按键被按下,先软件去抖动,确定被按下后则执行相应的子程序,然后返回,继续执行主程序。
6.功能实现及相应代码
1.主程序:
/**************************************************************************** * 文件名:main.c
* 功能:LED显示控制。
* 通过GPIO控制步进电机
* 说明:将跳线JP14和JP19全部短接。
****************************************************************************/ #include "config.h"
#define LED1 1<<18 // P2.16
#define MOTOA 1<<22 // P1.22
#define MOTOB 1<<23 // P1.23
#define MOTOC 1<<24 // P1.24
#define MOTOD 1<<25 // P1.25
#define LEDCON 0x03c40000 // LED控制字
//#define MOTOCON 0x0f000000 // MOTO控制字
#define GPIOSET(PIN) IO1SET = PIN // 方便修改置位端口
#define GPIOCLR(PIN) IO1CLR = PIN // 方便修改清位端口
uint8 k;
const uint32 KEY1 = 1 << 16; // P0.16连接KEY1
uint8 keynum;
volatile uint8 rcv_new; // 接收新数据标志
uint8 rcv_buf; // UART0数据接收缓冲区
uint32 time =1000;
char data[] = {"你选择的是正向单四拍方式,步距角1.8度: "};
char datb[] = {"你选择的是正向双四拍方式,步距角0.9度: "};
char datc[] = {"你选择的是正向单双八拍方式,步距角0.45度: "};
char datd[] = {"你选择的是反向单四拍方式,步距角1.8度"};
char date[] = {"你选择的是反向双四拍方式,步距角0.9度: "};
char datf[] = {"你选择的是反向单双八拍方式,步距角0.45度: "};
char INFO[] = {"这是EasyARM2131步进电机程序,您将可以选择控制电机的转动方向和方式;\
按键Key1 控制电机的开始和停止;\
1.正向单四拍方式;\
2.正向双四拍方式;\
3.正向单双八拍方式;\
4.反向单四拍方式;\
5.反向双四拍方式;\
6.反向单双八拍方式;\
请输入数字选择对应方式. "};
/* 定义串口模式设置数据结构*/
typedef struct UartMode
{
uint8 datab; // 字长度,5/6/7/8可选
uint8 stopb; // 停止位,1/2可选
uint8 parity; // 奇偶校验位,0-无校验,1-奇校验,2-偶校验
}UARTMODE;
void DelayNS(uint32 dly);
void MOTO_Mode1(uint8 i); // A-B-C-D
void MOTO_Mode2(uint8 i); // AB-BC-CD-DA-AB
void MOTO_Mode3(uint8 i); // A-AB-B-BC-C-CD-D-DA-A
void MOTO_Mode4(uint8 i); // D-C-B-A
void MOTO_Mode5(uint8 i); // BA-AD-DC-CB-BA
void MOTO_Mode6(uint8 i); //A-AD-D-DC-C-CB-B-BA-A
2.IRQ_UART0()
/*
**************************************************************************************** *****************
** 函数名称:IRQ_UART0()
** 函数功能:串口0接收中断服务程序
** 入口参数:无
** 出口参数:无
**************************************************************************************** *****************
*/
void __irq IRQ_UART0 (void)
{
if ((U0IIR & 0x0F) == 0x04)
rcv_new = 1; // 设置接收到新的数据标志
rcv_buf = U0RBR; // 读取FIFO的数据,并清除中断
VICVectAddr = 0x00; // 中断处理结束
}
3.UART0_SendByte()
/*
**************************************************************************************** *****************
** 函数名称:UART0_SendByte()
** 函数功能:向串口0发送1字节数据
** 入口参数:dat 要发送的数据
** 出口参数:无
**************************************************************************************** *****************
*/
void UART0_SendByte (uint8 dat)
{
U0THR = dat; // 要发送的数据
while ((U0LSR & 0x20) == 0);// 等待数据发送完毕
}
4.UART0_SendStr()
/*
**************************************************************************************** *****************
** 函数名称:UART0_SendStr()
** 函数功能:向串口发送一字符串
** 入口参数:str 要发送的字符串的指针
** 出口参数:无
**************************************************************************************** *****************
*/
void UART0_SendStr (char *str)
{
while (1)
{
if (*str == '\0') break; // 遇到结束符,退出
UART0_SendByte(*str++); // 发送数据
}
}
5.UART0_SendBuf()
/*
**************************************************************************************** *****************
** 函数名称:UART0_SendBuf()
** 函数功能:向串口发送8字节数据
** 入口参数:无
** 出口参数:无
**************************************************************************************** *****************
*/
void UART0_SendBuf (uint8 t)
{
uint8 connum;
connum=t;
switch(connum)
{
case 1:UART0_SendStr(INFO);break;
case 2:UART0_SendByte(rcv_buf);break;
case 3:UART0_SendStr(data);break;
case 4:UART0_SendStr(datb);break;
case 5:UART0_SendStr(datc);break;
case 6:UART0_SendStr(datd);break;
case 7:UART0_SendStr(date);break;
case 8:UART0_SendStr(datf);break;
default:break;
}
}
6.UART0_Init()
/*
**************************************************************************************** *****************
** 函数名称:UART0_Init()
** 函数功能:串口初始化,设置工作模式和波特率。
** 入口参数:baud 波特率
** set 模式设置(UARTMODE数据结构)
** 出口参数:1-初始化成功, 0-初始化失败
**************************************************************************************** *****************
*/
int8 UART0_Init (uint32 baud, UARTMODE set)
{
uint32 bak;
/* 参数过滤*/
if ((baud ==0 ) || (baud > 115200)) return (0);
if ((set.datab <5) || (set.datab > 8)) return (0);
if ((set.stopb == 0) || (set.stopb > 2)) return (0);
if (set.parity > 4) return (0);
/* 设置串口波特率*/
U0LCR = 0x80; // DLAB = 1
bak = (Fpclk >> 4) / baud;
U0DLM = bak >> 8;
U0DLL = bak & 0xFF;
/* 设置串口模式*/
bak = set.datab - 5; // 设置字长
if (set.stopb == 2) bak |= 0x04; // 判断是否为2位停止位
if (set.parity != 0)
{
set.parity = set.parity - 1;
bak |= 0x08;
}
bak |= set.parity << 4; // 设置奇偶校验
U0LCR = bak;