OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9052|回复: 10

STM32用L298N驱动步进电机

[复制链接]

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
发表于 2016-4-15 15:33:10 | 显示全部楼层 |阅读模式
5金钱
用STM32 L298N驱动两相四线步进电机,8拍模式,电机噪音很大,怎么降低噪音啊

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2016-4-15 22:54:54 | 显示全部楼层
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3340
金钱
3340
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-16 01:34:26 | 显示全部楼层
如果速度要求不高, 按原子哥说的,用 PWM输出按正弦波方式细分一下,就行了, 保证工作又移稳定又安于, 最多到每分种300转的样子, 64到256细分都行, 其实超过 16细分后就效果改变就不是很明显了,  这种方法你可以做一个256的正弦波表, 用STM32的 定时器1输出控制, A相查表B相用A相的值移相的90度的方式, 但如果你要求高速,哪我也没招了, 高速要上去, 电机操声要小, 这个用简单的方法可能不能实现,特别是你用L298 我个人觉得基本没招,因为电流上不去.!!!!本人长期跟这个破步进电机生活在一起快10年了, 什么怪招都用过了, 网上说了一大堆90%是费话!!!!!!!!!!!!
回复

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
 楼主| 发表于 2016-4-16 12:42:10 | 显示全部楼层
likunxue 发表于 2016-4-16 01:34
如果速度要求不高, 按原子哥说的,用 PWM输出按正弦波方式细分一下,就行了, 保证工作又移稳定又安于, 最多到 ...

直接用定时器细分么?不用专门的细分驱动器?我现在是用单纯的IO口输出脉冲时序来控制步进电机,用PWM输出按正弦波方式怎么细分啊,求指教
回复

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
 楼主| 发表于 2016-4-16 12:42:40 | 显示全部楼层

具体要怎么细分呢?新手不是太懂
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3340
金钱
3340
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-16 13:13:47 | 显示全部楼层
本帖最后由 likunxue 于 2016-4-16 13:32 编辑
qjw123456 发表于 2016-4-16 12:42
直接用定时器细分么?不用专门的细分驱动器?我现在是用单纯的IO口输出脉冲时序来控制步进电机,用PWM输 ...

PWM的宽度就是导通时间, 宽度越大,导通时间就长, 平均电流就大, 用这个关系,计算好正弦波电流对应的脉宽就行了, 然后直接查表输出
慢慢来吧! 别急, 以下为正弦波输出部份代码, 你可参考一下




/********************************************************************************************
函数名:失量调制参数初始化函数
调  用: SVPWM_int(void)
参  数: 无   
********************************************************************************************/
void SVPWM_int(void)
     {
     const int M = 128;                //最大细分128细分      
     float K, fx = 0.00f;     
     int  i,n;  
     K = (float)20/255;                //线性系数      
     for(i = 0; i< M; i++)  
        {
        fx = (float)i/M;
        SVP.SIN   = 4096*(fx + K * sin(6.2831852 * fx));//A相电流表
        n = M -i;
        fx = (float)n/M;
        SVP.SIN[i+M] = 4096*(fx + K * sin(6.2831852 * fx));//B相电流表
                                
       // SVP.SIN     = sin((3.1415926/256)*i)*4096;   //计算正弦表 0   ~ 128 Q12格式
       // SVP.SIN[i+128] = cos((3.1415926/256)*i)*4096;   //计算正弦表 128 ~ 256         
        }   
     SVP.PWMPRD = PWMPTD -1;
     SVP.VDC = (296 *811)/10000;                //直流则母线电压 (采样值/0.000811)
     SVP.VDCinvT = SVP.PWMPRD/SVP.VDC;          //存放 PWMPRD/VDC的数据
        
     SVP.VDCmax  = (SVP.PWMPRD * 7071)/10000;   //合成失量的最大值

        
     SVP.K  = 0.02*4096;                        //制动转矩控制比;Q12
     SVP.Counter = 0;                           //SPWM计数器(微步计数器)
     SVP.sector = 0;                            //当前扇区号
     SVP.PMAI = SVP.PWMPRD*0.96;                //最大脉冲宽度 PWMPTD 96%
     SVP.PMXI = SVP.PWMPRD*0.04;                //最小窄脉宽度 PWMPTD 4%               
     SVP.Uret = 500;                            //外部电压设定值

     //电流环PI参数初始化
     SVP.SetPoint = 40;                         //目标值电流
     SVP.SumError = 0 ;                         //前一次的误差
     SVP.P = 204;                               //比例常数 0.2*1024
     SVP.I = 51;                               //积分常数 0.5*1024
     }


