玩转电机驱动——DRV8848驱动直流减速电机(STM32F103)
文章目录
- 前言
- 一、硬件基础
- 二、DRV8848驱动
- 1. DDRV8848芯片特性
- 2. 引脚的功能及类型
- 3. DRV8848电路图
- 三、STM32驱动程序
- 1. 电路分析
- 2. 程序编写
- 2.1 main.c
- 2.2 PWM.c
- 2.2 PWM.h
- 总结
前言
采用两块DRV8848驱动四路电机,程序部分参考https://blog.csdn.net/weixin_44808082/article/details/113465107?spm=1001.2014.3001.5501
一、硬件基础
单片机:STM32F103RCT6
电机驱动芯片:DRV8848,两块驱动四路电机
直流减速电机:GB37-520
二、DRV8848驱动
1. DDRV8848芯片特性
(1)工作电源电压范围为4V至18V;
(2)双路H桥电机驱动器,可驱动单/双通道刷式直流、步进电机;
(3)每个H桥均提供高输出电流,最大驱动器电流为2A(12V,25℃),并联模式下最大驱动器电流为4A(12V,25℃);
(4)VM欠压闭锁(UVLO);
(5)过流保护(OCP);
(6)热关断(TSD);
(7)故障条件指示引脚(nFAULT)。
2. 引脚的功能及类型
(1)VCC不是DRV8848上的引脚,但开漏输出nFAULT需要VCC电源电压上拉;nFAULT可能被拉上到VINT
3. DRV8848电路图
四路驱动的DRV8848电路图。
三、STM32驱动程序
1. 电路分析
MCU电路图如下图所示。
结合DRV8848电路图确定引脚,此文暂未用到编码器,因此HALL引脚未列出。
2. 程序编写
利用了TIM2 4个通道产生PWM输出到AIN1、AIN2、BIN1、BIN2,利用AIN1和AIN2之间的PWM差,驱动电机转动。另一个DRV8848同理,其占用了TIM4的4个通道,驱动两组电机。
还有要注意,PA15、PC0接nSLEEP,此引脚需要输出高电平才能使能DRV8848,否则进入低功耗休眠模式。但是PA15默认为JTAG调试的引脚,所以要关闭JTAG,只用SWD调试模式。
2.1 main.c
代码如下:
# include "stm32f10x.h"
# include "LED.h"
# include "Delay.h"
# include "PWM.h"
/***************************************************
TIM2通道1/2控制前左轮电机正反转,CCR1>CCR2时正传
TIM2通道3/4控制前右轮电机正反转,CCR3>CCR4时正传
TIM4通道1/2控制后左轮电机正反转,CCR1>CCR2时正传
TIM4通道3/4控制后右轮电机正反转,CCR3>CCR4时正传
***************************************************/
int main(void)
{ JTAG_Init(); LED_Init(); //LED 连接的硬件接口 MotorEn_Init();Delay_ms(100); Motor_EN(); PWM_TIM2_Init(); //TIM2_PWM输出初始化PWM_TIM4_Init(); //TIM4_PWM输出初始化Delay_ms(1000); //延时等待初始化稳定GPIO_SetBits(GPIOC, GPIO_Pin_3); //设置LED高电平输出Delay_ms(100);GPIO_ResetBits(GPIOC, GPIO_Pin_3); //设置LED高电平输出Delay_ms(100);GPIO_SetBits(GPIOC, GPIO_Pin_3); //设置LED高电平输出while(1){ GPIO_SetBits(GPIOC, GPIO_Pin_3); //设置LED高电平输出Delay_us(20); //延时500毫秒TIM_SetCompare1(TIM2,750); //设置TIM2 CH1占空比输出 PA0TIM_SetCompare2(TIM2,0); //设置TIM2 CH2占空比输出 PA1TIM_SetCompare3(TIM2,1000); //设置TIM2 CH1占空比输出 PA2TIM_SetCompare4(TIM2,0); //设置TIM2 CH2占空比输出 PA3TIM_SetCompare1(TIM4,0); //设置TIM4 CH1占空比输出 PB6TIM_SetCompare2(TIM4,1500); //设置TIM4 CH2占空比输出 PB7TIM_SetCompare3(TIM4,0); //设置TIM4 CH3占空比输出 PB8TIM_SetCompare4(TIM4,2000); //设置TIM4 CH4占空比输出 PB9}
}
2.2 PWM.c
代码如下:
# include "PWM.h"/* 关闭JTAG调试模式,以使用PA15引脚 */
void JTAG_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //先开启开启AFIO复用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA外设时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//关闭JTAG,保留SWD(选择GPIO_Remap_SWJ_Disable,将失去两个调试模式,勿用!)
}/* 配置PC0、PA15的GPIO,初始化DRV8848芯片的使能引脚 */
void MotorEn_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能C口GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能A口GPIO时钟GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //指定引脚PC0,MotEn2GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz; //设置输出速率10MHzGPIO_Init(GPIOC,&GPIO_InitStruct); //初始化外设GPIOC寄存器GPIO_ResetBits(GPIOC, GPIO_Pin_0);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //选择推挽输出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_15; //指定引脚PA15,MotEn1GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz; //设置输出速率10MHzGPIO_Init(GPIOA,&GPIO_InitStruct); //初始化外设GPIOA寄存器GPIO_ResetBits(GPIOA, GPIO_Pin_15);
}/* 使能DRV8848芯片的nSLEEP引脚 */
void Motor_EN(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_15); //PA15_MotorAB_ENGPIO_SetBits(GPIOC, GPIO_Pin_0); //PC0_MotorAB_EN
}/* 配置TIM2定时器输出PWM */
void PWM_TIM2_Init(void)
{/* 开启时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO复用时钟,重映射使用TIM2定时器RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //使能TIM2时钟 /* GPIO初始化结构体 */GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //TIM2 Ch1/2/3/4GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; //速度 10MHzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 GPIOA/* TIM时间基数初始化结构体 */TIM_TimeBaseInitTypeDef TIM_TimeBaseSrtructure; TIM_TimeBaseSrtructure.TIM_Period= TIM2_Reload_Num_ARR; //计数器TIMx_CNT计数,从0累加到ARR次后溢出,设置自动重装载值TIM_TimeBaseSrtructure.TIM_Prescaler=TIM2_Frequency_Divide_PSC; //设置预分频系数 PSCTIM_TimeBaseSrtructure.TIM_ClockDivision=0; //1分频,用于滤波信号抖动TIM_TimeBaseSrtructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式溢出TIM_TimeBaseInit(TIM2,&TIM_TimeBaseSrtructure); //初始化TIM2的时钟参数/* TIM输出比较功能初始化结构体 */TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //选择定时器模式为比较低输出。TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_Pulse =(TIM2_Reload_Num_ARR+1)*0; //比较输出脉冲宽度,设置占空比(初始化用),即CCRTIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出极性:TIM输出比较极性高TIM_OC1Init(TIM2,&TIM_OCInitStructure); //初始化TIM2 CH1的时钟,下同 TIM_OC2Init(TIM2,&TIM_OCInitStructure);TIM_OC3Init(TIM2,&TIM_OCInitStructure);TIM_OC4Init(TIM2,&TIM_OCInitStructure);/* 初始化CH1/2/3/4 */TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable); //CH1 预装载使能,功能在ARR和CCR1改变时,等他们计数完一个周期再修改TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable); //CH2 预装载使能TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable); //CH3 预装载使能TIM_OC4PreloadConfig(TIM2,TIM_OCPreload_Enable); //CH4 预装载使能TIM_ARRPreloadConfig(TIM2,ENABLE); //使能 TIMx在ARR上的预装载寄存器TIM_Cmd(TIM2, ENABLE); //使能 TIM2}void PWM_TIM4_Init(void)
{/* 开启时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO复用时钟,重映射使用TIM4定时器RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //使能TIM4时钟 /* GPIO初始化结构体 */GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //TIM4 Ch1/2/3/4GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; //速度 10MHzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化 GPIOB/* TIM时间基数初始化结构体 */TIM_TimeBaseInitTypeDef TIM_TimeBaseSrtructure; TIM_TimeBaseSrtructure.TIM_Period= TIM4_Reload_Num_ARR; //计数器TIMx_CNT计数,从0累加到ARR次后溢出,设置自动重装载值TIM_TimeBaseSrtructure.TIM_Prescaler=TIM4_Frequency_Divide_PSC; //设置预分频系数 PSCTIM_TimeBaseSrtructure.TIM_ClockDivision=0; //1分频,用于滤波信号抖动TIM_TimeBaseSrtructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式溢出TIM_TimeBaseInit(TIM4,&TIM_TimeBaseSrtructure); //初始化TIM4的时钟参数/* TIM输出比较功能初始化结构体 */TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //选择定时器模式为比较低输出。TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_Pulse =(TIM4_Reload_Num_ARR+1)*0; //比较输出脉冲宽度,设置占空比(初始化用),即CCRTIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出极性:TIM输出比较极性高TIM_OC1Init(TIM4,&TIM_OCInitStructure); //初始化TIM4 CH1的时钟,下同 TIM_OC2Init(TIM4,&TIM_OCInitStructure);TIM_OC3Init(TIM4,&TIM_OCInitStructure);TIM_OC4Init(TIM4,&TIM_OCInitStructure);/* 初始化CH1/2/3/4 */TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable); //CH1 预装载使能,功能在ARR和CCR1改变时,等他们计数完一个周期再修改TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); //CH2 预装载使能TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable); //CH3 预装载使能TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable); //CH4 预装载使能TIM_ARRPreloadConfig(TIM4,ENABLE); //使能 TIMx在ARR上的预装载寄存器TIM_Cmd(TIM4, ENABLE); //使能 TIM4}
2.2 PWM.h
代码如下:
# ifndef _PWM_H
# define _PWM_H
# include "stm32f10x.h"#define TIM2_Reload_Num_ARR 1999 //自动重装载寄存器值
#define TIM2_Frequency_Divide_PSC 35 //TIM时钟预分频值#define TIM4_Reload_Num_ARR 1999 //自动重装载寄存器值
#define TIM4_Frequency_Divide_PSC 35 //TIM时钟预分频值void JTAG_Init(void);
void MotorEn_Init(void);
void Motor_EN(void);
void PWM_TIM2_Init(void); //TIM2_PWM输出初始化
void PWM_TIM4_Init(void); //TIM4_PWM输出初始化#endif
总结
本文利用两个DRV8848驱动四路电机,含STM32F103的程序编写。文内只列出主要程序代码,需要源码请点赞、收藏、回复留邮箱。
玩转电机驱动——DRV8848驱动直流减速电机(STM32F103)相关推荐
- 玩转电机驱动——A4950闭环驱动直流减速电机(Arduino)
玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 文章目录 玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 前言 一.PWM信号 二.PID控制简介 三.增量式(速度 ...
- 用L298驱动直流减速电机
转自:http://hi.baidu.com/brave_xixi/blog/item/86b9bdadd8b522004b36d6d5.html http://bbs.eeworld.com.cn/ ...
- 微型直流减速电机简述:无刷电机与有刷电机区别分析
参考文献 [1] 刘爱民, 倪元相. 电机与拖动技术[M]. 第二版. 大连:大连理工大学出版社, 2017. [2] 王爱元. 控制电机及其应用[M]. 第一版. 上海:上海交通大学出版社, 201 ...
- 编码电机测速(stm32f1/HAL库/CubeMX/编码器模式/平衡小车/直流减速电机/超详细)
系列文章目录(STM32常用外设/HAL库版) 一.HC-SR04超声波模块的使用 二.OLED的HAL库代码介绍及使用 三.直流减速电机的测速以及电机驱动的使用(本篇) 文章目录 系列文章目录(ST ...
- STM32直流减速电机控制篇(一)PWM调速
直流电机原理 下面是分析直流电机的物理模型图.其中,固定部分有磁铁,这里称作主磁极:固定部分还有电刷.转动部分有环形铁芯和绕在环形铁芯上的绕组. 直流电机的转动原理我就不再赘述,比较简单易懂.直接来说 ...
- 智能无障碍轮椅—— 520编码器直流减速电机
文章目录 编码器分类 产品参数 电机型号说明 电机选型 接线说明 为什么使用直流减速电机 编码器输出说明 编码器接口测速 编码器分类 霍尔编码器(磁式) 光电编码器(光学式) 光电编码器容易收到环境光 ...
- BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序
BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序, 无传感的实现是基于反电动势过零点实现的,有传感是霍尔实现. 永磁同步电机有 ...
- 基于TI DRV10970驱动直流无刷电机
前言 之前在实验室接手了一个项目,需要使用TI的DRV10970芯片来驱动直流无刷电机带霍尔反馈,最近这几天把电机调通了,所以写个文章记录一下. 关于直流无刷电机的驱动方式,我也不过多赘述,CSDN上 ...
- 玩转电机驱动——电机编码器
玩转电机驱动--电机编码器 文章目录 玩转电机驱动--电机编码器 前言 一.旋转编码器 1. 光学编码器 2. 光学旋转编码器与Arduino连接 3. 程序 二.Arduino Encoder.h库 ...
最新文章
- Python使用问题汇总
- PostgresSQL生成UUID
- 切割图形_3D打印、激光切割、图形化编程,六一科普活动喊你来报名啦!
- wpf控件设计时支持(1)
- jQuery对Table一个字段排序
- (转)解决fasterxml中string字符串转对象json格式错误问题(无引号 单引号问题)...
- options请求_前端数据请求的终极方案
- SAP License: 发票校验前收货后是否能更改物料价格
- 哪一瞬间让你觉得有妈的孩子像个宝?
- 处理导出到EXCEL时,身份证号码的问题:mso-number-format
- KVM系列之硬件管理
- 无水印的html5制作软件,ScreenToGif-开源、简单、无水印的gif动图制作软件
- weboffice集成
- 【工具】——远程协助(向日葵)
- 灵棋排盘(七政四余)入门指导—排盘与框架
- 笔记本电脑怎么在桌面添加计算机,怎么在笔记本电脑上添加便签,笔记本电脑桌面便签设置密码...
- Pycharm: ImportError: attempted relative import with no known parent package解决方案
- 调用百度aip实现短语音翻译(附代码)
- VC知识库视频大讲坛系列之GDI GDI+从入门到精通
- Cookies vs. Sessions