文章目录

  • 前言
  • 一、硬件基础
  • 二、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)相关推荐

  1. 玩转电机驱动——A4950闭环驱动直流减速电机(Arduino)

    玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 文章目录 玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 前言 一.PWM信号 二.PID控制简介 三.增量式(速度 ...

  2. 用L298驱动直流减速电机

    转自:http://hi.baidu.com/brave_xixi/blog/item/86b9bdadd8b522004b36d6d5.html http://bbs.eeworld.com.cn/ ...

  3. 微型直流减速电机简述:无刷电机与有刷电机区别分析

    参考文献 [1] 刘爱民, 倪元相. 电机与拖动技术[M]. 第二版. 大连:大连理工大学出版社, 2017. [2] 王爱元. 控制电机及其应用[M]. 第一版. 上海:上海交通大学出版社, 201 ...

  4. 编码电机测速(stm32f1/HAL库/CubeMX/编码器模式/平衡小车/直流减速电机/超详细)

    系列文章目录(STM32常用外设/HAL库版) 一.HC-SR04超声波模块的使用 二.OLED的HAL库代码介绍及使用 三.直流减速电机的测速以及电机驱动的使用(本篇) 文章目录 系列文章目录(ST ...

  5. STM32直流减速电机控制篇(一)PWM调速

    直流电机原理 下面是分析直流电机的物理模型图.其中,固定部分有磁铁,这里称作主磁极:固定部分还有电刷.转动部分有环形铁芯和绕在环形铁芯上的绕组. 直流电机的转动原理我就不再赘述,比较简单易懂.直接来说 ...

  6. 智能无障碍轮椅—— 520编码器直流减速电机

    文章目录 编码器分类 产品参数 电机型号说明 电机选型 接线说明 为什么使用直流减速电机 编码器输出说明 编码器接口测速 编码器分类 霍尔编码器(磁式) 光电编码器(光学式) 光电编码器容易收到环境光 ...

  7. BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序

    BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序, 无传感的实现是基于反电动势过零点实现的,有传感是霍尔实现. 永磁同步电机有 ...

  8. 基于TI DRV10970驱动直流无刷电机

    前言 之前在实验室接手了一个项目,需要使用TI的DRV10970芯片来驱动直流无刷电机带霍尔反馈,最近这几天把电机调通了,所以写个文章记录一下. 关于直流无刷电机的驱动方式,我也不过多赘述,CSDN上 ...

  9. 玩转电机驱动——电机编码器

    玩转电机驱动--电机编码器 文章目录 玩转电机驱动--电机编码器 前言 一.旋转编码器 1. 光学编码器 2. 光学旋转编码器与Arduino连接 3. 程序 二.Arduino Encoder.h库 ...

最新文章

  1. Python使用问题汇总
  2. PostgresSQL生成UUID
  3. 切割图形_3D打印、激光切割、图形化编程,六一科普活动喊你来报名啦!
  4. wpf控件设计时支持(1)
  5. jQuery对Table一个字段排序
  6. (转)解决fasterxml中string字符串转对象json格式错误问题(无引号 单引号问题)...
  7. options请求_前端数据请求的终极方案
  8. SAP License: 发票校验前收货后是否能更改物料价格
  9. 哪一瞬间让你觉得有妈的孩子像个宝?
  10. 处理导出到EXCEL时,身份证号码的问题:mso-number-format
  11. KVM系列之硬件管理
  12. 无水印的html5制作软件,ScreenToGif-开源、简单、无水印的gif动图制作软件
  13. weboffice集成
  14. 【工具】——远程协助(向日葵)
  15. 灵棋排盘(七政四余)入门指导—排盘与框架
  16. 笔记本电脑怎么在桌面添加计算机,怎么在笔记本电脑上添加便签,笔记本电脑桌面便签设置密码...
  17. Pycharm: ImportError: attempted relative import with no known parent package解决方案
  18. 调用百度aip实现短语音翻译(附代码)
  19. VC知识库视频大讲坛系列之GDI GDI+从入门到精通
  20. Cookies vs. Sessions

热门文章

  1. day01 - jQuery
  2. 数控雕刻机控制器_数控雕刻机系统
  3. 【游戏程序设计】程序框架
  4. 上网制作“网络地理图册”网页
  5. 高性能图表控件LightningChart中Datagrid的Pasar datos deview闪电图问题解答
  6. 浅谈:刷机必备神器,不断更新
  7. 从IT时代转入DT时代 安防应该注意什么?
  8. NSIS使用总结,安装包制作(图解)
  9. 单片机音乐演奏(STC89C51)
  10. 故事--你不杀伯仁,伯仁确因你而死