/********************************************************************************************
函 数 名: TIM1_IRQHandler:  定时器1中断函数
调    用: 无
参    数: 无
返 回 值: 无
********************************************************************************************/
void TIM1_UP_IRQHandler(void)  
     {           
     if(BIT_ADM(TIM1->SR,0)== 1)//溢出中断  
       {              
       int T1,T2,SA,SB;            
       u8 K = (u8)SVP.Counter;                //取微步计数器低8位的值   (加减这个值电机转动, )   
       BIT_ADM(TIM1->SR,0) = 0;               //清除定时器1中断标志位      
       if(SVP.Uret > SVP.VDCmax)SVP.Uret = SVP.VDCmax;    //最大失量电压限制      
       SVP.Uret = 500;
       //K = 224;
       if(SVP.Uret < 100) SVP.Uret = 100;     
       SVP.ua = ((s32)SVP.Uret *MY_COS[K])>>12;            //得到SVPWM输入的二相正弦电压
       SVP.ub = ((s32)SVP.Uret *MY_SIN[K])>>12;
       SVP.teta = K;
       SVP.sector = 0;
       if(SVP.ua > 0)SVP.sector = 1;
       if(SVP.ub > 0)SVP.sector += 2; //得到AB相换相数据(扇区号)
       switch(SVP.sector)         
             {
             case 3:{//第1扇区(+A,+B ->1 0 1 0)
                    T1 = SVP.ua;
                    T2 = SVP.ub;
                    SA = ((SVP.PWMPRD - T1)*SVP.K)>>12;    //计算A相转矩脉宽   
                    SB = ((SVP.PWMPRD - T2)*SVP.K)>>12;    //计算B相转矩脉宽
                    TIM1->CCR2 = SA;         //U4 +                     
                    TIM1->CCR1 = SA + T1;    //U5
                    TIM1->CCR3 = SB;         //U3 +
                    TIM1->CCR4 = SB + T2;    //U2  
                    }break;
             case 1:{//第4扇区(+A,-B ->1 0 0 1)
                    T1 = SVP.ua;
                    T2 = -SVP.ub;                     
                    SA = ((SVP.PWMPRD - T1)*SVP.K)>>12;    //计算A相转矩脉宽   
                    SB = ((SVP.PWMPRD - T2)*SVP.K)>>12;    //计算B相转矩脉宽
                    TIM1->CCR2 = SA;         //U4 +
                    TIM1->CCR1 = SA + T1;    //U5
                    TIM1->CCR3 = SB + T2;    //U3 -
                    TIM1->CCR4 = SB;         //U2
                    }break;
             case 0:{//第3扇区(-A,-B ->0 1 0 1)
                    T1 = -SVP.ua;
                    T2 = -SVP.ub;                     
                    SA = ((SVP.PWMPRD - T1)*SVP.K)>>12;    //计算A相转矩脉宽   
                    SB = ((SVP.PWMPRD - T2)*SVP.K)>>12;    //计算B相转矩脉宽
                    TIM1->CCR2 = SA + T1;   //U4 -
                    TIM1->CCR1 = SA;        //U5
                    TIM1->CCR3 = SB + T2;   //U3 -
                    TIM1->CCR4 = SB ;       //U2
                    }break;
             case 2:{//第2扇区(-A +B ->0 1 1 0)
                    T1 = -SVP.ua;
                    T2 = SVP.ub;                     
                    SA = ((SVP.PWMPRD - T1)*SVP.K)>>12;    //计算A相转矩脉宽   
                    SB = ((SVP.PWMPRD - T2)*SVP.K)>>12;    //计算B相转矩脉宽
                    TIM1->CCR2 = SA + T1;   //U4 -
                    TIM1->CCR1 = SA;        //U5
                    TIM1->CCR3 = SB;        //U3 +
                    TIM1->CCR4 = SB + T2;   //U2
                    }break;                             
             }     
       }               
     }



回复

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
 楼主| 发表于 2016-4-17 22:03:18 | 显示全部楼层
likunxue 发表于 2016-4-16 13:13
PWM的宽度就是导通时间, 宽度越大,导通时间就长, 平均电流就大, 用这个关系,计算好正弦波电流对应的 ...

感觉这个程序太难了对我这个新手来说,简直吃不燃啊
回复

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
 楼主| 发表于 2016-4-17 22:03:42 | 显示全部楼层
qjw123456 发表于 2016-4-17 22:03
感觉这个程序太难了对我这个新手来说,简直吃不燃啊

不过我会好好学习的
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2016-4-18
在线时间
2 小时
发表于 2016-4-18 11:55:00 | 显示全部楼层
减小扫描时间
回复

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2016-3-7
在线时间
16 小时
 楼主| 发表于 2016-4-18 15:16:07 | 显示全部楼层

我是直接用IO口操作的,没一拍是500us
回复

使用道具 举报

11

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2016-4-3
在线时间
17 小时
发表于 2016-6-17 16:46:08 | 显示全部楼层
兄弟加个QQ吧  我刚开始做这个 一加学习下  870497408 验证密码是 杨果
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 14:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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