51单片机控制四线步进电机驱动实现正反转和任意角度速度控制
最近有好多小伙伴私信我说,导师给他们布置了关于四线步进电机控制的相关设计,问我能不能写个类似的文章,今天我刚好有点时间,我们就一起探讨一下吧。
想要弄清楚步进电机的控制方式先要弄清楚它的接线方式和工作原理
步进电机结构和工作原理:
1.步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电动机的转速、停止的位置只取决于控制脉冲信号的频率和脉冲数。
2.脉冲数越多,电机转动的角度越大。
3.脉冲的频率越高,电机转速越快,但不能超过最高频率,否则电机的力矩迅速减小,电机不转。按力矩产生的原理可以分为:
(1)反应式:转子无绕组,由被激磁的定子绕组产生反应力矩实现步进运行
(2)激磁式:定、转子均有激磁绕组(或转子用永久磁钢),由电磁力矩实现步进运行按输出力矩大小可分为:
(1)伺服式:输出力矩在百分之几之几至十分之几(N.m)只能驱动较小的负载,要与液压扭矩放大器配用,才能驱动机床工作台等较大的负载
(2)功率式:输出力矩在5~50 N.m以上,可以直接驱动机床工作台等较大的负载按定子数可分为:
(1)单定子式(2)双定子式(3)三定子式(4)多定子式按各相绕组分布可分为;
(1)径向分布式:电机各相按圆周依次排列
步进电机和驱动板的连接方式:
鉴于时间原因我就用仿真软件做了一个单片机四线步进电机驱动项目 供大家参考学习,希望你看完后会有所收获。
项目软件程序功能:当按下SW1时步进电机正转,按下SW2后步进电机反转,并可以根据源码任意调节旋转速度和每一个脉冲旋转角度
以下是仿真图:
程序参考源代码如下:经过实际验证,软硬件可以实现设计功能,实验成功。
/C语言程序:/
#include <reg52.h> //
#define uchar unsigned char
#define uint unsigned int
uchar table_begin;
uint maichong; //脉冲
uchar zhuansu; //转速
uchar flag; //方向
sbit key_fuwei=P3^0; //复位键
sbit key_z=P3^1; //正转键
sbit key_f=P3^2; //反转键
sbit key_jia=P3^3; //加速键
sbit key_jian=P3^6; //减速键
sbit A1=P2^0;
sbit A2=P2^1;
sbit A3=P2^2;
sbit A4=P2^3;
void display();
void delayms(xms);
void delay(uchar x)
{
uchar i,j; //延时
for(i=0;i<x;i++)
for(j=100;j>0;j–);
}
void fuwei(void) //复位
{
flag=2;
zhuansu=0;
}
/*void Display(void) //显示
{
unsigned char b1, b2;
b1=zhuansu/10;
b2=zhuansu%10;
if(flag == 0) //0
P0=0x71;//显示F
else
P0=0x79;
A1=0;
delayms(3);
A1=1;
P0=0x40;
A2=0; //显示--
delayms(3);
A2=1;
P0=table2[b1];
A3=0; //显示十位
delayms(3);
A3=1;
P0=table2[b2];
A4=0;
delayms(3); //显示个位
A4=1;
void display()
{
uchar b1,b2,b3,b4;
if(flag0)
P0=0x71;//显示F
else
P0=0x79;
if(flag1)
P0=0x7c;//显示b
else
P0=0x71;
b1=10;
b2=0x3f;
b3=zhuansu/10;
b4=zhuansu%10;
//P0=table2;
A1=0; //P2.0
delay(1);
A1=1;
P0=b2;
A2=0; //P2.1
delay(1);
A2=1;
P0=table2[b3];
A3=0; //P2.3
delay(1);
A3=1;
P0=table2[b4];
A4=0; //P2.4
delay(1);
A4=1;
}
void key() //按键扫描
{
if(key_fuwei0)
{
delay(5);
if(key_fuwei0)
fuwei();
}
if(key_z0)
{
delay(5);
if(key_z0)
{
flag=0;
zhuansu=10;
while(key_z0);
}
}
if(key_f0)
{
delay(5);
if(key_f0)
{
flag=1;
zhuansu=10;
while(key_f0);
}
}
if(key_jia0)
{
delay(5);
if(key_jia0)
{
zhuansu++;
if(zhuansu21)
zhuansu=20;
while(key_jia0);
}
}
if(key_jian0)
{
delay(5);
if(key_jian0)
{
zhuansu–;
if(zhuansu<=0)
zhuansu=0;
while(key_jian==0);
}
}
}
void dispose() //脉冲函数
{
switch(zhuansu)
{
case 0: flag=2; break;
case 1: maichong=300; break;
case 2: maichong=295; break;
case 3: maichong=290; break;
case 4: maichong=280; break;
case 5: maichong=260; break;
case 6: maichong=240; break;
case 7: maichong=200; break;
case 8: maichong=180; break;
case 9: maichong=160; break;
case 10: maichong=120; break;
case 11: maichong=80; break;
case 12: maichong=70; break;
case 13: maichong=60; break;
case 14: maichong=40; break;
case 15: maichong=35; break;
case 16: maichong=30; break;
case 17: maichong=25; break;
case 18: maichong=20; break;
case 19: maichong=15; break;
case 20: maichong=10; break;
}
if(flag0)
table_begin=0;
else
if(flag1)
table_begin=4;
}
void zhuandong(void)
{
uint i,j;
if(zhuansu>0&&zhuansu<=20)
{
for(j=0+table_begin;j<4+table_begin;j++)
{
P1=table1[j];
for(i=0;i<maichong;i++)
display();
}
}
}
……………………
…
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 程序完整的源代码和 设计文件,请在下方留言或者私信我,看到后会第一时间回复。
如果喜欢我的文章请评论转发加关注哦。
看单片机如何控制PWM信号实现直流电机转速控制
设计中采用了专门的芯片组成了PWM信号的发生系统并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节从而控制其输入信号波形等均作了详细的阐述。另外本系统中使用了红外对管对直流电机的转速进行测量,经过整形电路后将测量值送到单片机,并且最终作为反馈值输入到单片机进行PID运算从而实现了对直流电机速度的控制。在软件方面,文章中详细介绍了PID运算程序初始化程序等的编写思路和具体的程序实现。
1 单片机最小系统:单片机最小系统由51单片机,晶振电路,复位电路,电源组成。大家都比较熟悉,这里不再赘述。
2 四位数码管显示:在应用系统中,设计要求不同,使用的LED显示器的位数也不同,因此就生产了位数,尺寸,型号不同的LED显示器供选择,在本设计中,选择4位一体的数码型LED显示器,简称“4-LED”。本系统中前三位显示电压的整数位,最后一位显示转速的小数位。4-LED显示器引脚如图2所示,是一个共阴极接法的4位LED数码显示管,其中a,b,c,e,f,g为4位LED各段的公共输出端,1、2、3、4分别是每一位的位数选端,dp是小数点引出端,4位一体LED数码显示管的内部结构是由4个单独的LED组成,每个LED的段输出引脚在内部都并联后,引出到器件的外部。
3 电机驱动电路:电机驱动电中是采用ULN2003来驱动。ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。该电路的特点:ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作电压下它能与TTL和CMOS电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据,输入5VTTL电平,输出可达500mA/50V。ULN2003的引脚图,其中IN1~IN7为输入控制端;OUT1~OUT7为输出端;8脚为芯片的接地端;9脚为公共端,该脚是内部7个续流二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。用于感性负载时,该脚接负载电源正极,实现续流作用。如果该脚接地,实际上就是达林顿管的集电极对地接通。
当P1.0中为高电平时,其内部三极管导通,使电机转动。当P1.0为低电平时,内部三极管截止,电路断开,电机停止转动。所以在程序中可以利用P1.0口输出PWM波来控制电机的转速。
4 红外测速电路:发射管工作时发出红外线,当接收管收到红外信号时,其电阻变小(本设计相当于从无穷大变到1k左右)。利用其电阻变化,改变接收管分压情况。挡片是利用圆盘上剪四个孔,当挡片随电机转动时,接收管两端电平发生变化,产生脉冲。
5 整形电路:本设计的整形电路是用555定时器接成的施密特触发器。
6 源程序:
#include reg52.h
#define uchar unsigned char
#define uint unsigned int
uchar code table[10]={0x3f,0x06,0x5b,
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管显示码(0-9)
sbit xiaoshudian=P0^7;
sbit wei1=P2^4; //数码管位选定义
sbit wei2=P2^5;
sbit wei3=P2^6;
sbit wei4=P2^7;
sbit beep=P2^3; //蜂鸣器控制端
sbit motor = P1^0; //电机控制
sbit s1_jiasu = P1^4; //加速按键
sbit s2_jiansu= P1^5; //减速按键
sbit s3_jiting=P1^6; //停止/开始按键
uint pulse_count; //INT0接收到的脉冲数
uint num=0; //num相当于占空比调节的精度
uchar speed[3]; //四位速度值存储
float bianhuasudu; //当前速度(理论计算值)
float reallyspeed; //实际测得的速度
float vv_min=0.0;vv_max=250.0;
float vi_Ref=60.0; //给定值
float vi_PreError,vi_PreDerror;
uint pwm=100; //相当于占空比标志变量
int sample_time=0; //采样标志
float v_kp=1.2,v_ki=0.6,v_kd=0.2; //比例,积分,微分常数
void delay (uint z)
{
uint x,y;
for(x=z;x0;x--)
for (y=20;y0;y--);
}
void time_init()
{
ET1=1; //允许定时器T1中断
ET0=1; //允许定时器T0中断
TMOD = 0x15; //定时器0计数,模式1;定时器1定时,模式1
TH1 = (65536-100)/256; //定时器1值,负责PID中断 ,0.1ms定时
TL1 = (65536-100)%6;
TR0 = 1; //开定时器
TR1 = 1;
IP=0X08; //定时器1为高优级
EA=1; //开总中断
}
void keyscan()
{
float j;
if(s1_jiasu==0) //加速
{
delay(20);
if(s1_jiasu==0)
vi_Ref+=10;
j=vi_Ref;
}
while(s1_jiasu==0);
if(s2_jiansu==0) //减速
{
delay(20);
if(s2_jiansu==0)
vi_Ref-=10;
j=vi_Ref;
}
while(s2_jiansu==0);
if(s3_jiting==0)
{
delay(20);
motor=0;
P1=0X00;
P3=0X00;
P0=0x00;
}
while(s3_jiting==0);
}
float v_PIDCalc(float vi_Ref,float vi_SpeedBack)
{
register float error1,d_error,dd_error;
error1=vi_Ref-vi_SpeedBack; //偏差的计算
d_error=error1-vi_PreError; //误差的偏差
dd_error=d_error-vi_PreDerror; //误差变化率
vi_PreError=error1; //存储当前偏差
vi_PreDerror=d_error;
bianhuasudu=(v_kp*d_error+v_ki*vi_PreError+v_kd*dd_error);
return (bianhuasudu);
}
void v_Display()
{
uint sudu;
sudu=(int)(reallyspeed*10); //乘以10之后强制转化成整型
speed[3]=sudu/1000; //百位
speed[2]=(sudu00)/100; //十位
speed[1]=(sudu0)/10; //个位
speed[0]=sudu; //小数点后一位
wei1=0; //第一位打开
P0=table[speed[3]];
delay(5);
wei1=1; //第一位关闭
wei2=0;
P0=table[speed[2]];
delay(5);
wei2=1;
wei3=0;
P0=table[speed[1]];
xiaoshudian=1;
delay(5);
wei3=1;
wei4=0;
P0=table[speed[0]];
delay(5);
wei4=1;
}
void BEEP()
{
if((reallyspeed)=vi_Ref+5||(reallyspeed
{
beep=~beep;
delay(4);
}
}
void main()
{
time_init();
motor=0;
while(1)
{
v_Display();
BEEP();
}
if(s3_jiting==0) //对按键3进行扫描,增强急停效果
{
delay(20);
motor=0;
P1=0X00;
P3=0X00;
P0=0x00;
}
while(s3_jiting==0);
}
void timer0() interrupt 1
{
}
void timer1() interrupt 3
{
TH1 = (65536-100)/256; //1ms定时
TL1 = (65536-100)%6;
sample_time++;
if(sample_time==5000) //采样时间0.1ms*5000=0.5s
{
TR0=0; //关闭定时器0
sample_time=0;
pulse_count=TH0*255+TL0; //保存当前脉冲数
keyscan(); //扫描按键
reallyspeed=pulse_count/(4*0.6); //计算速度
pwm=pwm+v_PIDCalc(vi_Ref,reallyspeed);
if(pwm
if(pwm100)pwm=100;
TH0=TL0=0;
TR0=1; //开启定时器0
}
num++;
if(num==pwm) //此处的num值,就是占空比
{
motor=0;
}
if(num==100) //100相当于占空比调节的精度
{
num=0;
motor=1;
}
}
相关问答
51单片机电机 调速的方法?单片机电机调速可以通过PWM(脉宽调制)实现,通过控制PWM的占空比可以调节电机的转速。具体实现方法是先采集电机转速,然后根据设定的目标转速计算对应的占空比...
如何用 51单片机控制电机 和水泵?谢谢邀请,作为一名单片机开发工程师,和大家讲一讲电机控制的几个技术要点。电机是自动化等领域必须要用到的电子器件,而电机控制也就应用很广泛,专业技术要求...
怎么 控制 转差率调节 电机转速 -ZOL问答达到调节转速的目的。老式电风扇的(高、中、低三档)调速器就属于这种方式。——★2、可控硅调速方法:新型的电风扇控制器,利用双向可控硅来调节电压,以控制电...
利用 51单片机 实现直流调速系统的pi调节器?利用51单片机实现直流调速系统的PI调节器是一种控制算法,用于调节直流电机的转速。PI调节器是一种常用的控制器,它可以根据系统的误差和误差的变化率来调节输...
单片机 问题,怎么设置一个 控制 马达快慢的程序?不知道是什么马达,一般而言,马达的速度有控制马达的信号频率决定的,所以你改变控制信号的频率就可以了。不知道是什么马达,一般而言,马达的速度有控制马达的...
求指点 单片机控制 步进 电机 方法?步进电机的驱动电路是根据单片机产生的控制信号进行工作的,因此单片机通过步进电机驱动电路发送控制信号就能实现对步进电机的控制。驱动电路:可用达林顿驱动...
51单片机 中的直流 电机 的参数?直流电机是由电磁场和永磁体相互作用而产生的一种理想的转换装置,它是电力传动领域中重要的组成部分。在51单片机中,直流电机的参数通常包括:额定电压、额定电...
【摩天轮 旋转速度 怎么均匀的如果自己做一个简单的,就是旋转...[最佳回答]OK,我也想到你的第二点解决办法,就是加装类似自行车碟刹的装置,增加阻力,请问简单高效的办法,应该就此了吧,还有别的吗?OK,我也想到你的第二点解决...
关于 电机 功率和 转速 的确定。-盖德问答-化工人互助问答社区建议下载《基于单片机的电机转速及功率因数测量电路设计》或《电机控制&变频等设计参考》此类文章看看。《电子电路网》有下载,网址如下:http:///...
STC的 51单片机 ,AD转换速度是250KHz,即一秒是250000次,这个速率是指转换一个位,还是转换10个位?首先你要明白ADC的时钟概念:时钟频率为250KHz,意思是一秒钟转换250000次,而每次转换的数据是根据你ADC的精度来算的。比如你的ADC是8位的,就是每次转换8个...