<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> STM32 >> 瀏覽文章

        stm32_定時器3控制PWM的輸出脈沖_步進電機的控制

        作者:碧海藍天   來源:來自碧海藍天   點擊數:  更新時間:2014年07月30日   【字體:

        碧海藍天的步進電機控制程序采用定時器TIM3來控制PWM的輸出來產生頻率變化的脈沖。

        過程:加速——勻速——減速——停止

        文件:stepmotor.c  定義步進電機控制程序

        //用到的tim2為了實現另外的功能可以忽視

        #include "stepmotor.h"
        #include

        u32 PUL_CNT;   // TIM3脈沖計數
        vu32 step_done;
        vu32 run_state;

        #define run_state_stop 0
        #define run_state_acc 1
        #define run_state_run 2
        #define run_state_dec 3

        void STEPMOTOR_CTRL_INIT(void)
        {
         GPIO_InitTypeDef GPIO_InitStructure;
         NVIC_InitTypeDef NVIC_InitStructure;
         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
         TIM_OCInitTypeDef TIM_OCInitStructure;

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //GPIO時鐘使能
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //定時器3時鐘使能 
            //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //定時器2時鐘使能

         GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;    //PA7為TIM3通道2
         GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  //復用推免輸出
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //GPIO口響應速度 
         GPIO_Init(GPIOA, &GPIO_InitStructure);

         GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;    //PA6為DIR控制輸出
         GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;  //推免輸出
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //GPIO口響應速度 
         GPIO_Init(GPIOA, &GPIO_InitStructure);

         //TIM3_Configuration
         TIM_TimeBaseStructure.TIM_Period            = 23999;     //自動重裝載寄存器
         TIM_TimeBaseStructure.TIM_Prescaler         = 2;      //預分頻器,t=(23999+1)*(2+1)/72M
         TIM_TimeBaseStructure.TIM_CounterMode       = TIM_CounterMode_Up; //計數器向上計數模式     
         TIM_TimeBaseStructure.TIM_ClockDivision     = 0x0;      //時鐘分頻因子
         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;      //每次溢出都產生事件更新
         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);       //寫TIM3各寄存器參數
          TIM_ClearFlag(TIM3,TIM_FLAG_Update);          //中斷標志位清零
         TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);       //允許捕獲/比較3中斷

         TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM2;   //PWM模式2 TIM3_CCMR1[14:12]=111 在向上計數時,一旦TIMx_CNT
         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //輸入/捕獲2輸出允許
         TIM_OCInitStructure.TIM_Pulse       = 40;       //確定占空比,這個值決定了有效電平的時間。
         TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_Low;      //輸出極性,低電平有效   
         TIM_OC2Init(TIM3, &TIM_OCInitStructure);         //配置定時器輸出模式,比較參數等
         TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);       //使能TIM3在CCR2上的預裝載寄存器

         //TIM2_Configuration
            TIM_DeInit(TIM2);          //TIM2重新配置為缺省值,默認狀態
         
         
         TIM_TimeBaseStructure.TIM_Period        = 359;     //自動重裝載寄存器
         TIM_TimeBaseStructure.TIM_Prescaler     = 199;     //時鐘預分頻器
         TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;   //計數器向上計數模式          
         TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;         //時鐘分頻因子 
         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);     //配置TIM2寄存器各參數
         
         TIM_ClearFlag(TIM2,TIM_FLAG_Update);          //中斷標志位清零
         TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);       //允許捕獲/比較2中斷

         NVIC_InitStructure.NVIC_IRQChannel          = TIM3_IRQn ;  //選擇定時器TIM3
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;          //選擇搶先式優先級(與中斷嵌套級別有關)
         NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 2;       //選擇子優先級(同搶先式優先級的響應順序)
         NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;    //選擇使能中斷源
         NVIC_Init(&NVIC_InitStructure);

         NVIC_InitStructure.NVIC_IRQChannel          = TIM2_IRQn ;  //選擇定時器TIM2
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;          //選擇搶先式優先級(與中斷嵌套級別有關)
         NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;       //選擇子優先級(同搶先式優先級的響應順序)
         NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;    //選擇使能中斷源
         NVIC_Init(&NVIC_InitStructure);
        }

        void TIM3_Configuration(u32 period)
        {
         TIM3->ARR = period-1;
         TIM3->CCR2 = period >> 2;
         //TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
         //TIM_OCInitTypeDef TIM_OCInitStructure;

         //TIM_TimeBaseStructure.TIM_Period            = period-1;      //自動重裝載寄存器
         //TIM_TimeBaseStructure.TIM_Prescaler         = 29;    //預分頻器,f=72M/[(period+1)*(29+1)], ft = 2400000
         //TIM_TimeBaseStructure.TIM_CounterMode       = TIM_CounterMode_Up; //計數器向上計數模式     
         //TIM_TimeBaseStructure.TIM_ClockDivision     = 0x0;      //時鐘分頻因子
         //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;      //每次溢出都產生事件更新
         //TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);       //寫TIM3各寄存器參數

         //TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM2;   //PWM模式2 TIM3_CCMR1[14:12]=111 在向上計數時,一旦TIMx_CNT
         //TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //輸入/捕獲2輸出允許
         //TIM_OCInitStructure.TIM_Pulse       = period >> 2;     //確定占空比,25%
         //TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_Low;      //輸出極性,低電平有效   
         //TIM_OC2Init(TIM3, &TIM_OCInitStructure);         //配置定時器輸出模式,比較參數等
        }
        //void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis)
        //步進電機運行參數
        //acc -- 加速度,單位: round/min/s
        //dec -- 減速度,單位: round/min/s
        //topspeed -- 最高速度,單位: round/min
        //dis -- 總角位移,單位: round/10000
        void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis)
        {
          u32 t_acc,t_dec,step_all,step_acc,step_dec,step_run;
          u32 i,tim_cnt,tim_rest,tim_cnt_temp;
          
          step_all = (float)dis * (N_MOTOR * 0.0001);

          t_acc = topspeed * 1000 / acc; //unit: ms
          t_dec = topspeed * 1000 / dec; //unit: ms

          if(topspeed * (t_acc + t_dec) / 12 > dis)  //達不到最高速度 // topspeed/60/1000 * (t_acc + t_dec) / 2 > dis / 10000
          {
            topspeed = sqrt(dis * acc * dec * 12 / (acc + dec) / 1000);
            t_acc = topspeed * 1000 / acc; //unit: ms
            t_dec = topspeed * 1000 / dec; //unit: ms 
          }

          step_acc = N_MOTOR * ((float)topspeed*topspeed/(acc*120));
          step_dec = N_MOTOR * ((float)topspeed*topspeed/(dec*120));
          if(step_all > step_acc + step_dec)
           step_run = step_all - step_acc - step_dec;
          else
           step_run = 0;

          //tim_cnt = 5.2363 * ft / (sqrt(acc*N_MOTOR/2)); //(ft * sqrt(60)*0.676) / sqrt(acc*N_MOTOR/2);
          tim_cnt = 7.7460 * ft / (sqrt(acc*N_MOTOR/2));
          tim_rest = 0;
          i = 0;
          TIM3_Configuration(tim_cnt);
          run_state = run_state_acc;
          TIM_Cmd(TIM3,ENABLE);
          step_done = 0;
          while(step_done==0);
          while(i
          {
            i++;
            //tim_cnt_temp = tim_cnt;
            //tim_cnt = tim_cnt - (2*tim_cnt+tim_rest) / (4*i+1);
            //tim_rest = (2*tim_cnt_temp+tim_rest) % (4*i+1);
            tim_cnt_temp = tim_cnt / ( sqrt((float)(i+1)) + sqrt((float)(i)) );
            TIM3_Configuration(tim_cnt_temp);
            step_done = 0;
            while(step_done==0);
          }
          
          if(step_run > 0)
          {
            run_state = run_state_run;
            tim_cnt = ft * 60 / (N_MOTOR*topspeed);
            i = 0;
            TIM3_Configuration(tim_cnt);
            while(i
            {
              step_done = 0;
              while(step_done==0);
              i++;
            }
          }

          run_state = run_state_dec;
          tim_rest = 0;
          i=0;
          tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1);
          while(i
          {
            TIM3_Configuration(tim_cnt);
            step_done = 0;
            while(step_done==0);
            i++;
            tim_cnt_temp = tim_cnt;
            tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1);
            tim_rest = (2*tim_cnt_temp+tim_rest) % (4*(step_dec-i)-1);
          }
          run_state = run_state_stop;
          TIM_Cmd(TIM3,DISABLE);
        }

        void TIM2_IRQHandler(void)
        {
          

         

        }

        void TIM3_IRQHandler(void)
        {
          TIM_ClearFlag(TIM3,TIM_FLAG_Update);

         step_done = 1; 

         //PUL_CNT++;  
        }

        文件:stepmotor.h  聲明步進電機控制頭文件

        #define N_MOTOR 10000 //步進電機細分
        #define ft 24000000

        void STEPMOTOR_CTRL_INIT(void);
        void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis);

         

        文件:main.c  主函數,設置加速度,減速度,最大速度和步數的參數值

        #include "main.h"

        #define LED_SET() GPIO_SetBits(GPIOB,GPIO_Pin_8)
        #define LED_RST() GPIO_ResetBits(GPIOB,GPIO_Pin_8)

        #define SET_DIR_CW() GPIO_SetBits(GPIOA,GPIO_Pin_6)
        #define SET_DIR_CCW() GPIO_ResetBits(GPIOA,GPIO_Pin_6)

        void NVIC_Configuration(void);
        void LED_init(void);
        void soft_delayms(u16 t);

        int main(void)
        {
         SystemInit();
         STEPMOTOR_CTRL_INIT();

         soft_delayms(1000);
         
         while(1)
         {
          SET_DIR_CW();
          MOTOR_RUN(600,600,1000,500000);
          soft_delayms(1000);
          
          SET_DIR_CCW();
          MOTOR_RUN(600,600,1000,500000);
          soft_delayms(1000);         
         }
         return 0;
        }

        void NVIC_Configuration(void)
        {
          NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); //將中斷矢量放到Flash的0地址
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //設置優先級配置的模式,詳情請閱讀原材料中的文章
        }

        void LED_init(void)
        {
         GPIO_InitTypeDef GPIO_InitStruct;

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
         GPIO_Init(GPIOB, &GPIO_InitStruct);
        }

        void soft_delayms(u16 t)
        {
         u16 tt;
         while(t--)
         {
          tt = 10000;
          while(tt--);
         }
        }

        #ifndef  _MAIN_H
        #define  _MAIN_H

        #include "stm32f10x.h"
        #include "stepmotor.h"

         

        #endif

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