前言: 浏览目录:
学习目标: 这一部分讲讲定时器和PWM,这一部分的5路PWM的产生是由TIM3(普通定时器-4个通道)和TIM1(高级定时器-7个通道),TIM1定时器的PWM配置过程是比普通定时器的配置多两行代码的,它所包含的其他功能我们现在这里还用不上我们只需要它输出PWM即可,笔者这里将以TIM1定时器和 TIM3定时器为例讲解怎么配置定时器输出PWM。
还有比较重要的就是PWM频率的计算方法:公式Fpwm = 100M / ((arr+1)*(psc+1))(单位:Hz)
例如:我们需要50hz的频率 单片机主频为72Mhz那么:
50hz=72M/(49+1)(71+1) 可以得出arr=49,psr=71,当然这只是举个例子如果arr的可调节范围太小将会影响后面PID的调节,不建议ARR的值过小。当然arr和psr这两个值自己凑只要凑出正确的结果就行。
笔者这里arr的值为1999无刷电机坏了临时用的直流电机所以没有频率的限制。若用无刷电机务必要严格计算频率。
定时器配置步骤: 1,时钟使能
2,配置预分频、自动重装值和重复计数值和计数模式
3,配置TIM1-CHx的通道,配置OC为PWM
4,使能定时器
TIM1和TIM3定时器配置代码:
#define ARR 1999
#define PWM_COUNTER_MODE TIM_CounterMode_Up/* 引脚的定义 */
#define TIM3_CH4_PINGPIO_Pin_1
#define TIM3_CH3_PINGPIO_Pin_0
#define TIM3_CH2_PINGPIO_Pin_7
#define TIM3_CH1_PINGPIO_Pin_6
#define TIM1_CH4_PINGPIO_Pin_11
#define TIM1_CH1_PINGPIO_Pin_8/* PWM初始化函数 */
void pwm_init(void);
/* 封装了一下官方的arr调节函数
* 原函数形式TIM_SetComparex(TIMx,x);
* 毕竟我们要控制很多电机
*/
void motor1_pwm(int a);
/*GPIO_Pin_6 GPIOA*/
void motor2_pwm(int a);
/*GPIO_Pin_7 GPIOA*/
void motor3_pwm(int a);
/*GPIO_Pin_0 GPIOB*/
void motor4_pwm(int a);
/*GPIO_Pin_1 GPIOB*/
void motor5_pwm(int a);
/*GPIO_Pin_8 GPIOA*/void TIM1_CH4_init()
{
GPIO_InitTypeDef pwm;
/* 定义GPIO结构体 用于初始化GPIO */
TIM_TimeBaseInitTypeDef tim1;
/* 定义定时器结构体 用于初始化定时器 */
TIM_OCInitTypeDef tim_oc;
/* 配置定时器通道结构体 用于初始化通道 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*使能GPIOA时钟 和 TIM1定时器的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
/* 配置GPIOA PIN11 */
pwm.GPIO_Mode=GPIO_Mode_AF_PP;
pwm.GPIO_Pin=TIM1_CH4_PIN;
pwm.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&pwm);
/* 配置定时器 */
tim1.TIM_ClockDivision=TIM_CKD_DIV1;
/* 设置分频值DIV1就是不分频 */
tim1.TIM_CounterMode=PWM_COUNTER_MODE;
/* 定时器的计数模式 向上还是向下 参考宏定义 */
tim1.TIM_Period=ARR;
/* 定时器预装值 */
tim1.TIM_Prescaler=71;
/* 设置预分频值 */
TIM_TimeBaseInit(TIM1,&tim1);
/* 初始化定时器 */
/* 配置通道 */
tim_oc.TIM_OCMode=TIM_OCMode_PWM1;
/* 模式为PWM */
tim_oc.TIM_OCPolarity=TIM_OCPolarity_High;
/* 极性为高*/
tim_oc.TIM_OutputState=TIM_OutputState_Enable;
/* 时能输出 */
tim_oc.TIM_Pulse=0;
/* 占空比为 */
TIM_OC4Init(TIM1,&tim_oc);
//使能 arr 预装载寄存器moe
TIM_CtrlPWMOutputs(TIM1,ENABLE);
/* 高级定时器要使能下面两行 否则不会输出PWMTIM3则不需要*/
TIM_ARRPreloadConfig(TIM1,ENABLE);
TIM_OC1PolarityConfig(TIM1,ENABLE);
//使能tim1
TIM_Cmd(TIM1,ENABLE);
}void TIM3_CH1_init()
{
GPIO_InitTypeDef pwm;
TIM_TimeBaseInitTypeDef tim3;
TIM_OCInitTypeDef tim3_oc;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
//初始化gpio->A6
pwm.GPIO_Mode=GPIO_Mode_AF_PP;
pwm.GPIO_Pin=TIM3_CH1_PIN;
pwm.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&pwm);
//初始化tim3定时器
tim3.TIM_ClockDivision=TIM_CKD_DIV1;
tim3.TIM_CounterMode=PWM_COUNTER_MODE;
tim3.TIM_Period=ARR;
tim3.TIM_Prescaler=71;
TIM_TimeBaseInit(TIM3,&tim3);
//初始化tim3——ch1通道
tim3_oc.TIM_OCMode=TIM_OCMode_PWM1;
tim3_oc.TIM_OCPolarity=TIM_OCPolarity_High;
tim3_oc.TIM_OutputState=TIM_OutputState_Enable;
tim3_oc.TIM_Pulse=0;
TIM_OC1Init(TIM3,&tim3_oc);
//TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM_OC1PolarityConfig(TIM3,TIM_OCPreload_Enable);
//使能tim3
TIM_Cmd(TIM3,ENABLE);
} void pwm_init()
{
TIM1_CH1_init();
/*motor5*/
TIM1_CH4_init();
TIM3_CH1_init();
/*motor1*/
TIM3_CH2_init();
/*motor2*/
TIM3_CH3_init();
/*motor3*/
TIM3_CH4_init();
/*motor4*/
}
【单片机|(3)下位机部分-水下管道智能巡检-方案STM32+树梅派+python+opencv—水下机器人】如果要配置其他定时器输出PWM参照上文配置即可。
要注意高级定时器和 普通定时器之间的配置差别。
推荐阅读
- machine|GridSearchCV调参方法
- 计算机视觉|Anomaly Detection 异常检测之 CSI(Contrasting shifted instances论文解读)
- 机器学习|Python实现词云舞
- python相关学习|用python批量修改图片名称!超级简单
- 编程语言大杂烩|Python批量改变图片名字
- 当人工智能遇上安全|[当人工智能遇上安全] 2.清华张超老师 - GreyOne: Discover Vulnerabilities with Data Flow Sensitive Fuzzing
- 历史上的今天|【历史上的今天】5 月 3 日(戴尔公司成立;“深蓝”再战象棋冠军;计算机先驱诞生日)
- YOLO-V4|yolov4 darknet编译和训练自己的数据集
- Darkent|Darknet-Yolo系列(一)利用 Darknet 在自己的数据集上训练 Yolov4-tiny 模型