搜索
bottom↓
回复: 10

用STM32F407的PWM控制DRV8825驱动步进电机加减速和匀速运行

[复制链接]

出0入0汤圆

发表于 2016-11-16 13:29:17 | 显示全部楼层 |阅读模式
我之前驱动电机用的TRINAMIC的芯片,控制步进电机加减速、匀速运行非常简单。这次打算用DRV8825来驱动,采用42步进电机(二相四线)。
控制信号如下:
STM32F407->DRV8825
PA0           ->        DIR:控制步进电机运行方向
PA3           ->        STP:一个上升沿脉冲使电机运行一步(或一个微步)
PA4           ->        SLP:低功耗模式
PF11          ->        EN:使能信号
DRV8825可以设置最高32细分,可以设置电流最大2.5A
如果速度不快不考虑加减速,直接控制PWM(TIM2_Ch4:PA3)产生恒定的脉冲,就可以让电机匀速运行了,速度和脉冲频率同步。但是如果需要电机高速运行,可能会在启动或停止时造成失步或者过冲。
作为初学者我在网上搜索了一下没有找到PWM控制DRV8825加减速的例子,不过有一些可供参考的文档,例如AVR446 :线性速度控制步进电机-研究笔记。还有:基于STM32的4轴步进电机加减速控制全套工程源码http://www.amobbs.com/thread-5529816-1-1.html
我采用2细分,转一圈需要400个脉冲(32细分,转一圈6400个脉冲)

代码如下:(未考虑限位和紧急状态变化情况)
//main.c

#include "sys.h"
#include "delay.h"
#include "DRV8825.h"


#define KEY0  PBin(7)

extern speedRampData srd;

/*------------------MAIN 开始------------------*/
int main(void)
{
        u32 i;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
       
        delay_init(168);  //初始化延时函数
        TIM3_Int_Init(100-1,840-1);       


        DRV8825_Init();
        SLP=0;
        EN=1;
        DIR=1;
        STP=0;
        delay_ms(2);
        SLP=1;
        delay_ms(2);
        EN=0;
        delay_ms(10);
        SLP=0;
        srd.run_state=RUN;
        srd.dir=0;
       
        while(1)
        {
                if(KEY0==0)
                {
                        delay_ms(50); //延时50ms,消抖
                        if(KEY0==0) //再判断是否按下
                        {
                                while(KEY0==0);//松手检测
                                //AxisMove(SPR*1/8, 200000, 200000, 8000);//6400*10实现往复振动功能
                                for(i=0;i<200;i++)
                                {//快速
                                        AxisMove(SPR*1/16, 500000, 500000, 8000);//6400*10
                                        delay_ms(20);
                                        AxisMove(-SPR*1/16, 500000, 500000, 8000);//6400*10
                                        delay_ms(20);
                                }
                               
                        }

                }
        }
}
/*------------------MAIN 结束------------------*/

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-11-16 13:54:49 | 显示全部楼层
用延时这样不太好把

出0入4汤圆

发表于 2016-11-16 13:59:42 来自手机 | 显示全部楼层
赞一个,不错

出0入0汤圆

 楼主| 发表于 2016-11-16 14:01:56 | 显示全部楼层
霸气侧漏 发表于 2016-11-16 13:54
用延时这样不太好把

也可以判断MotionStatus标志,我偷懒了

出0入0汤圆

发表于 2016-11-16 17:59:07 来自手机 | 显示全部楼层
呵呵!路过帮顶

出0入0汤圆

发表于 2016-11-17 01:29:32 | 显示全部楼层
这大牛拉玩具车呀,太浪费了。咋的也得加个流水灯嘛

出0入0汤圆

发表于 2017-7-27 09:51:06 | 显示全部楼层
请问有没有电路原理图啊 楼主

出0入0汤圆

发表于 2017-11-14 00:49:38 | 显示全部楼层
楼主,,8825工作时的电流多大??

我试了下,,1A时,发热很厉害。。求推荐大电流,带微步的芯片。

出0入0汤圆

发表于 2017-11-27 22:25:05 | 显示全部楼层
litop 发表于 2017-11-14 00:49
楼主,,8825工作时的电流多大??

我试了下,,1A时,发热很厉害。。求推荐大电流,带微步的芯片。 ...


  TB67S109AFNAG  ,导热窗在芯片顶部, 大贴片封装,36脚。 参数与8825差不多

发热厉害只能是加散热片,特别是要考虑夏天的情况

出0入0汤圆

 楼主| 发表于 2017-12-22 09:55:36 | 显示全部楼层
本帖最后由 am3359 于 2017-12-22 10:00 编辑

用VB写了个测试程序



