stm32控制多个步进电机出现的问题

2019-07-21 08:37发布

我需要控制多个电机,我用原子的源码控制一个电机,电机转的很正常,我控制第二个的时候,用了定时器3 ,把之前定时器8相关的源码移了一个文件,改了相关参数,结果第二个电机无论怎么挑脉冲和频率,电机转的都很慢,我考虑到可能是时钟线的问题,就用了个定时器1,结果好不容易有改完了,电机速度确实和用定时器一样了,只是电机一直抖动,我用给的相对定位函数,把频率调到30000了,发现和1000是没有区别的,都在抖动!!!!!!!,怎么用板子控制多个步进电机呀。我的代码哪里需要改呀,而且很令我不解的是,我把串口的函数一旦注释掉,电机就转不了了,串口1 有用吗??为啥有影响呢,
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
SunnyOpen
1楼-- · 2019-07-21 12:28
程序里  driver3 是模仿着 源码写的,用的是定时器1  电机总是抖动,定时器3  的代码我也写过,就是速度非常的慢
#include "driver2.h"
#include "delay.h"
#include "usart.h"
************************************************************
//DT??è??ú:2016/05/12
//////////////////////////////////////////////////////////////////////////////////
/********** ?y?ˉ?÷ ???ú?¨ò? **************
//DRIVER_DIR  PA6
//DRIVER_OE   PA5
//STEP_PULSE   PA7   TIM3_CH2,LCD_RW)
******************************************/

u8 rcr_remainder2;   //???′??êyóàêy2?·?
u8 is_rcr_finish2=1; //???′??êy?÷ê?·?éè??íê3é
long rcr_integer2;        //???′??êy??êy2?·?
long target_pos2=0;  //óD·?o?·??ò
long current_pos2=0; //óD·?o?·??ò
DIR_Type motor_dir2=CW;//?3ê±??

/************** ?y?ˉ?÷????D?o???3?ê??ˉ ****************/
void Driver_Init2(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        //ê1?üPC???úê±?ó

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;        //PC0.2 ???ú????
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 //í?íìê?3?
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                //IO?ú?ù?è?a50MHz
        GPIO_Init(GPIOA, &GPIO_InitStructure);                                        //?ù?Yéè?¨2?êy3?ê??ˉGPIOC
        GPIO_SetBits(GPIOA,GPIO_Pin_5);                                                         //PC0ê?3??? ?3ê±??·??ò  DRIVER_DIR
        GPIO_ResetBits(GPIOA,GPIO_Pin_6);                                                //PC2ê?3?μí ê1?üê?3?  DRIVER_OE
}

