(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_PIN     GPIO_Pin_1  
#define TIM3_CH3_PIN     GPIO_Pin_0
#define TIM3_CH2_PIN	 GPIO_Pin_7
#define TIM3_CH1_PIN     GPIO_Pin_6
 
#define TIM1_CH4_PIN     GPIO_Pin_11
#define TIM1_CH1_PIN     GPIO_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);/* 高级定时器要使能下面两行 否则不会输出PWM  TIM3则不需要*/
	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*/
}

如果要配置其他定时器输出PWM参照上文配置即可。
要注意高级定时器和 普通定时器之间的配置差别。

你可能感兴趣的:(单片机,人工智能,嵌入式,深度学习,机器学习)