admin管理员组

文章数量:1531374

2024年1月27日发(作者:)

基于proteus的步进电机电机仿真

摘要:步进电机广泛应用在生产实践的各个领域。它最大的应用是在数控机床的制造中,因为步进电机不需要A/D转换,能够直接将数字脉冲信号转化成为角位移,所以被认为是理想的数控机床的执行元件。本设计利用proteus仿真软件进行电路仿真,系统通过设置四个按键分别控制不进电机的起止、圈数、方向、不进速度,使用1602液晶显示以上参数。整个系统具有稳定性好,实用性强,操作界面友好等优点。

关键词:proteus 仿真 不进电机 拍数

一、 Proteus简介

Proteus ISIS是英国Labcenter公司开发的电路分析与实物仿真软件。它运行于Windows操作系统上,可以仿真、分析(SPICE)各种模拟器件和集成电路,该软件的特点是:

①实现了单片机仿真和SPICE电路仿真相结合。具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS232动态仿真、I2C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。

②支持主流单片机系统的仿真。目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列以及各种外围芯片。

③提供软件调试功能。在硬件仿真系统中具有全速、单步、设置断点等调试功能,同时可以观察各个变量、寄存器等的当前状态,因此在该软件仿真系统中,也必须具有这些功能;同时支持第三方的软件编译和调试环境,如Keil C51

uVision2等软件。

④具有强大的原理图绘制功能。总之,该软件是一款集单片机和SPICE分析于一身的仿真软件,功能极其强大。

二、整体电路分析

如下图,整个设计以STC89C51单片机为中心,由复位电路,时钟电路,电机驱动,步进电机,显示电路等组成,硬件模块如图2-1所示:

图1 硬件模块图

通过按键进行相应的参数设定,单片机接收到信号后经过判断驱动电机驱动模块,然后由驱动电路驱动步进电机运转,并用1602显示设置的参数。

三、系统硬件电路选择与设计

1、主控器的选择

按照题目要求本次主控单元使用C51单片机对整个系统进行控制。STC89C51RC包含512字节RAM 、32条I/O口线、3个16位定时/计数器、8输入4优先级嵌套中断结构、1个串行I/O口(可用于多机通信、I/O扩展或全双工UART)以及片内振荡器和时钟电路。此外,由于器件采用了静态设计,可提供很宽的操作频率范围(频率可降至0)。可实现两个由软件选择的节电模式、空闲模式和掉电模式。空闲模式冻结CPU,但RAM、定时器、串口和中断系统仍然工作。掉电模式保存RAM的内容,但是冻结振荡器,导致所有其它的片内功能停止工作。由于设计是静态的,时钟可停止而不会丢失用户数据。运行可从时钟停止处恢复。所以该单片机可以满足系统要求,电路图如下:

21RS22RW23E242526272839D038D137D236D335D434D533D632D7101112S113S214S315S41617P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RDABCD12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15U1AT89C51XTAL1XTAL2PSENALEEARST

图2 单片机最小系统电路图

2、步进电机选择

步进电机是一种能够将电脉冲信号转换成角位移或线位移的机电元件,它实际上是一种单相或多相同步电动机。单相步进电动机有单路电脉冲驱动,输出功率一般很小,其用途为微小功率驱动。多相步进电动机有多相方波脉冲驱动,用途很广。本设计使用的是四相三拍步进电机,连接图如下:

U2ABCD12345671B2B3B4B5B6B7BCOM1C2C3C4C5C6C7C9110+88.8ULN2004A

图3 步进电机接线图

3、驱动电路的选择

驱动模块我们使用集成驱动芯片ULN2003,给芯片是高耐压、大电流达林顿管由七个硅NPN 达林顿管组成。该电路的特点如下:ULN2003 的每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS

电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。ULN2003 工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V 的电压,输出还可以在高负载电流并行运行。1脚输入,16脚输出,你的负载接在VCC与16脚之间,不用9脚。

图4 ULN2003内部结构图 图5 ULN2003管脚图

ULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。可直接驱动继电器等负载。所以足以满足驱动步进电机的要求,连接图如下:

U2ABCD12345671B2B3B4B5B6B7BCOM1C2C3C4C5C6C7C9110ULN2003A

图6 uln2003接线图

4、显示电路的

