步进电机驱动程序C语言
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了步进电机驱动程序C语言相关的知识,希望对你有一定的参考价值。
步进电机控制程序(c语言+51单片机)#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define ms *77
// f = 12 M
#define LEDLen 4
#define Dj_star() IE=0x81; pri_dj=0;
#define Dj_stop() IE=0x00; pri_dj=1; P1=0xff; shache="0"; delay(800ms); delay(800ms);delay(400ms); shache = 1;
#define Chilun_Num 8
/* 齿轮数 8 个*/
#define set_display_num() LEDBuf[0] = tmp / 1000; LEDBuf[1] = tmp / 100 % 10; \
LEDBuf[2] = tmp / 10 % 10; LEDBuf[3] = tmp % 10;
uchar LEDBuf[LEDLen] = 0,0,0,0;
void read_num (); /* 读播码盘 到 set_round_num * 8 */
void display ();
void delay(uint delay_time) uint i; for (i=0; i < delay_time ; i++) ;
void run ();
void fx_run();
uint round_num = 0; /* 记录已转的 齿轮数 , 中断1次 加 1*/
uint set_round_num = 0; /* 播码盘设置 圈数 */
uint set_pwm_width = 0; /* 播码盘设置 步进电机 正向速度 */
bit one_round_flg = 0;
sbit led_1000 = P0^7; //use for display
sbit led_100 = P0^6; //use for display
sbit led_10 = P0^5; //use for display
sbit led_1 = P0^4; //use for display
sbit key_start = P3^0;
sbit key_puse = P3^0;
sbit key_clear = P3^1;
/* P3^2 接齿轮传感器 中断 */
sbit bujin_zx_stop = P3^3; /* 接步进电机 ,正向到位传感器 ,为 0 停机 */
sbit bujin_fx_stop = P3^4; /* 接步进电机 ,反向到位传感器 ,为 0 停机 */
sbit shache = P3^5; /* 接刹车控制继电器 0 电位有效 */
sbit pri_dj = P3^6; /* 接主电机控制继电器 0 电位有效 */
void main()
TCON = 0x01;
display();
while(1)
IE="0x00";
round_num = 0;
display();
if ( bujin_fx_stop ) fx_run();
while ( key_start );
delay ( 8ms );
if(!key_start)
read_num();
//set_round_num = 8;
while ( !key_start );
run ();
fx_run();
void run ()
#define Delay_time 180
/* 转一圈 50 次循环,每循环 4 步 ,50 * 4 = 200 , 200 * 1。8 = 360 */
uchar i ;
P1 = 0xff;
set_pwm_width = 15 + set_pwm_width / 10;
while ( 1 )
while( !shache | !key_start );
Dj_star();
for ( i="0" ; bujin_zx_stop & !pri_dj;i++ )
P1 = 0xf9;
delay ( Delay_time ); // bujin_zx_stop = P3^3;
P1 = 0xfc; // bujin_fx_stop = P3^4;
delay ( Delay_time); // key_puse = P3^0;
P1 = 0xf6; // key_clear = P3^1;
delay ( Delay_time ); // shache = P3^5;
P1 = 0xf3; // pri_dj = P3^6;
delay ( Delay_time );
if( i == set_pwm_width ) P1 = 0xff; i = 0; one_round_flg = 0; while ( !one_round_flg & key_puse );
if(!key_puse) delay(4ms); if(!key_puse) break;
P1 = 0xff;
if ( pri_dj ) break;
if ( !key_puse )
delay ( 8ms );
if ( !key_puse )
Dj_stop();
while ( !key_puse );
// next pree key
while( !shache );
while(1)
while ( key_puse & key_clear );
delay ( 8ms );
if ( !key_clear ) round_num = 0; display();
if ( !key_puse ) break;
while( !key_puse );
delay(8ms);
while( !key_puse );
void ext_int0(void) interrupt 0 /* 主电机 齿轮 中断 */
uint tmp;
EA = 0;
if( !pri_dj )
round_num ++;
if (round_num % Chilun_Num == 0 )
one_round_flg = 1;
tmp = round_num / Chilun_Num ;
set_display_num();
P0 = 0xf0;
P0 = P0 | LEDBuf[0] ;
led_1000 = 0;
P0 |= 0xf0;
P0 = 0xf0;
P0 = P0 | LEDBuf[1] ;
led_100 = 0;
P0 |= 0xf0;
P0 = 0xf0;
P0 = P0 | LEDBuf[2] ;
led_10 = 0;
P0 |= 0xf0;
P0 = 0xf0;
P0 = P0 | LEDBuf[3] ;
led_1 = 0;
P0 |= 0xf0;
P0 = 0xf0;
if ( round_num >= set_round_num ) Dj_stop();
EA = 0x81;
void display()
uchar i;
uint tmp = 0;
tmp = round_num / Chilun_Num ;
set_display_num();
for(i = 0; i < LEDLen ; i ++)
P0 = 0xf0;
P0 = P0 | LEDBuf[i] ;
if(i==0) led_1000 = 0; //P0^4
if(i==1) led_100 = 0; //P0^5
if(i==2) led_10 = 0; //P0^6
if(i==3) led_1 = 0; //P0^7
P0 |= 0xf0;
P0 = 0xf0;
void read_num()
/* 读播码盘 到 set_round_num ,set_pwm_width */
uchar tmp;
P2 = 0xFF;
P2 = 0xEF; // 1110 1111
delay ( 1ms );
tmp = ~(P2 | 0xF0);
P2 = 0xDF; // 1101 1111
delay ( 1ms );
tmp = (~(P2 | 0xF0 )) * 10 + tmp;
set_round_num = tmp;
P2 = 0xBF; // 1011 1111
delay ( 1ms );
tmp = (~(P2 | 0xF0));
P2 = 0x7F; // 0111 1111
delay ( 1ms );
tmp = (~(P2 | 0xF0)) * 10 + tmp;
set_round_num = set_round_num + tmp * 100;
set_round_num = set_round_num * Chilun_Num;
P2 = 0xFF;
P1 = 0xbF; // 0111 1111
delay ( 1ms );
tmp = ~(P2 | 0xF0) ;
P1 = 0xFF;
P2 = 0xFF;
P1 &= 0x7F; // 1011 1111
delay ( 1ms );
tmp = (~(P2 | 0xF0)) * 10 + tmp ;
set_pwm_width = tmp ;
P1 = 0xFF;
P2 = 0xFF;
void fx_run()
#define f_Delay_time 180
while ( bujin_fx_stop ) /* 反向 回车 直到 传感器 动作*/
P1 = 0xf3; //0011
delay ( f_Delay_time );
P1 = 0xf6; //0110
delay ( f_Delay_time );
P1 = 0xfc; //1100
delay ( f_Delay_time );
P1 = 0xf9; //1001
delay ( f_Delay_time );
P1 = 0xff;
参考技术A 您好,这样的情况建议您下载最新版本的驱动精灵,或是直接在线升级一下驱动精灵。希望可以帮到您。
步进电机S曲线加减速控制生成器-VB6.0实现
程序功能:生成步进电机S曲线运动数组代码
程序语言:VB6.0
对应硬件线路连接见上章:
https://blog.csdn.net/LuDanTongXue/article/details/87869557
对应单片机程序见上章(PC端程序显示正常,手机端程序后半段显示不出来):
https://blog.csdn.net/LuDanTongXue/article/details/87869806
程序详细使用方法请见:
https://blog.csdn.net/LuDanTongXue/article/details/87886580
程序下载地址:
https://download.csdn.net/download/ludantongxue/11114203
程序界面如下:
S曲线算法参照该博文:
https://blog.csdn.net/pengzhihui2012/article/details/52228822
源码如下:
Option Explicit
Dim BuJuJiao As Double '步进电机步距角
Dim F0 As Double '硬件频率
Dim Nf As Double '定时器分频
Dim v0 As Double '加速段启动速度
Dim vt As Double '加速段最大速度
Dim JSBuShu As Long '加速步数
Dim JSJiaoDu As Double '加速段角度
Dim XiFen As Double '驱动器细分
Dim JSKuaiMan As Double '加速快慢,数值越大越慢
Dim JSshijian As Double '加速时间
Dim FenDuan As Double '将曲线分成梯形图
Dim MCCiShu As Long '每个速断段脉冲次数
Dim MCYuShu As Integer '分段不整除时最后的余数
Dim Fmin As Double 'V0对应的脉冲频率
Dim Fmax As Double 'Vt对应的脉冲频率
Dim Fcurrent As Double '实时频率
Dim DSChuZhi As Long '定时器1初值,采用溢出中断
Dim i As Integer '计数
Dim a0 As Long 'A0第一个脉冲的初值
Dim DingShiQiFenPing As Integer '定时器1预分频数
Dim ZhuanXiang As String '电机转动方向
Public Function Max(a As Double, b As Double) As Double '求最大值
If a < b Then
Max = b
ElseIf a >= b Then
Max = a
End If
End Function
Public Function ST(ax As Double, ay As Double, n As Double, m As Double) '图框初始化
'图框初始化
Dim Kuandanwei As Double
Picture1.ScaleMode = 6 '设置图片框单位
Kuandanwei = Picture1.Width / 400
Picture1.ScaleTop = -Picture1.Height / 2 '定义坐标原点x
Picture1.ScaleLeft = -Picture1.Width / 2 '-10 * Kuandanwei '定义坐标原点y
Picture1.Circle (0, 0), 1000
'X轴
Picture1.Line (-8 * Kuandanwei, 0)-(380 * Kuandanwei, 0)
Picture1.Line (380 * Kuandanwei, 0)-(370 * Kuandanwei, 10 * Kuandanwei)
Picture1.Line (380 * Kuandanwei, 0)-(370 * Kuandanwei, -10 * Kuandanwei)
Picture1.CurrentX = 380 * Kuandanwei
Picture1.CurrentY = 0
Picture1.Print "t"
'Y轴
Picture1.Line (0, 0.45 * Picture1.Height)-(0, -0.45 * Picture1.Height)
Picture1.Line (0, -0.45 * Picture1.Height)-(-10 * Kuandanwei, -0.45 * Picture1.Height + 10 * Kuandanwei)
Picture1.Line (0, -0.45 * Picture1.Height)-(10 * Kuandanwei, -0.45 * Picture1.Height + 10 * Kuandanwei)
Picture1.CurrentX = 0
Picture1.CurrentY = -0.5 * Picture1.Height
Picture1.Print "S"
'绘制坐标点
Picture1.PSet (n * Kuandanwei, -ax * m / 3), vbRed
Picture1.PSet (n * Kuandanwei, -ay * m / 3), vbBlue
n = n + 1
If n >= 360 Then
n = n - 360
Picture1.Cls
End If
End Function
Public Function QuXian() '曲线图框初始化,BS步进电机步数为x轴,vt为Y轴
'图框初始化
Picture1.Cls
Picture1.DrawWidth = 1
Dim Bili As Double '绘图比例
Bili = 0.7
Dim Kuandanwei As Double 'x方向图片放缩比例
Dim Gaodanwei As Double 'y方向图片放缩比例
Form1.ScaleMode = 6 '设置FORM框单位
Picture1.ScaleMode = 6 '设置图片框单位
Kuandanwei = Picture1.Width / (JSBuShu) '根据步进电机总时间计算图片放缩比例
Gaodanwei = Picture1.Height / Max(v0, vt)
Picture1.ScaleTop = -Picture1.Height + 5 * Kuandanwei '定义坐标原点y
Picture1.ScaleLeft = -5 * Kuandanwei '定义坐标原点x
Picture1.CurrentX = 0
Picture1.CurrentY = 0
Picture1.Print "0"
'X轴
Dim x1 As Double
Dim y1 As Double
Dim x2 As Double
Dim y2 As Double
Dim x3 As Double
Dim y3 As Double
x1 = Bili * (JSBuShu * Kuandanwei)
y1 = Bili * 0
x2 = Bili * (x1 - 3) ' 5 * Kuandanwei)
y2 = Bili * (y1 + 3) '5 * Kuandanwei)
x3 = x2
y3 = -y2
Picture1.Line (0, 0)-(x1, y1)
Picture1.Line (x1, y1)-(x2, y2)
Picture1.Line (x1, y1)-(x3, y3)
Picture1.CurrentX = x1
Picture1.CurrentY = y1
Picture1.Print Int(JSshijian * 1000) & "ms"
'Y轴
Dim x4 As Double
Dim y4 As Double
Dim x5 As Double
Dim y5 As Double
Dim x6 As Double
Dim y6 As Double
x4 = Bili * 0
y4 = Bili * (-Max(v0, vt) * Gaodanwei)
x5 = Bili * (x4 - 3) '-5* Kuandanwei)
y5 = Bili * (y4 - 3) '-5* Kuandanwei)
x6 = -x5
y6 = y5
Picture1.Line (0, 0)-(x4, y4)
Picture1.Line (x4, y4)-(x5, y5)
Picture1.Line (x4, y4)-(x6, y6)
Picture1.CurrentX = x4 + Kuandanwei
Picture1.CurrentY = y4
Picture1.Print Max(v0, vt) & "r/s"
'绘制坐标点
Picture1.DrawWidth = 5
Dim i As Integer
For i = 1 To JSBuShu
Picture1.PSet (Bili * i * Kuandanwei, Bili * -Gaodanwei * (v0 + (vt - v0) / (1 + Exp(-JSKuaiMan * (i - JSBuShu / 2) / (JSBuShu / 2))))), vbRed
Next
End Function
Private Sub Command1_Click()
BuJuJiao = Text2.Text
F0 = Text3.Text
Nf = Text4.Text
v0 = Text5.Text
vt = Text6.Text
JSJiaoDu = Text7.Text
XiFen = Text8.Text
JSKuaiMan = Text9.Text
If Text4.Text = 1 Then
DingShiQiFenPing = 1
ElseIf Text4.Text = 8 Then
DingShiQiFenPing = 2
ElseIf Text4.Text = 64 Then
DingShiQiFenPing = 3
ElseIf Text4.Text = 256 Then
DingShiQiFenPing = 4
ElseIf Text4.Text = 1024 Then
DingShiQiFenPing = 5
End If
JSBuShu = JSJiaoDu / (BuJuJiao / XiFen)
Fmin = v0 * 360 / (BuJuJiao / XiFen)
Fmax = vt * 360 / (BuJuJiao / XiFen)
Text1 = ""
JSshijian = 0
''''''''''''''''''''''''''''加速段A0数组生成'''''''''''
For i = 1 To JSBuShu
Fcurrent = Fmin + (Fmax - Fmin) / (1 + Exp(-JSKuaiMan * (i - JSBuShu / 2) / (JSBuShu / 2)))
DSChuZhi = 65535 - 1 / (Fcurrent * 2) * F0 / Nf '16位定时器
If i <> JSBuShu Then
Text1 = Text1 & "0X" & Hex(DSChuZhi) & ","
Else
Text1 = Text1 & "0X" & Hex(DSChuZhi)
End If
JSshijian = JSshijian + 1 / Fcurrent
Next
a0 = 65535 - 1 / ((Fmin + (Fmax - Fmin) / (1 + Exp(-JSKuaiMan * (1 - JSBuShu / 2) / (JSBuShu / 2)))) * 2) * F0 / Nf
Text10 = JSBuShu
Text12 = JSshijian * 1000
Text1 = "A[" & JSBuShu & "]=" & Text1 & ";" & vbCrLf & vbCrLf
''''''''''''''''''''''''''''
Text11.Text = (2 * F0 * BuJuJiao) / (65535 * Nf * 360 * XiFen) '计算最小启动速度
QuXian '绘制速度曲线
End Sub
微信/QQ:pph846375164
以上是关于步进电机驱动程序C语言的主要内容,如果未能解决你的问题,请参考以下文章
STM32F103+步进电机28BYJ-48+ULN2003 实现简单的正反转demo