/***********************************************
//TIM3_CH2(PC7) μ¥??3?ê?3?+???′??êy1|?ü3?ê??ˉ
//TIM3 ê±?ó?μ?ê 72MHz
//arr£o×??ˉ??×°?μ
//psc£oê±?ó?¤·??μêy
************************************************/
void TIM3_OPM_RCR_Init(u16 arr,u16 psc)
{                                                          
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //TIM3ê±?óê1?ü
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //ê1?üGPIOCíaéèê±?óê1?ü                                                                                    

        //éè????òy???a?′ó?ê?3?1|?ü,ê?3?TIM3 CH2μ?PWM??3?2¨D?
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM3_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //?′ó?í?íìê?3?
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
       
        TIM_TimeBaseStructure.TIM_Period = arr; //éè???ú??ò????üD?ê??t×°è????ˉμ?×??ˉ??×°????′??÷?ü?úμ??μ         
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //éè??ó?à′×÷?aTIMxê±?ó?μ?ê3yêyμ??¤·??μ?μ
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //éè??ê±?ó·???:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM?òé???êy?£ê?
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //?ù?YTIM_TimeBaseInitStruct?D???¨μ?2?êy3?ê??ˉTIMxμ?ê±???ùêyμ¥??
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

        TIM_UpdateRequestConfig(TIM3,TIM_UpdateSource_Regular); /********* éè????óD??êyò?3?×÷?a?üD??D?? ********/
        TIM_SelectOnePulseMode(TIM3,TIM_OPMode_Single);/******* μ¥??3??£ê? **********/

        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //?????¨ê±?÷?£ê?:TIM??3??í?èμ÷???£ê?2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±è??ê?3?2ê1?ü
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** ±è??ê?3?2Nê§?ü *******/
        TIM_OCInitStructure.TIM_Pulse = arr>>1; //éè??′y×°è?2???±è????′??÷μ???3??μ
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //ê?3???D?:TIMê?3?±è????D???
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //?ù?YTIM_OCInitStruct?D???¨μ?2?êy3?ê??ˉíaéèTIMx

        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH2?¤×°??ê1?ü         
        TIM_ARRPreloadConfig(TIM3, ENABLE); //ê1?üTIMx?úARRé?μ??¤×°????′??÷
       
        TIM_ITConfig(TIM3, TIM_IT_Update ,ENABLE);  //TIM3   ê1?ü?ò??ê§?ü???¨μ?TIM?D??

        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3?D??
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //?è??ó??è??1??
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //′óó??è??1??
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQí¨μà±?ê1?ü
        NVIC_Init(&NVIC_InitStructure);  //?ù?YNVIC_InitStruct?D???¨μ?2?êy3?ê??ˉíaéèNVIC??′??÷
       
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //??3yTIMxμ??D??′y′|àí??:TIM ?D???′
        TIM_Cmd(TIM3, ENABLE);  //ê1?üTIM3                                                                          
}
/******* TIM3?üD??D??·t??3ìDò *********/
void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_FLAG_Update)!=RESET)//?üD??D??
        {
                TIM_ClearITPendingBit(TIM3,TIM_FLAG_Update);//??3y?üD??D??±ê????               
                if(is_rcr_finish2==0)//???′??êy?÷?′éè??íê3é
                {
                        if(rcr_integer2!=0) //??êy2?·???3??1?′·¢?ííê3é
                        {
                                TIM3->RCR=RCR_VAL;//éè?????′??êy?μ
                                rcr_integer2--;//??éùRCR_VAL+1????3?                               
                        }else if(rcr_remainder2!=0)//óàêy2?·???3? 2???0
                        {
                                TIM3->RCR=rcr_remainder2-1;//éè??óàêy2?·?
                                rcr_remainder2=0;//??á?
                                is_rcr_finish2=1;//???′??êy?÷éè??íê3é                               
                        }else goto out;   //rcr_remainder2=0£??±?óí?3?                         
                        TIM_GenerateEvent(TIM3,TIM_EventSource_Update);//2úéúò????üD?ê??t ??D?3?ê??ˉ??êy?÷
                        TIM_CtrlPWMOutputs(TIM3,ENABLE);        //MOE ?÷ê?3?ê1?ü       
                        TIM_Cmd(TIM3, ENABLE);  //ê1?üTIM3                       
                        if(motor_dir2==CW) //è?1?·??ò?a?3ê±??   
                                current_pos2+=(TIM3->RCR+1);//?óé????′??êy?μ
                        else          //·??ò·??ò?a??ê±??
                                current_pos2-=(TIM3->RCR+1);//??è¥???′??êy?μ                       
                }else
                {
out:                is_rcr_finish2=1;//???′??êy?÷éè??íê3é
                        TIM_CtrlPWMOutputs(TIM3,DISABLE);        //MOE ?÷ê?3?1?±?
                        TIM_Cmd(TIM3, DISABLE);  //1?±?TIM3                               
       
                }       
        }
}
/***************** ???ˉTIM3 *****************/
void TIM3_Startup(u32 frequency)   //???ˉ?¨ê±?÷3
{
        u16 temp_arr=1000000/frequency-1;
        TIM_SetAutoreload(TIM3,temp_arr);//éè?¨×??ˉ??×°?μ       
        TIM_SetCompare2(TIM3,temp_arr>>1); //?¥???μ2μèóú??×°?μò?°?£?ê?ò?????±è?a50%       
        TIM_SetCounter(TIM3,0);//??êy?÷??á?
        TIM_Cmd(TIM3, ENABLE);  //ê1?üTIM3
}
/********************************************
//?à???¨??oˉêy
//num 0??2147433647
//frequency: 20Hz~100KHz
//dir: CW(?3ê±??·??ò)  CCW(??ê±??·??ò)
*********************************************/
void Locate_Rle2(long num,u32 frequency,DIR_Type dir) //?à???¨??oˉêy
{
        if(num<=0) //êy?μD?μèóú0 ?ò?±?ó·μ??
        {
       
                return;
        }
        if(TIM3->CR1&0x01)//é?ò?′???3??1?′·¢?ííê3é  ?±?ó·μ??
        {
       
                return;
        }
        if((frequency<20)||(frequency>100000))//??3??μ?ê2??ú·??§?ú ?±?ó·μ??
        {
        //        printf(" The frequency is out of range! please reset it!!(range:20Hz~100KHz) ");
                return;
        }
        motor_dir2=dir;//μ?μ?·??ò       
        DRIVER_DIR2=motor_dir2;//éè??·??ò
       
        if(motor_dir2==CW)//?3ê±??
                target_pos2=current_pos2+num;//??±ê????
        else if(motor_dir2==CCW)//??ê±??
                target_pos2=current_pos2-num;//??±ê????
       
        rcr_integer2=num/(RCR_VAL+1);//???′??êy??êy2?·?
        rcr_remainder2=num%(RCR_VAL+1);//???′??êyóàêy2?·?
        is_rcr_finish2=0;//???′??êy?÷?′éè??íê3é
        TIM3_Startup(frequency);//?a??TIM3
}
/********************************************
//?????¨??oˉêy
//num   -2147433643??2147433647
//frequency: 20Hz~100KHz
*********************************************/
void Locate_Abs2(long num,u32 frequency)//?????¨??oˉêy
{
        if(TIM3->CR1&0x01)//é?ò?′???3??1?′·¢?ííê3é ?±?ó·μ??
        {
                printf(" The last time pulses is not send finished,wait please! ");
                return;
        }
        if((frequency<20)||(frequency>100000))//??3??μ?ê2??ú·??§?ú ?±?ó·μ??
        {
                printf(" The frequency is out of range! please reset it!!(range:20Hz~100KHz) ");
                return;
        }
        target_pos2=num;//éè????±ê????
        if(target_pos2!=current_pos2)//??±êoíμ±?°????2?í?
        {
                if(target_pos2>current_pos2)
                        motor_dir2=CW;//?3ê±??
                else
                        motor_dir2=CCW;//??ê±??
                DRIVER_DIR2=motor_dir2;//éè??·??ò
               
                rcr_integer2=abs(target_pos2-current_pos2)/(RCR_VAL+1);//???′??êy??êy2?·?
                rcr_remainder2=abs(target_pos2-current_pos2)%(RCR_VAL+1);//???′??êyóàêy2?·?
                is_rcr_finish2=0;//???′??êy?÷?′éè??íê3é
                TIM3_Startup(frequency);//?a??TIM3
        }
}