Sub Calculator()

    Dim accel_count, step_delay, min_delay, decel_val, decel_start As Long    '-2,147,483,648 ~ 2,147,483,647
    Dim A_T_x100, T1_FREQ_148, A_SQ, A_x20000 As Long             '-2,147,483,648 ~ 2,147,483,647
    Dim ALPHA As Double                                           '-1.67E+308 ~ 1.67E+308
    Dim run_state As Integer                                      'STOP:0ACCEL:1DECEL:2RUN:3   '-32768 ~ 32767
   
    Dim step&, accel&, decel&, speed&, max_s_lim&, accel_lim&
    Dim step_count&, rest&, sum&, new_step_delay&, last_accel_delay&

   
    ALPHA = Val(Worksheets("stepmoto1").Cells(11, 3).Value)
    A_T_x100 = ALPHA * Val(Worksheets("stepmoto1").Cells(7, 3).Value) * 100
    T1_FREQ_148 = Val(Worksheets("stepmoto1").Cells(7, 3).Value) * 0.676 / 100
    A_SQ = ALPHA * 2 * 100000 * 100000
    A_x20000 = ALPHA * 20000
   
    step = Val(Worksheets("stepmoto1").Cells(20, 3).Value)
    accel = Val(Worksheets("stepmoto1").Cells(21, 3).Value) * 100
    decel = Val(Worksheets("stepmoto1").Cells(22, 3).Value) * 100
    speed = Val(Worksheets("stepmoto1").Cells(23, 3).Value) * 100
   
    If Val(Worksheets("stepmoto1").Cells(20, 3).Value) = 1 Then
        ' 如果只移动一步,直接减速
        accel_count = -1
        ' 进入减速状态 DECEL=2
        run_state = 2
        ' 走一步时c0设置为2000
        step_delay = 2000
    Else
        ' 最小计数值 min_delay是最大速度时对应的c值,最大速度时c最小,c0~cn都不能小于min_delay
        ' 1MHz信号计数至少循环20次产生一次PWM信号,TIM2->ARR=20
        ' 要保证计数值c=ALPHA*T1_FREQ*100/speed>=20,最大速度speed<=157_079/细分数
        min_delay = Int(A_T_x100 / speed) 'c = (alpha / tt)/ w

        ' c0=(((T1_FREQ*0.676)) * sqrt((ALPHA*2*100) / accel))>=20,计算出整步时accel<=7_178_156_159.2,2细分时accel<=3_589_078_079.6
        step_delay = Int((T1_FREQ_148 * Int(Sqr(A_SQ / accel))) / 100) 'c0 = 1/tt * sqrt(2*alpha/accel)
        
        ' max_s_lim使用accel加速到speed需要发送的步数
        ' 由于accel和speed都放大了100倍计算结果需要除100  max_s_lim = speed*speed/(2*alpha*accel*100)
        max_s_lim = Int(speed * speed / ((A_x20000 * accel) / 100)) '//speed*speed/(2*alpha*accel)

        ' 至少要走一步
        If max_s_lim = 0 Then
            max_s_lim = 1
        End If

        ' 计算多少步开始减速n1=accel_lim
        ' 推导过程n1*accel = n2*decel -> n1*accel = (n1+n2-n1)*decel -> n1 = (n1+n2)*decel/(accel+decel)=step*decel/(accel+decel)
        accel_lim = Int((step * decel) / (accel + decel)) 'n1=step*decel/(accel+decel)
        ' 减速过程至少有一步
        If accel_lim = 0 Then
            accel_lim = 1
        End If

        ' 计算减速需要走的步数,取负值
        If accel_lim <= max_s_lim Then '速度曲线为三角形
            decel_val = accel_lim - step 'step=n1+n2 -> -n2=n1-step
        Else '速度曲线为梯形
            decel_val = Int(-max_s_lim * accel / decel) 'max_s_lim*accel=decel_val*decel
        End If
        ' 减速停止前至少走一步
        If decel_val = 0 Then
            decel_val = -1
        End If

        ' 计算减速前走多少步
        decel_start = step + decel_val

        ' 如果设置的最大速度很低可以不加速
        If step_delay <= min_delay Then
            step_delay = min_delay
            run_state = 3
        Else
            run_state = 1
        End If

        ' 复位计数器
        accel_count = 0
    End If
   
    rest = 0
    sum = 0
    For step_count = 1 To step
        Select Case run_state

        Case 0 'STOP
            'step_count = 0
            rest = 0
            sum = 0
            Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
            Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "S"
        Case 1 'ACCEL '一般运动先进这里
            sum = sum + step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
            Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "A"
            Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
            'step_count++
            accel_count = accel_count + 1
            new_step_delay = step_delay - (((2 * step_delay) + rest) \ (4 * accel_count + 1)) '计算当前的c
            rest = ((2 * step_delay) + rest) Mod (4 * accel_count + 1) '取整后的余数保留,在下次计算中加进去,减少误差
            If step_count >= decel_start Then
            '计数到减速开始位置
                accel_count = decel_val
                run_state = 2
            ElseIf new_step_delay <= min_delay Then
            '若 c<=min_delay 则 c=min_delay 匀速
                'printf("B\t%d\t%d",new_step_delay,min_delay)
                last_accel_delay = new_step_delay '保存最后一个加速值,此处保存的值可能超过设定的最高速度??
                new_step_delay = min_delay
                rest = 0
                run_state = 3
            End If
        Case 3 'RUN '初始速度就是最高速度直接进这里
            sum = sum + step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
            Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "R"
            Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
            'step_count++
            new_step_delay = min_delay
            If step_count >= decel_start Then
                accel_count = decel_val
                ' Start decelration with same delay as accel ended with.
                new_step_delay = last_accel_delay
                run_state = 2
            End If
        Case 2 'DECEL '走1步进这里
            sum = sum + step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
            Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "D"
            Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
            Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
            'step_count++
            accel_count = accel_count + 1
            new_step_delay = step_delay - (((2 * step_delay) + rest) \ (4 * accel_count + 1)) '计算当前的c
            rest = ((2 * step_delay) + rest) Mod (4 * accel_count + 1) '取整后的余数保留,在下次计算中加进去,减少误差
            If accel_count >= 0 Then
                run_state = 0
            End If
        End Select
        step_delay = new_step_delay
        DoEvents
    Next step_count
End Sub

出0入0汤圆

 楼主| 发表于 2017-12-22 09:58:26 | 显示全部楼层
本帖最后由 am3359 于 2017-12-22 10:09 编辑

excel表如图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 04:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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