说明:本文是对自己学习过程的一次总结,不然学完很容易就忘了
电机驱动板优点大功率,管脚占用少,自带编码器输出,HAL编程简单。
不想了解细节,可以直接下载源码和PCB
链接:驱动板
链接:C8T6代码 提取码:abds 。可能需要打开"Reset and Run"
管脚描述L_EN,R_EN是PWM管脚,L_A,L_B,R_A,R_B是编码器管脚;L_PH,R_PH是换向管脚;最后一个管脚是GND
驱动板原理介绍
驱动芯片选取DRV8701
控制逻辑
nSLEEP、EN、PH为输入管脚,SH1,SH2为相位检测管脚(不用管),AVDD和DVDD是两路LDO,用于输出3.3V
4.8V输出。(1、H代表高电平,0、L代表低电平。ENabled代表使能,Disable代表失能)
nSLEEP通过电阻分压产生3.3V,EN由单片机产生PWM进行调速,PH接单片机产生高低电平控制方向。
H桥
H桥由四个MOS管组成,Q1和Q4导通,Q2和Q3关断,电机正转;Q1和Q4关断,Q2和Q3导通,电机反转。
总结优点
- 拥有两路LDO输出,一路为3.3V,一路为4.8V,可以为运行指示灯供电和编码器供电,减少外围电路。
- 具有比较好的隔离效果。
- 可以调节驱动电流,从而驱动不同的MOS管。
驱动板软件配置及其编程
STM32CubeMX配置
工程名字及其编译环境设置,编译器使用KEIL5
包含.h和.c文件
Debug设置
设置系统时钟为72M
时钟输入设置,外部时钟输入
定时器1设置为PWM输出口,72M/72/100=10K,频率为10KHZ。
设置定时器2,编码器模式(Encoder Mode),编码器会输出两路方波信号,如果只在通道A的上升沿计数,那就是1倍频;通道A的上升、下降沿计数,那就是2倍频;如果在通道A、B的上升、下降沿计数,那就是4倍频。Encoder Mode TI1 and TI2 是 4倍频。
设置定时器为定时器功能,每10ms检测一次编码器数值。1 * 7200/72M * 100=10ms
设置定时器优先级,TIM3优先级最高,不断读取编码器数值
生成工程
引入打印头文件
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
重定义打印函数
先打开USE MocroLIB
重定义打印函数
/* USER CODE BEGIN 0 */
int fputc(int ch, FILE *p)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE* f)
{
uint8_t ch;
HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
/* USER CODE END 0 */
定义变量
/* USER CODE BEGIN PTD */
float speed,count;//speed:1minute编码器速度,count:10ms的速度
/* USER CODE END PTD */
输出PWM,并且修改占空比,开启定时器中断。
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // TIM1_CH1(pwm)
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); // TIM1_CH4(pwm)
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_4, 99); //通过修改比较值来改变占空比
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 99); //通过修改比较值来改变占空比
// 开启AB相编码器定时器
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_1|TIM_CHANNEL_2);
// 开启定时器2,3中断
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */
打印“speed”
/* USER CODE BEGIN 3 */
printf("speed:%d\n\r", (int)(speed));
HAL_Delay(500);
}
/* USER CODE END 3 */
编码器测速代码
此处设定根据电机实际参数设定(4:AB向上下沿采样;13:转动一圈13个脉冲;30:30的减速比)
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
// 3号定时器中断
if(htim == (&htim3))
{
// 设置测量频率为100Hz(10ms)
int rate = 100;
// 获取编码器信号数
short encoder = __HAL_TIM_GET_COUNTER(&htim2);
// 计算10ms的速度
count = ((float)encoder)/4/13/30;//4:AB向上下沿采样;13:转动一圈13个脉冲;30:30的减速比
// 编码器数据清零
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 计数1minute的转速
speed = count * rate* 60;//10ms*100*60=1minute
}
}
/* USER CODE END 4 */