LCD显示模块是把LCD显示屏、背景光源、线路 板和驱动集成电路等部件构造成1个整体作为1个独 立部件使用,只留1个接口与外部通信。显示模块通 过这个接口接收显示的命令和数据,并按指令和数据 的要求进行显示,外部电路通过这个接口读出显示模 块的工作状态和显示数据。1602液晶模块内部的字 符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大 小写、常用的符号和日文假名等,每1个字符都有1个 固定的代码。用户对模块写入适当的控制命令,即可 完成清屏、显示、地址设置等操作 。设计采用并行方式控制,LCD与单片机的通讯接口电路如图3所示采用直连的方法。

LM016LGND1VSSVCC2VDDVCC/V3DDVEERSRWERS4RW5E6D07D18D29D310D411D512D613D714D0D1D2D3D4D5D6D7

图7 1602显示电路接线图

5键盘输入模块电路

设计中,键盘采用非编码键盘系统中的独立式按 键结构。键盘工作方式采用定时扫描方式。采用定时 器TO定时,通过输出数据,识别按键的工作状态。键 盘主要用来提供人机接口,电路如图3所示,采用独立 式按键电路,各按键开关均采用了上拉电阻,保证在按 键断开时,各I/O有确定的高电平。按键功定义如 下:当P3.2按下时,步进电机开始加速;当P3.3按下 时,步进电机开始减速;当P3.4按下时,步进电机开始 正转;当P3.5按下时,步进电机开始反转。按键抖动的消除采用软件消抖实现。连接图如下:

起始键S1圈数键S2方向键S3S4

图8 按键接连接图

四、系统软件设计

1、软件流程图

GND速度键

图9 系统流程图

2程序代码

见附件。

五、总结

采用模块程序设计,逐个模块调好以后,再进行系统程序总调试。利用仿真软件Proteus及KeilC5l进 行调试。 系统实现了可程序设定和显示步进角、步进方向 和步进速度,支持用开关量单独控制步进电机的转向, 转速。电路简单可靠,结构紧凑,控制灵活,成本低,可 移植性强。经实验验证,本系统对步进电机的各项控 制都能达到比较理想的效果,具有较高的实用价值。通过此次课程设计,我不仅将知识融会贯通,而且在查找资料的过程中也了解了许多课外知识,开拓了视野,使自己在专业知识方面和动手能力方面有了很大的提高,让我学会了理论到实践的转化,即如何将自己学到的运用到以后的生活和工作中,同时,也让我意识到团队精神的重要性。

此外,感谢丁老师的悉心教导以及同学的帮助,正是王老师细心的辅导和提供的一些参考资料还有同学们的互相帮助,让我顺利的完成了毕业设计,相信这对我以后的生活和工作都会有很大的帮助。

六参考文献

[1]徐薇莉,曹柱中.控制理论与设计[M].上海:上海交通大学出版 社.2003.

[2]黄 坚.自动控制原理及其应用[M].北京:高等教育出版社, 2004.

[3]先锋工作室.单片机程序设计实例[M].北京:清华大学出版社, 2003.’

[4]王幸之,钟爱琴.AT89系列单片机原理及接口技术[M].北京:北京航天大学出版社,2004.

[5]康华光,陈大钦.模拟电子电路[M].北京:高教育出版社,2004.

七附录

(1) 整体电路图

LCD2LM016LRP1123456789D0D1D2D3D4D5D6D7ABCD1234567U21B2B3B4B5B6B7BCOM1C2C3C4C5C6C7C9110-4.81GND1VSSVCC2VDDVCC/V3DDVEERSRWERS4RW5E6D07D18D29D310D411D512D613D714D0D1D2D3D4D5D6D7ULN2004ARESPACK-821RS22RW23E242526272839D038D137D236D335D434D533D632D7101112S113S214S315S41617P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RDP0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15U1起始键圈数键方向键S3S1AT89C51S2S4XTAL1XTAL2PSENALEEAABCD12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7RSTGND速度键

(2)程序代码

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

unsigned char code FFW[8]={0xfe,0xfc,0xfd,0xf9,0xfb,0xf3,0xf7,0xf6}; //反转

unsigned char code REV[8]={0xf6,0xf7,0xf3,0xfb,0xf9,0xfd,0xfc,0xfe}; //正转

//unsigned char code FFW[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //反转

//unsigned char code REV[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; //正转

sbit K1 = P3^2; //运行与停止

sbit K2 = P3^3; //设定圈数

sbit K3 = P3^4; //方向转换

sbit K4 = P3^5; //速率调整

sbit LCD_RS = P2^0;

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

bit on_off=0; //运行与停止标志

bit direction=1; //方向标志

