STM32用L298N驱动步进电机

2019-07-20 21:41发布

用STM32 L298N驱动两相四线步进电机,8拍模式,电机噪音很大,怎么降低噪音啊
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
正点原子
1楼-- · 2019-07-21 03:32
细分!!
likunxue
2楼-- · 2019-07-21 08:26
 精彩回答 2  元偷偷看……
qjw123456
3楼-- · 2019-07-21 10:51
likunxue 发表于 2016-4-16 01:34
如果速度要求不高, 按原子哥说的,用 PWM输出按正弦波方式细分一下,就行了, 保证工作又移稳定又安于, 最多到 ...

直接用定时器细分么?不用专门的细分驱动器?我现在是用单纯的IO口输出脉冲时序来控制步进电机,用PWM输出按正弦波方式怎么细分啊,求指教
qjw123456
4楼-- · 2019-07-21 16:26
正点原子 发表于 2016-4-15 22:54
细分!!

具体要怎么细分呢?新手不是太懂
likunxue
5楼-- · 2019-07-21 17:54
本帖最后由 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;                             
             }     
       }               
     }



qjw123456
6楼-- · 2019-07-21 19:27
likunxue 发表于 2016-4-16 13:13
PWM的宽度就是导通时间, 宽度越大,导通时间就长, 平均电流就大, 用这个关系,计算好正弦波电流对应的 ...

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

一周热门 更多>