专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
小型5线4相步进电机24BYJ48A用ULN2803如何进行4细分?
2020-01-20 19:01
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
5029
16
16
这个电机是每转一步是5.625度,正常应该是转子转64步后,转动一周。即64X5.625=360度。
我现在采用的是半步,即四相八拍工作方式。A_AB_B_BC_C_CD_D_D,转子转64步后,转动半周即180度。
我现在需要做到转子转动128步,才转动半周即180度。我想这应该是要用PWM进行4细分才行?
请问,用单片机驱动ULN2803如何进行4细分?
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
16条回答
wenking99
2020-01-21 08:04
2路PWM 驱动单极性步进电机 演示程序 82G516专用,其它的请自消化!
目的让大家了解细分后步进电机运行的效果(特别是低速时)
用两路PWM接ULN2803来驱动单极性6线/5线的步进电机,另两路通过一反相连接
如要求不太高的,一般可以满足,只是在PWM的每个像限的初始时,
会一快一慢(极底速时才能发觉),这是电流不均匀所产生的 .
这只是一个简单的示例,让大家了解PWM的巧妙用法,实际工程中是要加入一些相关的算法的,如加、减速;调速、定位、扭矩等等。
请自行消化!此方面不提供技术支持的。
用的是带硬8位PWM的MCU(可以是MPC82G516、MPC82E54、STC12C5410等)
用前先初始化,PWM频率为46.71KHz左右,24M晶体)
此演示程序硬件配置:M-508U开发板的J1需外接入9V 电源,单片用MPC82G516, 晶振12M(24M也可以,速度不同)
运行现像: J35接的 X电机转到90度后再反转
J34接的 Y电机一直转
J33接的 X电机转一周后,再反转
此处用细分驱动步进电机,51200个脉冲为一周
*/
#include <MPC82G516.h> //头文件
#define uchar unsigned char //宏定议,方便书写
#define uint unsigned int //宏定议,方便书写
//[82G516 MCU]
#define pwm6 CCAP0H //82G516内部PWM 寄存器
#define pwm5 CCAP1H
#define pwm4 CCAP2H
#define pwm3 CCAP3H
#define pwm2 CCAP4H
#define pwm1 CCAP5H
uchar MAXSP,cnt;
uchar x_task, y_task, z_task; //电机工作装态
uint x_step, y_step, z_step; //步数
bit x_dir, y_dir, z_dir, s; //方向标记
//MPC82G516 内部硬PWM初始化,使之有效!
//---------------------------------------------
void Init_pwm(void)
{
CMOD = 0x02; //
CCAPM0 = 0x42; //Configure PCA Module0 to PWM
CCAPM1 = 0x42; //Configure PCA Module1 to PWM
CCAPM2 = 0x42; //Configure PCA Module2 to PWM
CCAPM3 = 0x42; //Configure PCA Module3 to PWM
CCAPM4 = 0x42; //Configure PCA Module4 to PWM(Only for MPC82G516)
CCAPM5 = 0x42; //Configure PCA Module5 to PWM(Only for MPC82G516)
CR = 1; //start PCA Timer
}
//----------------------------------------------
void Init_time(void)
{
TMOD = 0x11; // 11 T1 & T0 16位定时
TR0=1;
ET0=1; //T0中断开
// TR1=1;
// ET1=1;
EA=1; //开总中断
}
//-----------------------------------------------
void main(void)
{
x_step=0;
Init_pwm(); //硬PWM初始化
Init_time(); //定时器初始化
s=1;
while(1)
{
MAXSP=10; //最大速度[可改为可调, 此处为3个电机同时调速,也可改为单独调速; 但时此种控多用改变细分来进行调速!]
}
}
//-------------定时0--------------------
void Time0_isr (void) interrupt 1
{
TH0 = 0xff; //
TL0 = 0xe0;
if(s)
{
if(++cnt>=MAXSP)
{
cnt=0;
//如要改变方向,x_task++改为x_task--即可;此改为:if(x_task==0xff)x_task=3; //注:此程序本人用来测试电机用的,力度也很大,一般场合也够用!
if(x_dir)
{
if(x_task>3) x_task=0;
switch(x_task)
{
case 0: if(++pwm1==255){x_task++;} pwm2=0; break; //像限1区
case 1: if(++pwm2==255){x_task++;} pwm1=255; break; //....2
case 2: if(--pwm1==0) {x_task++;} pwm2=255; break; //....3
case 3: if(--pwm2==0) {x_task++;} pwm1=0; break; //....4
default: x_task=0; break;
}
}
else
{
if(x_task==0xff)x_task=3;
switch(x_task)
{
case 0: if(++pwm2==255){x_task++;} pwm1=0; break; //像限1区
case 1: if(++pwm1==255){x_task++;} pwm2=255; break; //....2
case 2: if(--pwm2==0) {x_task++;} pwm1=255; break; //....3
case 3: if(--pwm1==0) {x_task++;} pwm2=0; break; //....4
default: x_task=0; break;
}
}
if(++x_step==51200) {x_dir=!x_dir; x_step=0;} //X电机转到一周后,再反转 (51200个脉冲为一周, 1.8度的39BYG系步进电机)
// -------------------------------------------------------------------Y 步进电机一直转
if(y_task>3) y_task=0;
switch(y_task)
{
case 0: if(++pwm3==255){y_task++;} pwm4=0; break; //像限1区
case 1: if(++pwm4==255){y_task++;} pwm3=255; break; //....2
case 2: if(--pwm3==0) {y_task++;} pwm4=255; break; //....3
case 3: if(--pwm4==0) {y_task++;} pwm3=0; break; //....4
default: y_task=0; break;
}
// ------------------------------------------------------------------- Z 步进电机 转90度再反转回去
if(z_dir)
{
if(z_task>3) z_task=0;
switch(z_task)
{
case 0: if(++pwm5==255){z_task++;} pwm6=0; break; //像限1区
case 1: if(++pwm6==255){z_task++;} pwm5=255; break; //....2
case 2: if(--pwm5==0) {z_task++;} pwm6=255; break; //....3
case 3: if(--pwm6==0) {z_task++;} pwm5=0; break; //....4
default: z_task=0; break;
}
}
else
{
if(z_task==0xff) z_task=3;
switch(z_task)
{
case 0: if(++pwm6==255){z_task++;} pwm5=0; break; //像限1区
case 1: if(++pwm5==255){z_task++;} pwm6=255; break; //....2
case 2: if(--pwm6==0) {z_task++;} pwm5=255; break; //....3
case 3: if(--pwm5==0) {z_task++;} pwm6=0; break; //....4
default: z_task=0; break;
}
}
if(++z_step==12800) {z_dir=!z_dir; z_step=0;}
}
}
}
看到这个是两相电机的细分,不知道4相电机4细分怎么弄?
加载中...
查看其它16个回答
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
目的让大家了解细分后步进电机运行的效果(特别是低速时)
用两路PWM接ULN2803来驱动单极性6线/5线的步进电机,另两路通过一反相连接
如要求不太高的,一般可以满足,只是在PWM的每个像限的初始时,
会一快一慢(极底速时才能发觉),这是电流不均匀所产生的 .
这只是一个简单的示例,让大家了解PWM的巧妙用法,实际工程中是要加入一些相关的算法的,如加、减速;调速、定位、扭矩等等。
请自行消化!此方面不提供技术支持的。
用的是带硬8位PWM的MCU(可以是MPC82G516、MPC82E54、STC12C5410等)
用前先初始化,PWM频率为46.71KHz左右,24M晶体)
此演示程序硬件配置:M-508U开发板的J1需外接入9V 电源,单片用MPC82G516, 晶振12M(24M也可以,速度不同)
运行现像: J35接的 X电机转到90度后再反转
J34接的 Y电机一直转
J33接的 X电机转一周后,再反转
此处用细分驱动步进电机,51200个脉冲为一周
*/
#include <MPC82G516.h> //头文件
#define uchar unsigned char //宏定议,方便书写
#define uint unsigned int //宏定议,方便书写
//[82G516 MCU]
#define pwm6 CCAP0H //82G516内部PWM 寄存器
#define pwm5 CCAP1H
#define pwm4 CCAP2H
#define pwm3 CCAP3H
#define pwm2 CCAP4H
#define pwm1 CCAP5H
uchar MAXSP,cnt;
uchar x_task, y_task, z_task; //电机工作装态
uint x_step, y_step, z_step; //步数
bit x_dir, y_dir, z_dir, s; //方向标记
//MPC82G516 内部硬PWM初始化,使之有效!
//---------------------------------------------
void Init_pwm(void)
{
CMOD = 0x02; //
CCAPM0 = 0x42; //Configure PCA Module0 to PWM
CCAPM1 = 0x42; //Configure PCA Module1 to PWM
CCAPM2 = 0x42; //Configure PCA Module2 to PWM
CCAPM3 = 0x42; //Configure PCA Module3 to PWM
CCAPM4 = 0x42; //Configure PCA Module4 to PWM(Only for MPC82G516)
CCAPM5 = 0x42; //Configure PCA Module5 to PWM(Only for MPC82G516)
CR = 1; //start PCA Timer
}
//----------------------------------------------
void Init_time(void)
{
TMOD = 0x11; // 11 T1 & T0 16位定时
TR0=1;
ET0=1; //T0中断开
// TR1=1;
// ET1=1;
EA=1; //开总中断
}
//-----------------------------------------------
void main(void)
{
x_step=0;
Init_pwm(); //硬PWM初始化
Init_time(); //定时器初始化
s=1;
while(1)
{
MAXSP=10; //最大速度[可改为可调, 此处为3个电机同时调速,也可改为单独调速; 但时此种控多用改变细分来进行调速!]
}
}
//-------------定时0--------------------
void Time0_isr (void) interrupt 1
{
TH0 = 0xff; //
TL0 = 0xe0;
if(s)
{
if(++cnt>=MAXSP)
{
cnt=0;
//如要改变方向,x_task++改为x_task--即可;此改为:if(x_task==0xff)x_task=3; //注:此程序本人用来测试电机用的,力度也很大,一般场合也够用!
if(x_dir)
{
if(x_task>3) x_task=0;
switch(x_task)
{
case 0: if(++pwm1==255){x_task++;} pwm2=0; break; //像限1区
case 1: if(++pwm2==255){x_task++;} pwm1=255; break; //....2
case 2: if(--pwm1==0) {x_task++;} pwm2=255; break; //....3
case 3: if(--pwm2==0) {x_task++;} pwm1=0; break; //....4
default: x_task=0; break;
}
}
else
{
if(x_task==0xff)x_task=3;
switch(x_task)
{
case 0: if(++pwm2==255){x_task++;} pwm1=0; break; //像限1区
case 1: if(++pwm1==255){x_task++;} pwm2=255; break; //....2
case 2: if(--pwm2==0) {x_task++;} pwm1=255; break; //....3
case 3: if(--pwm1==0) {x_task++;} pwm2=0; break; //....4
default: x_task=0; break;
}
}
if(++x_step==51200) {x_dir=!x_dir; x_step=0;} //X电机转到一周后,再反转 (51200个脉冲为一周, 1.8度的39BYG系步进电机)
// -------------------------------------------------------------------Y 步进电机一直转
if(y_task>3) y_task=0;
switch(y_task)
{
case 0: if(++pwm3==255){y_task++;} pwm4=0; break; //像限1区
case 1: if(++pwm4==255){y_task++;} pwm3=255; break; //....2
case 2: if(--pwm3==0) {y_task++;} pwm4=255; break; //....3
case 3: if(--pwm4==0) {y_task++;} pwm3=0; break; //....4
default: y_task=0; break;
}
// ------------------------------------------------------------------- Z 步进电机 转90度再反转回去
if(z_dir)
{
if(z_task>3) z_task=0;
switch(z_task)
{
case 0: if(++pwm5==255){z_task++;} pwm6=0; break; //像限1区
case 1: if(++pwm6==255){z_task++;} pwm5=255; break; //....2
case 2: if(--pwm5==0) {z_task++;} pwm6=255; break; //....3
case 3: if(--pwm6==0) {z_task++;} pwm5=0; break; //....4
default: z_task=0; break;
}
}
else
{
if(z_task==0xff) z_task=3;
switch(z_task)
{
case 0: if(++pwm6==255){z_task++;} pwm5=0; break; //像限1区
case 1: if(++pwm5==255){z_task++;} pwm6=255; break; //....2
case 2: if(--pwm6==0) {z_task++;} pwm5=255; break; //....3
case 3: if(--pwm5==0) {z_task++;} pwm6=0; break; //....4
default: z_task=0; break;
}
}
if(++z_step==12800) {z_dir=!z_dir; z_step=0;}
}
}
}
看到这个是两相电机的细分,不知道4相电机4细分怎么弄?
一周热门 更多>