找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2723|回复: 11
收起左侧

步进电机驱动器 单片机控制角度程序问题

  [复制链接]
回帖奖励 10 黑币 回复本帖可获得 10 黑币奖励! 每人限 1 次
ID:200362 发表于 2021-5-30 00:25 | 显示全部楼层 |阅读模式
本帖最后由 ereerr 于 2021-5-30 00:44 编辑

51单片机利用步进电机驱动器DM422控制一个两相四线步进电机(42CM08),共阳极接法,24V电源。要实现按一个按键,转动一个预设角度。程序中m=7,对应数组里200个脉冲,在不细分时是转360度,但是提出现偏差,请问是程序哪里出错了?该怎么改呢?
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uint num,turepluse,doubltruepl,m;  //num为进入中断次数,turepluse为脉冲数,m为数组标号
uint Angle[]={25,50,75,100,125,150,175,200}; //对应45,90,135,180,225,270,315,360度 不细分,步距角为1.8度
//电机控制引脚
sbit PUL  = P1^0;                                                //脉冲
sbit ENA  = P1^1;                                                 //使能
sbit DIR  = P1^2;                                                   //方向
//sbit Foreward  = P3^4;              //正转控制端
//sbit Backward  = P3^5;              //正转控制端
sbit OneAngle  = P3^6;              //固定角度控制
bit DJ_status=0;              //标志位
void Init_time();
void Key_scan();
void delay(uint z)
{
   uint x,y;
    for(x=z;x>0;x--)
          for(y=110;y>0;y--);
}
void OneStep(uint doubltruepl)  //固定角度转动
{
        turepluse=doubltruepl;
        ENA=1;                  //驱动器使能
        TR0=1;                   //打开定时器0
        DJ_status=1;          //进入一次固定角度转动,置1
        num=0;
      
}
void main()
{
        ENA=0;
        PUL=1;           
        DIR=0;                  
        Init_time();   //初始化定时器      
        m=7;           //转动360度


                while(1)
        {
               
                Key_scan();
        }      
}


void Init_time()                                 //初始化定时器
{
        TMOD |= 0x01;
        TH0=(65536-800)/256;                      //给time0装初值 800,这个800影响步进电机的转速,不知道影不影响脉冲数
        TL0=(65536-800)%256;
        EA=1;                                            //打开总中断
        TR0=1;                                          //打开定时器0
        ET0=1;


}
void Enter_Timer0() interrupt 1                                //进入定时器中断
{
        TH0=(65536-800)/256;
        TL0=(65536-800)%256;
        PUL=~PUL;                //取反,产生脉冲,2次中断产生一个完整脉冲
        num++;                      //中断个数 实际脉(truepluse)*2=num
// if(num==50) { num=0; ENA=0; TR0=0; }//50/2=25个脉冲 45度
        if(num==(2*turepluse)&&DJ_status)                                       //若m=0Angle[m])=25=turepluse=1/2num
        {
                num=0;
                TR0=0;
                ENA=0;
        }
}
void Key_scan()                                             
{
                if(OneAngle==0)      //固定角度键按下
        {
        delay(10);
                if(OneAngle==0)
                {
                        while(!OneAngle);               
                        OneStep(Angle[m]);
                }      
        }   

回复

使用道具 举报

ID:94031 发表于 2021-5-30 07:00 | 显示全部楼层
如果单靠步进电机步数控制,由于失步精度不会高,要想高加编码器,行程开关闭环。
回复

使用道具 举报

ID:200362 发表于 2021-5-30 10:02 | 显示全部楼层
xuyaqi 发表于 2021-5-30 07:00
如果单靠步进电机步数控制,由于失步精度不会高,要想高加编码器,行程开关闭环。

如果是因为失步,那我觉得这个由于失步偏差也大了,也试过细分3200脉冲一圈,误差也差不多。
还有就是我在定时器装初值那里设置的800,这个值可以改变步进电机转速,把它改大,电机转速慢了一些,这时候就偏差较小。我觉得是不是可能程序有问题,请问在哪改一下呢?
如果用闭环控制,在普通开环控制上具体要加什么?谢谢
回复

使用道具 举报

ID:920848 发表于 2021-6-2 01:04 | 显示全部楼层
用编码器
回复

使用道具 举报

ID:920827 发表于 2021-6-2 23:51 | 显示全部楼层
步进电机的脉冲有最小时间限制,脉冲发的过快,电机响应不过来就会出问题,
还有电流给的够不够,即使是空载,电流过小一样会丢步,
定时器优先级看一下,可能是抢断了的影响
回复

使用道具 举报

ID:818024 发表于 2021-6-3 11:52 | 显示全部楼层
步进电机带负载时一开始会有偏差,脉冲过快也会有偏差
回复

使用道具 举报

ID:200362 发表于 2021-6-3 16:46 | 显示全部楼层
我欠你钱么 发表于 2021-6-2 23:51
步进电机的脉冲有最小时间限制,脉冲发的过快,电机响应不过来就会出问题,
还有电流给的够不够,即使是空 ...

脉冲最小时间限制就相当于它的频率吧,高低频率我都试了一下,除了转速快慢不同,还有就是高频率的误差比较大(设置转到固定角度)。
电机电流,在空载时我给的都是接近它的额定电流,这个应该不是原因
我程序用了定时器0,这种情况要考虑优先级吗?谢谢
回复

使用道具 举报

ID:200362 发表于 2021-6-15 19:43 | 显示全部楼层
谁知道怎么解决呢?
回复

使用道具 举报

ID:399179 发表于 2022-4-9 21:09 来自手机 | 显示全部楼层
ereerr 发表于 2021-6-15 19:43
谁知道怎么解决呢?

楼主解决了吗?我也在研究这个
回复

使用道具 举报

ID:161164 发表于 2022-4-9 23:36 | 显示全部楼层
快乐眼泪 发表于 2022-4-9 21:09
楼主解决了吗?我也在研究这个

就算电机没有启动
num也在不停的自加

应改为
  1. void Enter_Timer0() interrupt 1                                //进入定时器中断
  2. {
  3.         TH0=(65536-800)/256;
  4.         TL0=(65536-800)%256;
  5.         PUL=~PUL;                //取反,产生脉冲,2次中断产生一个完整脉冲
  6.         if(DJ_status)num++;//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<                      //中断个数 实际脉(truepluse)*2=num
  7. // if(num==50) { num=0; ENA=0; TR0=0; }//50/2=25个脉冲 45度
  8.         if(num==(2*turepluse))//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<                                       //若m=0Angle[m])=25=turepluse=1/2num
  9.         {
  10.                 num=0;
  11.                 TR0=0;
  12.                 ENA=0;
  13.                                 DJ_status=0;//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  14.         }
  15. }
复制代码


回复

使用道具 举报

ID:399179 发表于 2022-4-11 20:10 来自手机 | 显示全部楼层
lkc8210 发表于 2022-4-9 23:36
就算电机没有启动
num也在不停的自加


感谢指导!有时间试试!
回复

使用道具 举报

ID:982617 发表于 2022-4-13 17:37 | 显示全部楼层
编码器加进来试试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表