/*  头文件
#ifndef __DRIVER2_H
#define __DRIVER2_H
#include "sys.h"
#include "stdlib.h"       
#include "driver.h"

#define DRIVER_DIR2   PAout(6) // Dy×a·??ò
#define DRIVER_OE2    PAout(5) // ê1?ü?? μíμ???óDD§
#define RCR_VAL    255  //????êy£¨RCR_VAL+1£?′?£??D??ò?′?£??a???죨0~255£?éè??′óò?D??éò??μμí?D???μ?ê

//typedef enum
//{
//        CW = 1,//??μ????3ê±??
//        CCW = 0,//μíμ?????ê±??
//}DIR_Type;//??DD·??ò

extern long target_pos2;//óD·?o?·??ò
extern long current_pos2;//óD·?o?·??ò

void Driver_Init2(void);//?y?ˉ?÷3?ê??ˉ
void TIM3_OPM_RCR_Init(u16 arr,u16 psc);//TIM3_CH2 μ¥??3?ê?3?+???′??êy1|?ü3?ê??ˉ
void TIM3_Startup(u32 frequency);   //???ˉ?¨ê±?÷3
void Locate_Rle2(long num,u32 frequency,DIR_Type dir); //?à???¨??oˉêy
void Locate_Abs2(long num,u32 frequency);//?????¨??oˉêy

#endif


*/

1208
2楼-- · 2019-07-21 14:01
帮顶
Electronic
3楼-- · 2019-07-21 18:46
这种方法一定电机可以,如果连续驱动8个步进电机,这样硬件资源是不够的。可以看看国外的SPTA算法,一个定时器驱动N个步进电机。
SunnyOpen
4楼-- · 2019-07-22 00:28
我只驱动四个,定时器好像还够用,可是我一换成定时器1  就不行了,  电机总是抖动
男儿裆自强
5楼-- · 2019-07-22 04:32
 精彩回答 2  元偷偷看……
candylife9
6楼-- · 2019-07-22 05:55
你用示波器测下PWM的频率不就好啦。要么就是定时器配置问题,要么就是驱动器设置问题。

一周热门 更多>