|
給大家分享一些平衡車(chē)的相關(guān)文件,
基于SM32的脈沖輸出定位控制
所有資料51hei提供下載:
基于SM32的脈沖輸出定位控制.rar
(276.16 KB, 下載次數(shù): 21)
2017-8-11 20:45 上傳
點(diǎn)擊文件名下載附件
TIMER2_PWM_005單片機(jī)源程序如下(stm32芯片):
- /*簡(jiǎn)易運(yùn)動(dòng)控制器*/
- /*脈沖+方向控制步進(jìn)伺服電機(jī)*/
- /*由PORTA.0口輸出占空比為50%的脈沖*/
- /*GPIOA.0為脈沖輸出*/
- /*GPIOB.5為方向輸出*/
- /*DRVI(A,B);相對(duì)定位,以B的頻率輸出A(A取絕對(duì)值)個(gè)脈沖A不能為0,若A為正數(shù),方向GPIOB.5為高電平;反之,負(fù)數(shù),低電平*/
- /*DRVA(A,B);絕對(duì)定位,以B的頻率輸出脈沖,運(yùn)行至A個(gè)脈沖的位置*/
- #include "stm32reg.h"
- #include "system_stm32.h"
- long mubiao;//有符號(hào)方向
- long dangqian;//有符號(hào)方向
- STATUS_Type run;
- void MyTimer2_Init()
- {
- RSTCLKCTRL->APB2CLKEN|=(1<<2)|(1<<0);//使能AFIO、GPIOA時(shí)鐘
- GPIOA->CONFG[0]&=0xfffffff0;
- GPIOA->CONFG[0]|=0x0000000a; //配置PORTA.0為復(fù)用推挽輸出,輸出最大頻率2MHz
-
- RSTCLKCTRL->APB1CLKEN|=1; //使能定時(shí)器TIMER2時(shí)鐘
- TIMER2->PRESC=64-1; //設(shè)置定時(shí)器2預(yù)分頻值,使定時(shí)器得到1MHz的計(jì)數(shù)頻率
- TIMER2->CONTROL1|=1<<2; //設(shè)置只有計(jì)數(shù)溢出作為更新中斷
- TIMER2->DMAINTEN|=1<<0; //允許定時(shí)器2計(jì)數(shù)溢出中斷
-
- Interrupt_Priority(28,0,2,group_2); //使能第28號(hào)中斷(即定時(shí)器2全局中斷),搶占0響應(yīng)2,中斷分組2
-
- TIMER2->CAPCMPMOD1&=~(3<<0); //CC1通道配置為輸出模式
- TIMER2->CAPCMPMOD1|=7<<4; //輸出比較1為PWM模式2
- TIMER2->CAPCMPEN|=1<<0; //通道1輸出使能
-
- }
- void Timer2_Startup(u16 frequency) //啟動(dòng)定時(shí)器2
- {
- if(frequency<20) frequency=20; //最小頻率設(shè)定為20,因?yàn)轭l率設(shè)定過(guò)小,得到的重裝值會(huì)超出16位
- TIMER2->RELOAD=1000000/frequency-1; //設(shè)定重裝值
- TIMER2->CAPCMP1=TIMER2->RELOAD>>1; //匹配值1等于重裝值一半,是以占空比為50%
- MyDelay(10,ms); //脈沖信號(hào)比方向信號(hào)滯后,以提高可靠性
- TIMER2->CONTROL1|=1<<0; //啟動(dòng)定時(shí)器TIMER2計(jì)數(shù)
- }
- void DRVI(long num,u16 frequency) //相對(duì)定位函數(shù)
- {
- if(num>0)
- {
- GPIOB->BITSETRST=1<<5;
- }
- else if(num<0)
- {
- GPIOB->BITRST=1<<5;
- }
- mubiao=dangqian+num;
- Timer2_Startup(frequency);
- }
- void DRVA(long num,u16 frequency) //絕對(duì)定位函數(shù)
- {
- mubiao=num;
- if(mubiao==dangqian)
- {
- run=OFF;
- }
- else
- {
- if(mubiao>dangqian)
- {
- GPIOB->BITSETRST=1<<5;
- }
- else
- {
- GPIOB->BITRST=1<<5;
- }
- Timer2_Startup(frequency);
- }
- }
- void TIM2_IRQHandler() //定時(shí)器2全局中斷函數(shù)
- {
- if(TIMER2->STATUS&0x0001)
- {
- if(GPIOB->OUTDATA&(1<<5)) //如果方向?yàn)檎?nbsp;
- {
- dangqian++;
- }
- else //否則方向?yàn)樨?fù)
- {
- dangqian--;
- }
- if(dangqian==mubiao) //計(jì)數(shù)溢出次數(shù)、也即輸出的脈沖個(gè)數(shù)達(dá)到目標(biāo)值
- {
- TIMER2->CONTROL1&=~(1<<0); //停止定時(shí)器2計(jì)數(shù)、也即停止脈沖輸出
- run=OFF; //復(fù)位脈沖定位指令執(zhí)行標(biāo)志
- }
- TIMER2->STATUS=0x0000;
- }
- }
- int main(void)
- {
- u32 tp,tp1;
- mubiao=0;//目標(biāo)位置脈沖值
- dangqian=0;//當(dāng)前位置脈沖值
- run=OFF;//脈沖定位指令執(zhí)行標(biāo)志
-
- System_Init();
-
- RSTCLKCTRL->APB2CLKEN|=(1<<3)|(1<<6);//使能GPIOB、GPIOE時(shí)鐘
-
- GPIOB->CONFG[0]&=0xff0fffff;
- GPIOB->CONFG[0]|=0x00300000;//GPIOB.5配置為推挽輸出,作為脈沖的方向信號(hào)輸出
- GPIOB->BITRST=1<<5;
-
- GPIOE->CONFG[0]&=0xfff00000;
- GPIOE->CONFG[0]|=0x00088888;//GPIOE.0/1/2/3/4配置為上下拉輸入,作為按鍵
- GPIOE->BITRST=0x001f;
-
- Interrupt_Group(group_2);//中斷分組,只要一次
- MyTimer2_Init();//定時(shí)器2初始化
-
- while(1)
- {
- tp=GPIOE->INDATA;//讀取按鍵輸入
- if(tp&0x001f)
- {
- MyDelay(10,ms);//延時(shí)消抖,輸入濾波
- tp1=GPIOE->INDATA;//再次讀取按鍵輸入
- if((tp&0x001f)&&(tp==tp1))//確實(shí)有按鍵輸入,且兩次讀取的值一致
- {
- if(run==OFF)//如果此時(shí)正在發(fā)生脈沖輸出,不接受新命令,
- {
- run=ON;//置位脈沖定位指令執(zhí)行標(biāo)志
- switch(tp&0x001f)
- {
- case 0x0001:DRVI(20,20);break;//按下按鍵PE0,前進(jìn)20脈沖
- case 0x0002:DRVI(-25,33);break;//按下按鍵PE1,后退25脈沖
- case 0x0004:DRVA(0,50);break;//按下按鍵PE2,回零點(diǎn)
- case 0x0008:DRVA(15,25);break;//按下按鍵PE3,運(yùn)動(dòng)到絕對(duì)位置15脈沖處
- case 0x0010:DRVA(-5,40);break;//按下按鍵PE4,運(yùn)動(dòng)到絕對(duì)位置-5脈沖處
- }
- }
- }
- }
- }
- }
復(fù)制代碼
- /*由PORTA.0口輸出占空比為50%的脈沖,脈沖數(shù)量無(wú)限,脈沖頻率指定*/
- #include "stm32reg.h"
- #include "system_stm32.h"
- void MyTimer2_Init()
- {
- RSTCLKCTRL->APB2CLKEN|=(1<<2)|(1<<0);//使能AFIO、GPIOA時(shí)鐘
- GPIOA->CONFG[0]&=0xfffffff0;
- GPIOA->CONFG[0]|=0x0000000a; //配置PORTA.0為復(fù)用推挽輸出,輸出最大頻率2MHz
-
- RSTCLKCTRL->APB1CLKEN|=1; //使能定時(shí)器TIMER2時(shí)鐘
- TIMER2->PRESC=64-1; //設(shè)置定時(shí)器2預(yù)分頻值,使定時(shí)器得到1MHz的計(jì)數(shù)頻率
-
- TIMER2->CAPCMPMOD1&=~(3<<0); //CC1通道配置為輸出模式
- TIMER2->CAPCMPMOD1|=7<<4; //輸出比較1為PWM模式2
- TIMER2->CAPCMPEN|=1<<0; //通道1輸出使能
-
- }
- void MyTimer2_Startup(u16 frequency)
- {
- if(frequency<20) frequency=20;
- TIMER2->RELOAD=1000000/frequency-1;
- TIMER2->CAPCMP1=TIMER2->RELOAD>>1;
- TIMER2->CONTROL1|=1<<0; //啟動(dòng)定時(shí)器TIMER2計(jì)數(shù)
- }
- void TIM2_IRQHandler()
- {
-
- }
- int main(void)
- {
- System_Init();
-
- RSTCLKCTRL->APB2CLKEN|=1<<3;
-
- GPIOB->CONFG[0]&=0xff0fffff;
- GPIOB->CONFG[0]|=0x00300000;
- GPIOB->BITRST=1<<5;
-
- //Interrupt_Group(group_2);//本例沒(méi)有使用中斷,不需要分組
- MyTimer2_Init();
- MyTimer2_Startup(33);
-
- while(1)
- {
- GPIOB->BITRST=1<<5;
- MyDelay(100,ms);
- GPIOB->BITSETRST=1<<5;
- MyDelay(100,ms);
- }
- }
復(fù)制代碼
|
|