给大家分享一些平衡车的相关文件,
基于SM32的脉冲输出定位控制
所有资料51hei提供下载:
基于SM32的脉冲输出定位控制.rar
(276.16 KB, 下载次数: 21)
TIMER2_PWM_005单片机源程序如下(stm32芯片):
- /*简易运动控制器*/
- /*脉冲+方向控制步进伺服电机*/
- /*由PORTA.0口输出占空比为50%的脉冲*/
- /*GPIOA.0为脉冲输出*/
- /*GPIOB.5为方向输出*/
- /*DRVI(A,B);相对定位,以B的频率输出A(A取绝对值)个脉冲A不能为0,若A为正数,方向GPIOB.5为高电平;反之,负数,低电平*/
- /*DRVA(A,B);绝对定位,以B的频率输出脉冲,运行至A个脉冲的位置*/
- #include "stm32reg.h"
- #include "system_stm32.h"
- long mubiao;//有符号方向
- long dangqian;//有符号方向
- STATUS_Type run;
- void MyTimer2_Init()
- {
- RSTCLKCTRL->APB2CLKEN|=(1<<2)|(1<<0);//使能AFIO、GPIOA时钟
- GPIOA->CONFG[0]&=0xfffffff0;
- GPIOA->CONFG[0]|=0x0000000a; //配置PORTA.0为复用推挽输出,输出最大频率2MHz
-
- RSTCLKCTRL->APB1CLKEN|=1; //使能定时器TIMER2时钟
- TIMER2->PRESC=64-1; //设置定时器2预分频值,使定时器得到1MHz的计数频率
- TIMER2->CONTROL1|=1<<2; //设置只有计数溢出作为更新中断
- TIMER2->DMAINTEN|=1<<0; //允许定时器2计数溢出中断
-
- Interrupt_Priority(28,0,2,group_2); //使能第28号中断(即定时器2全局中断),抢占0响应2,中断分组2
-
- TIMER2->CAPCMPMOD1&=~(3<<0); //CC1通道配置为输出模式
- TIMER2->CAPCMPMOD1|=7<<4; //输出比较1为PWM模式2
- TIMER2->CAPCMPEN|=1<<0; //通道1输出使能
-
- }
- void Timer2_Startup(u16 frequency) //启动定时器2
- {
- if(frequency<20) frequency=20; //最小频率设定为20,因为频率设定过小,得到的重装值会超出16位
- TIMER2->RELOAD=1000000/frequency-1; //设定重装值
- TIMER2->CAPCMP1=TIMER2->RELOAD>>1; //匹配值1等于重装值一半,是以占空比为50%
- MyDelay(10,ms); //脉冲信号比方向信号滞后,以提高可靠性
- TIMER2->CONTROL1|=1<<0; //启动定时器TIMER2计数
- }
- void DRVI(long num,u16 frequency) //相对定位函数
- {
- 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) //绝对定位函数
- {
- 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() //定时器2全局中断函数
- {
- if(TIMER2->STATUS&0x0001)
- {
- if(GPIOB->OUTDATA&(1<<5)) //如果方向为正
- {
- dangqian++;
- }
- else //否则方向为负
- {
- dangqian--;
- }
- if(dangqian==mubiao) //计数溢出次数、也即输出的脉冲个数达到目标值
- {
- TIMER2->CONTROL1&=~(1<<0); //停止定时器2计数、也即停止脉冲输出
- run=OFF; //复位脉冲定位指令执行标志
- }
- TIMER2->STATUS=0x0000;
- }
- }
- int main(void)
- {
- u32 tp,tp1;
- mubiao=0;//目标位置脉冲值
- dangqian=0;//当前位置脉冲值
- run=OFF;//脉冲定位指令执行标志
-
- System_Init();
-
- RSTCLKCTRL->APB2CLKEN|=(1<<3)|(1<<6);//使能GPIOB、GPIOE时钟
-
- GPIOB->CONFG[0]&=0xff0fffff;
- GPIOB->CONFG[0]|=0x00300000;//GPIOB.5配置为推挽输出,作为脉冲的方向信号输出
- 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();//定时器2初始化
-
- while(1)
- {
- tp=GPIOE->INDATA;//读取按键输入
- if(tp&0x001f)
- {
- MyDelay(10,ms);//延时消抖,输入滤波
- tp1=GPIOE->INDATA;//再次读取按键输入
- if((tp&0x001f)&&(tp==tp1))//确实有按键输入,且两次读取的值一致
- {
- if(run==OFF)//如果此时正在发生脉冲输出,不接受新命令,
- {
- run=ON;//置位脉冲定位指令执行标志
- switch(tp&0x001f)
- {
- case 0x0001:DRVI(20,20);break;//按下按键PE0,前进20脉冲
- case 0x0002:DRVI(-25,33);break;//按下按键PE1,后退25脉冲
- case 0x0004:DRVA(0,50);break;//按下按键PE2,回零点
- case 0x0008:DRVA(15,25);break;//按下按键PE3,运动到绝对位置15脉冲处
- case 0x0010:DRVA(-5,40);break;//按下按键PE4,运动到绝对位置-5脉冲处
- }
- }
- }
- }
- }
- }
复制代码
- /*由PORTA.0口输出占空比为50%的脉冲,脉冲数量无限,脉冲频率指定*/
- #include "stm32reg.h"
- #include "system_stm32.h"
- void MyTimer2_Init()
- {
- RSTCLKCTRL->APB2CLKEN|=(1<<2)|(1<<0);//使能AFIO、GPIOA时钟
- GPIOA->CONFG[0]&=0xfffffff0;
- GPIOA->CONFG[0]|=0x0000000a; //配置PORTA.0为复用推挽输出,输出最大频率2MHz
-
- RSTCLKCTRL->APB1CLKEN|=1; //使能定时器TIMER2时钟
- TIMER2->PRESC=64-1; //设置定时器2预分频值,使定时器得到1MHz的计数频率
-
- 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; //启动定时器TIMER2计数
- }
- 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);//本例没有使用中断,不需要分组
- MyTimer2_Init();
- MyTimer2_Startup(33);
-
- while(1)
- {
- GPIOB->BITRST=1<<5;
- MyDelay(100,ms);
- GPIOB->BITSETRST=1<<5;
- MyDelay(100,ms);
- }
- }
复制代码
|