標題: STM32 PWM實現(xiàn)精確輸出脈沖數(shù)控制電機 [打印本頁]

作者: gaozm    時間: 2017-8-22 17:44
標題: STM32 PWM實現(xiàn)精確輸出脈沖數(shù)控制電機
精確輸出脈沖數(shù)控制電機,使用stm32單片機的pwm功能實現(xiàn),精確控制脈沖個數(shù)

單片機源程序如下:
  1. #include <stm32f10x_lib.h>
  2. #include "sys.h"
  3. #include "usart.h"               
  4. #include "delay.h"       
  5. #include "led.h"
  6. #include "exti.h"
  7. #include "key.h"
  8. #define MOTOR_DIR PBout(11)// PB11
  9. #define MOTOR_EN  PEout(15)// PE15
  10. u16 i;
  11. u16 fre;
  12. u16        TIM5CH1_CAPTURE_VAL;        //輸入捕獲值
  13. u16 PUL_CNT;
  14. void Motor_Set()
  15. {
  16.         RCC->APB2ENR|=1<<3;    //使能PORTB時鐘                    
  17.         GPIOB->CRH&=0XFFFF0FFF;
  18.         GPIOB->CRH|=0X00003000;  //PB11 推挽輸出            
  19.     GPIOB->ODR|=(1<<11);      //PB11 輸出高
  20.         RCC->APB2ENR|=1<<6;    //使能PORTE時鐘                    
  21.         GPIOE->CRH&=0X0FFFFFFF;
  22.         GPIOE->CRH|=0X30000000;  //PE15 推挽輸出            
  23.     GPIOE->ODR|=(1<<15);      //PE15 輸出高
  24.         MOTOR_EN=0; //不使能
  25. }          
  26. void Timer3_Init(u16 arr,u16 psc)
  27. {
  28.         RCC->APB2ENR|=1<<2;    //使能PORTA時鐘
  29.         RCC->APB2ENR|=1<<3;    //使能PORTB時鐘
  30.         RCC->APB2ENR|=1<<5;    //使能PORTD時鐘
  31.         GPIOB->CRL&=0XFF0FFFFF;        //PB5輸出
  32.         GPIOB->CRL|=0X00B00000;        //復(fù)用功能輸出           

  33.         GPIOA->CRL&=0x00ffffff;
  34.         GPIOA->CRL|=0xBB000000;
  35.         GPIOA->ODR|=3<<6;
  36.         GPIOB->CRL&=0xffffff00;
  37.         GPIOB->CRL|=0x000000BB;
  38.         GPIOB->ODR|=3;
  39.         RCC->APB1ENR|=1<<1;//TIM3時鐘使能
  40.         TIM3->CR1|=1<<4;//向下計數(shù)
  41.         TIM3->CCMR1=0x6868;//通道1、2PWM模式1,預(yù)裝載使能
  42.         TIM3->CCMR2=0x6868;//通道3、4PWM模式1,預(yù)裝載使能
  43.        
  44.         TIM3->CCR1=100;
  45.         TIM3->CCR2=200;
  46.         TIM3->CCR3=200;
  47.         TIM3->CCR4=100; //4k->250
  48.         TIM3->ARR=arr;  //設(shè)定計數(shù)器自動重裝值//剛好0.1ms   
  49.         TIM3->PSC=psc;  //預(yù)分頻器7200,得到10Khz的計數(shù)時鐘
  50. //        TIM3->ARR=1000;  //設(shè)定計數(shù)器自動重裝值  1000=1ms                  10000=10ms(1~10ms對應(yīng)1000~100hz)
  51. //        TIM3->PSC=72;  //預(yù)分頻器72,得到1Mhz的計數(shù)時鐘
  52.         TIM3->CCER=0X1111;//打開四個通道,允許輸出,有效電平為高
  53.         TIM3->CR1|=1<<7;
  54.         TIM3->EGR|=1;
  55.                 //這兩個東東要同時設(shè)置才可以使用中斷
  56.         TIM3->DIER|=1<<0;   //允許更新中斷                               
  57.         TIM3->DIER|=1<<6;   //允許觸發(fā)中斷
  58.         TIM3->CR1|=0x01;    //使能定時器3  
  59. }

  60. void Timer4_Init(u16 arr,u16 psc)
  61. {
  62.         RCC->APB1ENR|=1<<2;//TIM4時鐘使能   
  63.         TIM4->ARR=arr;  //設(shè)定計數(shù)器自動重裝值//剛好1ms   
  64.         TIM4->PSC=psc;  //預(yù)分頻器7200,得到10Khz的計數(shù)時鐘
  65.         //這兩個東東要同時設(shè)置才可以使用中斷
  66.         TIM4->DIER|=1<<0;   //允許更新中斷   
  67.         TIM4->DIER|=1<<6;   //允許觸發(fā)中斷
  68.                
  69.         TIM4->CR1|=0x01;    //使能定時器4
  70.         MY_NVIC_Init(1,3,TIM4_IRQChannel,2);//搶占1,子優(yōu)先級3,組2         
  71. }
  72. void TIM4_IRQHandler(void)
  73. {
  74.         if(TIM4->SR&0X0001)//溢出中斷
  75.         {
  76.                 LED2=!LED2;                                     
  77.         }      
  78.         TIM4->SR&=~(1<<0);//清除中斷標志位   
  79. }
  80. void Timer2_Init(u16 arr,u16 psc)
  81. {
  82.         RCC->APB1ENR|=1<<0;//TIM4時鐘使能   
  83.         TIM2->ARR=arr;  //設(shè)定計數(shù)器自動重裝值//剛好1ms   
  84.         TIM2->PSC=psc;  //預(yù)分頻器7200,得到10Khz的計數(shù)時鐘
  85.         //這兩個東東要同時設(shè)置才可以使用中斷
  86.         TIM2->DIER|=1<<0;   //允許更新中斷   
  87.         TIM2->DIER|=1<<6;   //允許觸發(fā)中斷
  88.                
  89.         TIM2->CR1&=0xfe;    //不使能定時器2
  90. //        TIM2->CR1|=0x01;    //使能定時器2
  91.         MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//搶占1,子優(yōu)先級3,組2       
  92. }
  93. void TIM2_IRQHandler(void)        //1s到
  94. {
  95.         if(TIM2->SR&0X0001)//溢出中斷
  96.         {
  97.                 EXTI->IMR &=~(1<<0); //關(guān)閉外部中斷
  98.                 TIM2->CR1&=0xfe;    //不使能定時器2
  99.                 fre=TIM5CH1_CAPTURE_VAL/2; //計算出頻率
  100.                 printf("%d \r\n",fre);
  101.                 TIM5CH1_CAPTURE_VAL=0;
  102.                 LED1=!LED1;       
  103.                 EXTI->IMR |= (1<<0); //打開外部中斷                                        
  104.         }      
  105.         TIM2->SR&=~(1<<0);//清除中斷標志位   
  106. }
  107. //定時器3中斷服務(wù)程序
  108. void TIM3_IRQHandler(void)
  109. {                                                                   
  110.         if(TIM3->SR&0X0001)//溢出中斷
  111.         {       
  112.                                                                                                                        
  113.         }                                  
  114.         TIM3->SR&=~(1<<0);//清除中斷標志位             
  115. }
  116.                                
  117. //外部中斷0服務(wù)程序
  118. void EXTI0_IRQHandler(void)
  119. {
  120.         TIM2->CR1|=0x01;    //使能定時器2
  121.         TIM5CH1_CAPTURE_VAL ++;
  122.         PUL_CNT ++;
  123.         if(TIM5CH1_CAPTURE_VAL%500==0)
  124.         LED3 = !LED3;         
  125.         EXTI->PR=1<<0;  //清除LINE0上的中斷標志位  
  126. }
  127.                                        
  128. int main(void)
  129. {       
  130.         u16 Motor_cnt;
  131.         Stm32_Clock_Init(9); //系統(tǒng)時鐘設(shè)置
  132.         delay_init(72);             //延時初始化
  133.         uart_init(72,115200);  //串口初始化
  134.         LED_Init();                           //初始化與LED連接的硬件接口
  135.         KEY_Init();                        //按鍵
  136.         Timer3_Init(1000-1,72-1);                //1MHZ 周期1MS  定時器3產(chǎn)生PWM
  137.         EXTIX_Init();                //外部中斷
  138.         Motor_Set();                //電機參數(shù)設(shè)置
  139.         Timer4_Init(2000,7200);

  140.         Timer2_Init(10000-1,7200-1);

  141.         LED1=0;TIM3->CR1&=0xfe;
  142.            while(1)
  143.         {
  144.                 //delay_ms(100);
  145.                 if(PUL_CNT==1600)  //800個脈沖一圈
  146.                 {        PUL_CNT=0;
  147.                         MOTOR_EN=0;
  148.                         TIM3->CR1&=0xfe;                                                    
  149.                 }
  150.                 if(KEY3==0)
  151.                 {       
  152.                         LED0=0;
  153.                         while(KEY3==0);        LED0=1;
  154.                         MOTOR_DIR = !MOTOR_DIR;
  155.                 }
  156.                 if(KEY1==0)
  157.                 {       
  158.                         LED0=0;TIM5CH1_CAPTURE_VAL=0;
  159.                         while(KEY1==0);        LED0=1;
  160.                         MOTOR_EN = 1;//!MOTOR_EN;
  161.                         TIM3->CR1|=0x01;
  162.                         TIM3->ARR=1000;
  163.                         LED2 = !LED2;
  164.                 }
  165.                 if(KEY2==0)
  166.                 {
  167.                         LED0=0;MOTOR_EN=1; TIM5CH1_CAPTURE_VAL=0;
  168.                         while(KEY2==0);        LED0=1;
  169.                         for(Motor_cnt=1000;Motor_cnt>250;Motor_cnt--)
  170.                         {        if(Motor_cnt<252)
  171.                                         Motor_cnt=249;
  172.                                 TIM3->ARR=Motor_cnt;
  173.                                 delay_ms(5);       
  174.                         }
  175.                         LED3 = !LED3;
  176.                 }  
  177.         }         
  178. }
復(fù)制代碼

所有資料51hei提供下載:
PWM實現(xiàn)精確輸出脈沖數(shù)控制電機.rar (350.48 KB, 下載次數(shù): 167)



作者: raohuayun188    時間: 2019-10-12 18:01
學習了
作者: raohuayun188    時間: 2019-10-14 13:52
感謝。!
作者: neng_liang    時間: 2019-10-19 18:40
學習一下
作者: ryoostar    時間: 2019-10-21 14:19
謝謝樓主分享!
作者: kissme    時間: 2019-10-23 17:22
位帶操作實在看著費解




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1