PWM电机调速(寄存器版):分享用定时器3实现小车PWM控制经验?
- 时间:
- 浏览:89
- 来源:中国微特电机网
在技术探索的路上,实现PWM控制电机调速这事,真是让人又爱又恨!网上资料大多泛泛,想要找到合适的真不容易。接下来,咱就好好唠唠用TIM3实现PWM控制电机调速的干货!
开启时钟与引脚配置
咱要使用 TIM3产生PWM波来控制电机调速,第一步就得开启 TIM3的时钟。这得通过 APB1ENR 寄存器去设置才行!并且要把 PB0 和 PA6 这俩引脚配置成复用输出。为啥?因为 TIM3_CH1 通道会映射到 PB0上,TIM3-CH3映射到PA6上,这样 PB0和PA6就算是复用功能输出智能小车电机驱动模块,这一步至关重要。
控制PWM周期
开启了 TIM3 的时钟后,紧接着就是设置 ARR 和 PSC 这俩寄存器的值。这就好比给 PWM波定个大框架,用它们来控制输出 PWM 的周期。这俩值设置得准确,后续产生的 PWM波可就精准得多。设置这些个东西,对实现精准的电机调速太关键,一点儿都不能马虎。
PWM模式设置
把 TIM3 的时钟开启、ARR和PSC 也设置好之后,就轮到设置 TIM3_CH1和TIM3-CH3 的PWM模式!这俩通道默认是冻结状态的,得给它们改改。咱要知道,电机可是低电平转得快的家伙,咱就希望 CCR1 和 CCR3 的值小的时候,电机暗点儿,数值大的时候电机就转得快。那就得好好用 TIM3_CCMR1 和TIM_CCMR2,控制好通道的PWM模式,这里头可不简单。
开关设置与波输出
以上这些事都做好了,接下来把“开关”给搞定。第一步得开启 TIM3 的通道 1 和通道 3 输出,这得靠 TIM3_CCER1和TIM_CCMR2 来设置,它们控制单个通道的“开关”。然后,得开启整个 TIM3,这就得靠 TIM3_CR1 这个“总开关”。把这俩寄存器设置好之后, TIM3 的通道 1和通道 3 上就能看到美妙的PWM波输出了!
占空比控制
void TIM3_Int_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms
TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟
TIM3->DIER|=1<<0; //允许更新中断
TIM3->CR1|=0x01; //使能定时器3
MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2
}
经历前面一堆复杂步骤,这时候 PWM已经开始欢快输出!只不过,这时候的占空比和频率固定得很。咱可以通过修改 TIM3_CCR1和TIM3_CCR3,就可以灵活地控制 CH1和CH2 的输出占空比。调节电机的转速,这一步的占空比控制真是关键中的关键!
void TIM3_PWM_Init(u16 arr,u16 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<1; //TIM3时钟使能
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOB->CRL&=0XFFFFFFF0; //PB0输出
GPIOB->CRL|=0X0000000B; //复用功能输出
GPIOA->CRL&=0XF0FFFFFF; //PA6输出
GPIOA->CRL|=0X0B000000; //复用输出
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器不分频
TIM3->CCMR1|=6<<4; //CH1 PWM2模式
TIM3->CCMR1|=1<<3; //CH1预装载使能
TIM3->CCMR2|=6<<4; //CH3预装载使能
TIM3->CCMR2|=1<<3; //CH3输出使能
TIM3->CCER|=1<<0; //OC1 输出使能
TIM3->CCER|=1<<8;
TIM3->CR1=0x0080; //ARPE使能
TIM3->CR1|=0x01; //使能定时器3
STBY=1;
}
高级定时器提醒
这儿要特别跟大家提点一下,高级定时器虽然和通用定时器有相似的地方,但是它输出 PWM 的方法稍有不同使用高级定时器输出PWM,必须把 TIMx_BDTR 的第 15 位这个叫作MOE位的东西设置好智能小车电机驱动模块,把主输出给使能。要是疏忽了这事,那就啥 PWM 都别想输出了!
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
//1,增加TIM3_PWM_Init函数。
//2,增加left和right宏定义,控制TIM3_CH1脉宽
//通过改变TIM3->CCR1和TIM->CR3的值来改变占空比,从而控制电机的速度
#define left TIM3->CCR1
#define right TIM3->CCR3
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif
还有这个 timer.c文件,这里面包含了定时器 3 的初始化和 PWM 的初始化代码。另外,电机模块的 IO 口初始化也不可或缺,里面有小车前进、后退、左右操作的函数,靠改变 left和right的值能调节电机的速度!通过这么多步骤,用 TIM3控制电机调速应该能实现得差不离儿。
不知道大家在实践中,用这种方法控制电机调速的时候,有没有遇到什么头疼的问题?欢迎在评论区说说,也别忘记点赞和分享!
#include "moter.h"
void MOTER_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOA->CRL&=0XFF0FFFFF;
GPIOA->CRL|=0X00300000;
GPIOA->ODR|=1<<5;
GPIOA->CRL&=0X0FFFFFFF;
GPIOA->CRL|=0X30000000;
GPIOA->ODR|=1<<7;
GPIOB->CRL&=0XFFFFFF0F;
GPIOB->CRL|=0X00000030;
GPIOB->ODR|=1<<1;
GPIOB->CRL&=0XFFFFF0FF;
GPIOB->CRL|=0X00000300;
GPIOB->ODR|=1<<2;
GPIOB->CRL&=0XFFFF0FFF;
GPIOB->CRL|=0X00003000;
GPIOB->ODR|=1<<3;
GPIOB->CRL&=0XFFF0FFFF;
GPIOB->CRL|=0X00030000;
GPIOB->ODR|=1<<4;
GPIOC->CRL&=0XFFF0FFFF;
GPIOC->CRL|=0X00030000;
GPIOC->ODR|=1<<4;
GPIOC->CRL&=0XFF0FFFFF;
GPIOC->CRL|=0X00300000;
GPIOC->ODR|=1<<5;
}
猜你喜欢