bit rate_dr=1; //速率标志

bit snum_dr=1; //圈数标志

uchar code cdis1[ ] = {"NO. "};

uchar code cdis2[ ] = {" 2012/5/24"};

uchar code cdis3[ ] = {" STOP "};

uchar code cdis4[ ] = {"NUM: RATE: "};

uchar code cdis5[ ] = {" RUNNING "};

uchar m,v=0,q=0;

uchar number=0,number1=0;

uchar snum=20,snum1=20; //预设定圈数

uchar rate=3; //预设定速率

uchar data_temp,data_temP0,data_temp2;

/********************************************************/

/*

/* 延时t毫秒

/* 11.0592MHz时钟,延时约1ms

/*

/********************************************************/

void delay(uint t)

{

uchar k;

while(t--)

{

for(k=0; k<124; 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); // m = 0;

while(cdis2[m] != '0')

{

lcd_wdat(cdis2[m]); // m++;

}

delay(3000); //

lcd_pos(0); // m = 0;

while(cdis3[m] != '0')

{ // lcd_wdat(cdis3[m]);

m++;

}

lcd_pos(0x40); // m = 0;

while(cdis4[m] != '0')

{

lcd_wdat(cdis4[m]); // m++;

}

显示字符

设置显示位置为第二行第1个字符

显示字符

延时

设置显示位置为第一行的第1个字符

显示字符

设置显示位置为第二行第1个字符

显示字符

for(m=0;m<2;m++)

{

lcd_pos(0x0c+m); //显示方向符号

lcd_wdat(0x3e);

}

}

/********************************************************/

/*

/*数据转换子程序

/*

/********************************************************/

void data_conv()

{

data_temP0=data_temp/10; //高位

if(data_temP0==0)

{data_temP0=0x20;} //高位为0不显示

else

{data_temP0=data_temP0+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_temP0);

lcd_pos(0x45);

lcd_wdat(data_temp2);

data_temp = rate; //显示速率

data_conv();

lcd_pos(0x4d);

lcd_wdat(data_temP0);

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; P0 =0x0f;

lcd_pos(0); //设置显示位置为第一行的第1个字符

m = 0;

while(cdis3[m] != '0')

{ lcd_wdat(cdis3[m]); //STOP

m++; }

motor_DR(); //

snum=snum1; //

number1=0; //清圈数计数器

}

}

/********************************************************

*

* 主程序

*

*********************************************************/

main()

{

TMOD = 0x01; //T0定时方式1

TL0 = 0x33;

TH0 = 0xf5;

EA = 1;

ET0 = 1;

LCD_init_DIS();

P1=0;

while(1)

{

if(K1==0)

{

//beep();

while(K1==0); //等待键释放

on_off=~on_off;

motor_RUN();

} //K1 end

/********************************************************/

if(K2==0)

{

if(snum_dr==1)

{ snum++;

snum1=snum;

if(snum==0x14)

{ snum_dr=~snum_dr;}

}

else

{snum--;

snum1=snum;

if(snum==0x01)

{ snum_dr=~snum_dr; }

}

} //K2 end

/********************************************************/

if(K3==0)

{

direction=~direction;

motor_DR();

}//K3 end

/********************************************************/

if(K4==0)

{

if(rate_dr==1)

{ rate++;

if(rate==0x10)

{ rate_dr=~rate_dr;}

}

else

{

rate--;

if(rate==0x01)

{ rate_dr=~rate_dr; }

}

} //K4 end

/********************************************************/

if(number1==snum1) //与设定圈数是否相等

{ number1=0;

on_off=0;

TR0=0;

snum=snum1;

P1=0x0f;

motor_RUN();

}

data_dis();

} // while(1) end

} //main end

/********************************************************/

/*

/* 定时器 T0 中断

/*

/********************************************************/

void motor_onoff() interrupt 1

{

TL0 = 0x33;

TH0 = 0xf5;

q++;

if(q < rate)

{ return; }

else

{ q=0;

number++; //脉冲计数

if(number==64) //64个脉冲电机转一圈

{ snum--;

number=0;

number1++; } //

if(direction==1) // { if(v<8)

{P1 = FFW[v];v++;} // if(v==8)

{ v=0; }

}

else

{ if(v<8)

{P1 = REV[v];v++;} // if(v==8)

{ v=0; }

}

}

}

电机转动圈数方向标志

取数据,正转取数据,反转起止

志=2

圈数 方向 速度

本文标签: 显示步进电机电路