使用STM32 再实现PWM小车两轮分别调速

关于PWM调速的原理,其实在之前89C52开发小车的时候也已经详细的描述过,所以主要的区别还是STM32和89C52的PWM实现区别。

关于STM32的PWM实现,是从CubeMX的配置开始的:

CubeMX

1. 在上节的CubeMX项目基础上进行修改

2. 两路PWM分别选择TIM2的CH1(对应PA0)和 TIM2的CH2(对应PA1),PWM的周期为20ms,在Tclk = 72000 000的前提下,将PSC设置为7199;ARR设置为199

另外,还要强调一点和89C52控制小车调速不同的地方:

  • 89C52中,生成PWM波后,在有效电平期间,对控制电机的引脚写数据让轮子进行前进或后退
  • 而在STM32中我直接将控制电机的引脚配成了时钟的PWM波输出

所以:

我如果希望对“前进”调速,应该将两路的PWM的有效电平设置为LOW,并把PB1和PB10的GPIO初值设为HIGH

我如果希望对“后退”调速,应该将两路的PWM的有效电平设置为HIGH,并把PB1和PB10的GPIO初值设为LOW

此处,我希望对前进调速,所以“应该将两路的PWM的有效电平设置为LOW,并把PB1和PB10的GPIO初值设为HIGH

2.1 同时注意,由于刚刚配置了PA0和PA1为GPIO的输出,所以TIM2的CH1和CH2会自动分配到其他复用引脚上,所以要将PA0和PA1设置回TIM2的CH1和CH2输出:

 3. 惯例设置更新代码

Keil

ARR的199对应20ms,所以CCRx的值是0到199,每增加1就说明在一个周期(20ms)内,增加了 20/199 约等于0.1ms的 有效电平持续时间!

void speed_left(int speed) //speed就是CCRx的值,理论在0到199之间,实际最好大于130
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, speed);//左轮调速
}

void speed_right(int speed) //speed就是CCRx的值,理论在0到199之间,实际最好大于130
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, speed);//左轮调速
}


int main(void)
{
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); //打开Timer2的1号Channel, 1号通道对应 左轮
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); //打开Timer2的2号Channel, 2号通道对应 右轮

  while (1)
  {	
		speed_left(140);
		speed_right(199);
  }
}

实现效果

可见,右轮速度全力运转而左轮则慢些,这就是PWM实现的两轮分别调速:

代码封装 

在代码测试成功后,将两轮分别调速的代码封装到motor.c中:

motor.c:

#include "motor.h"
#include "gpio.h"
#include "tim.h"

#define left_B_1A_HIGH HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET)
#define left_B_1A_LOW HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET)

#define left_B_1B_HIGH HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET)
#define left_B_1B_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET)

#define right_A_1A_HIGH HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)
#define right_A_1A_LOW HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET)

#define right_A_1B_HIGH HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET)
#define right_A_1B_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET)



void move_backward(void) //后退
{
	left_B_1A_HIGH;
	left_B_1B_LOW;
	
	right_A_1A_HIGH;
	right_A_1B_LOW;
}
 
void move_forward(void) //前进
{
	left_B_1A_LOW;
	left_B_1B_HIGH;
	
	right_A_1A_LOW;
	right_A_1B_HIGH;
}
 
void move_leftturn(void) //左转
{
	left_B_1A_LOW; //左轮不动
	left_B_1B_LOW;
	
	right_A_1A_LOW; //右轮往前
	right_A_1B_HIGH;
}
 
void move_rightturn(void) //右转
{
	left_B_1A_LOW; //左轮往前
	left_B_1B_HIGH;
	
	right_A_1A_LOW; //右轮不动
	right_A_1B_LOW;
}
 
void move_stop(void) //停止
{
	left_B_1A_LOW;
	left_B_1B_LOW;
	
	right_A_1A_LOW;
	right_A_1B_LOW;
}

void speed_left(int speed) //speed就是CCRx的值,理论在0到199之间,实际最好大于130
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, speed);//左轮调速
}

void speed_right(int speed) //speed就是CCRx的值,理论在0到199之间,实际最好大于130
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, speed);//左轮调速
}

motor.h:

#ifndef __motor_H__ // "XXXX"就是h文件的名字
#define __motor_H__
 
void move_backward(void);
void move_forward(void);
void move_leftturn(void);
void move_rightturn(void);
void move_stop(void);

void speed_left(int speed);
void speed_right(int speed);
 
 
#endif 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值