单片机|(3)下位机部分-水下管道智能巡检-方案STM32+树梅派+python+opencv—水下机器人

前言: 浏览目录:
学习目标: 这一部分讲讲定时器和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参照上文配置即可。
要注意高级定时器和 普通定时器之间的配置差别。

    推荐阅读