精確輸出脈沖數控制電機,使用stm32單片機的pwm功能實現,精確控制脈沖個數
單片機源程序如下:
- #include <stm32f10x_lib.h>
- #include "sys.h"
- #include "usart.h"
- #include "delay.h"
- #include "led.h"
- #include "exti.h"
- #include "key.h"
- #define MOTOR_DIR PBout(11)// PB11
- #define MOTOR_EN PEout(15)// PE15
- u16 i;
- u16 fre;
- u16 TIM5CH1_CAPTURE_VAL; //輸入捕獲值
- u16 PUL_CNT;
- void Motor_Set()
- {
- RCC->APB2ENR|=1<<3; //使能PORTB時鐘
- GPIOB->CRH&=0XFFFF0FFF;
- GPIOB->CRH|=0X00003000; //PB11 推挽輸出
- GPIOB->ODR|=(1<<11); //PB11 輸出高
- RCC->APB2ENR|=1<<6; //使能PORTE時鐘
- GPIOE->CRH&=0X0FFFFFFF;
- GPIOE->CRH|=0X30000000; //PE15 推挽輸出
- GPIOE->ODR|=(1<<15); //PE15 輸出高
- MOTOR_EN=0; //不使能
- }
- void Timer3_Init(u16 arr,u16 psc)
- {
- RCC->APB2ENR|=1<<2; //使能PORTA時鐘
- RCC->APB2ENR|=1<<3; //使能PORTB時鐘
- RCC->APB2ENR|=1<<5; //使能PORTD時鐘
- GPIOB->CRL&=0XFF0FFFFF; //PB5輸出
- GPIOB->CRL|=0X00B00000; //復用功能輸出
- GPIOA->CRL&=0x00ffffff;
- GPIOA->CRL|=0xBB000000;
- GPIOA->ODR|=3<<6;
- GPIOB->CRL&=0xffffff00;
- GPIOB->CRL|=0x000000BB;
- GPIOB->ODR|=3;
- RCC->APB1ENR|=1<<1;//TIM3時鐘使能
- TIM3->CR1|=1<<4;//向下計數
- TIM3->CCMR1=0x6868;//通道1、2PWM模式1,預裝載使能
- TIM3->CCMR2=0x6868;//通道3、4PWM模式1,預裝載使能
-
- TIM3->CCR1=100;
- TIM3->CCR2=200;
- TIM3->CCR3=200;
- TIM3->CCR4=100; //4k->250
- TIM3->ARR=arr; //設定計數器自動重裝值//剛好0.1ms
- TIM3->PSC=psc; //預分頻器7200,得到10Khz的計數時鐘
- // TIM3->ARR=1000; //設定計數器自動重裝值 1000=1ms 10000=10ms(1~10ms對應1000~100hz)
- // TIM3->PSC=72; //預分頻器72,得到1Mhz的計數時鐘
- TIM3->CCER=0X1111;//打開四個通道,允許輸出,有效電平為高
- TIM3->CR1|=1<<7;
- TIM3->EGR|=1;
- //這兩個東東要同時設置才可以使用中斷
- TIM3->DIER|=1<<0; //允許更新中斷
- TIM3->DIER|=1<<6; //允許觸發中斷
- TIM3->CR1|=0x01; //使能定時器3
- }
- void Timer4_Init(u16 arr,u16 psc)
- {
- RCC->APB1ENR|=1<<2;//TIM4時鐘使能
- TIM4->ARR=arr; //設定計數器自動重裝值//剛好1ms
- TIM4->PSC=psc; //預分頻器7200,得到10Khz的計數時鐘
- //這兩個東東要同時設置才可以使用中斷
- TIM4->DIER|=1<<0; //允許更新中斷
- TIM4->DIER|=1<<6; //允許觸發中斷
-
- TIM4->CR1|=0x01; //使能定時器4
- MY_NVIC_Init(1,3,TIM4_IRQChannel,2);//搶占1,子優先級3,組2
- }
- void TIM4_IRQHandler(void)
- {
- if(TIM4->SR&0X0001)//溢出中斷
- {
- LED2=!LED2;
- }
- TIM4->SR&=~(1<<0);//清除中斷標志位
- }
- void Timer2_Init(u16 arr,u16 psc)
- {
- RCC->APB1ENR|=1<<0;//TIM4時鐘使能
- TIM2->ARR=arr; //設定計數器自動重裝值//剛好1ms
- TIM2->PSC=psc; //預分頻器7200,得到10Khz的計數時鐘
- //這兩個東東要同時設置才可以使用中斷
- TIM2->DIER|=1<<0; //允許更新中斷
- TIM2->DIER|=1<<6; //允許觸發中斷
-
- TIM2->CR1&=0xfe; //不使能定時器2
- // TIM2->CR1|=0x01; //使能定時器2
- MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//搶占1,子優先級3,組2
- }
- void TIM2_IRQHandler(void) //1s到
- {
- if(TIM2->SR&0X0001)//溢出中斷
- {
- EXTI->IMR &=~(1<<0); //關閉外部中斷
- TIM2->CR1&=0xfe; //不使能定時器2
- fre=TIM5CH1_CAPTURE_VAL/2; //計算出頻率
- printf("%d \r\n",fre);
- TIM5CH1_CAPTURE_VAL=0;
- LED1=!LED1;
- EXTI->IMR |= (1<<0); //打開外部中斷
- }
- TIM2->SR&=~(1<<0);//清除中斷標志位
- }
- //定時器3中斷服務程序
- void TIM3_IRQHandler(void)
- {
- if(TIM3->SR&0X0001)//溢出中斷
- {
-
- }
- TIM3->SR&=~(1<<0);//清除中斷標志位
- }
-
- //外部中斷0服務程序
- void EXTI0_IRQHandler(void)
- {
- TIM2->CR1|=0x01; //使能定時器2
- TIM5CH1_CAPTURE_VAL ++;
- PUL_CNT ++;
- if(TIM5CH1_CAPTURE_VAL%500==0)
- LED3 = !LED3;
- EXTI->PR=1<<0; //清除LINE0上的中斷標志位
- }
-
- int main(void)
- {
- u16 Motor_cnt;
- Stm32_Clock_Init(9); //系統時鐘設置
- delay_init(72); //延時初始化
- uart_init(72,115200); //串口初始化
- LED_Init(); //初始化與LED連接的硬件接口
- KEY_Init(); //按鍵
- Timer3_Init(1000-1,72-1); //1MHZ 周期1MS 定時器3產生PWM
- EXTIX_Init(); //外部中斷
- Motor_Set(); //電機參數設置
- Timer4_Init(2000,7200);
- Timer2_Init(10000-1,7200-1);
- LED1=0;TIM3->CR1&=0xfe;
- while(1)
- {
- //delay_ms(100);
- if(PUL_CNT==1600) //800個脈沖一圈
- { PUL_CNT=0;
- MOTOR_EN=0;
- TIM3->CR1&=0xfe;
- }
- if(KEY3==0)
- {
- LED0=0;
- while(KEY3==0); LED0=1;
- MOTOR_DIR = !MOTOR_DIR;
- }
- if(KEY1==0)
- {
- LED0=0;TIM5CH1_CAPTURE_VAL=0;
- while(KEY1==0); LED0=1;
- MOTOR_EN = 1;//!MOTOR_EN;
- TIM3->CR1|=0x01;
- TIM3->ARR=1000;
- LED2 = !LED2;
- }
- if(KEY2==0)
- {
- LED0=0;MOTOR_EN=1; TIM5CH1_CAPTURE_VAL=0;
- while(KEY2==0); LED0=1;
- for(Motor_cnt=1000;Motor_cnt>250;Motor_cnt--)
- { if(Motor_cnt<252)
- Motor_cnt=249;
- TIM3->ARR=Motor_cnt;
- delay_ms(5);
- }
- LED3 = !LED3;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
PWM實現精確輸出脈沖數控制電機.rar
(350.48 KB, 下載次數: 167)
2017-8-22 17:55 上傳
點擊文件名下載附件
stm32精確控制脈沖輸出
|