当前位置: 首页 > news >正文

【STM32】DRV8833驱动电机

1.电机如何转动

只需要给电机两个端子加一正一负的极性就会转起来了,但是要注意的是不要将电机两端直接接在5v和gnd之间,这种电机一般要提供几百毫安的电流,而GPIO口只能提供几毫安,所以我们使用一个DRV8833来驱动
在这里插入图片描述
DRV8833输入口要接PA0,PA1,并且供电,通过OUT1,OUT2连接电机
在这里插入图片描述
IN1,IN2对应PA0,PA1。
如果要使电机转速发生改变,我们可以将通入DRV8833的IN1,IN2接PWM即可。通过改变高电平时间实现转速的快慢
在这里插入图片描述

2.DRV8833

在这里插入图片描述
因为有两对输出口,则一个DRV8833可以驱动两个电机,对应SLEEP引脚是如果开启,则驱动芯片停止工作,实现低功耗,FAULT引脚是出现控制错误时提醒单片机

3.DRV8833驱动代码

drv8833.h


#ifndef __DRV8833_H_
#define __DRV8833_H_

#include <stdint.h>

/**
 * @brief 衰减模式枚举
 */
typedef enum {
    SLOW_DECAY,  /**< 慢衰减模式 */
    FAST_DECAY   /**< 快衰减模式 */
} DecayMode;

/**
 * @brief 初始化DRV8833
 */
void DRV8833_Init(void);

/**
 * @brief 设置衰减模式
 * @param mode 衰减模式
 */
void DRV8833_SetDecayMode(DecayMode mode);

/**
 * @brief 控制电机前进
 * @param speed 速度值(0-100)
 */
void DRV8833_Forward(uint8_t speed);

/**
 * @brief 控制电机后退
 * @param speed 速度值(0-100)
 */
void DRV8833_Backward(uint8_t speed);

/**
 * @brief 电机刹车
 */
void DRV8833_Brake(void);

/**
 * @brief 电机滑行
 */
void DRV8833_Coast(void);

#endif /* __DRV8833_H_ */

drv8833.c

/**
 * @file drv8833.c
 * @brief DRV8833双H桥电机驱动器控制实现
 */

#include "drv8833.h"
#include "tim.h"

/** @brief IN1引脚的定时器 */
#define IN1_TIM &htim2
/** @brief IN2引脚的定时器 */
#define IN2_TIM &htim2

/** @brief IN1引脚的定时器通道 */
#define IN1_CH TIM_CHANNEL_1
/** @brief IN2引脚的定时器通道 */
#define IN2_CH TIM_CHANNEL_2

/** @brief 最大速度值 */
#define MAX_SPEED 100


/** @brief 当前衰减模式 */
static DecayMode currentDecayMode = SLOW_DECAY;

/**
 * @brief 设置IN1引脚的PWM占空比
 * @param duty 占空比值
 */
static inline void __SetIn1PWM(uint8_t duty)
{
    __HAL_TIM_SET_COMPARE(IN1_TIM, IN1_CH, duty);
}

/**
 * @brief 设置IN2引脚的PWM占空比
 * @param duty 占空比值
 */
static inline void __SetIn2PWM(uint8_t duty)
{
    __HAL_TIM_SET_COMPARE(IN2_TIM, IN2_CH, duty);
}

/**
 * @brief 初始化DRV8833
 */
void DRV8833_Init(void)
{
    HAL_TIM_PWM_Start(IN1_TIM, IN1_CH);
    HAL_TIM_PWM_Start(IN2_TIM, IN2_CH);
}

/**
 * @brief 设置衰减模式
 * @param mode 衰减模式
 */
void DRV8833_SetDecayMode(DecayMode mode)
{
    currentDecayMode = mode;
}

/**
 * @brief 控制电机前进
 * @param speed 速度值(0-100)
 */
void DRV8833_Forward(uint8_t speed)
{
    if (speed > MAX_SPEED)
        speed = MAX_SPEED;
    
    if (currentDecayMode == FAST_DECAY) {
        __SetIn1PWM(speed);
        __SetIn2PWM(0);
    } else {
        __SetIn1PWM(MAX_SPEED);
        __SetIn2PWM(MAX_SPEED - speed);
    }
}

/**
 * @brief 控制电机后退
 * @param speed 速度值(0-100)
 */
void DRV8833_Backward(uint8_t speed)
{
    if (speed > MAX_SPEED)
        speed = MAX_SPEED;
    
    if (currentDecayMode == FAST_DECAY) {
        __SetIn1PWM(0);
        __SetIn2PWM(speed);
    } else {
        __SetIn1PWM(MAX_SPEED - speed);
        __SetIn2PWM(MAX_SPEED);
    }
}

/**
 * @brief 电机刹车
 */
void DRV8833_Brake(void)
{
    __SetIn1PWM(MAX_SPEED);
    __SetIn2PWM(MAX_SPEED);
}

/**
 * @brief 电机滑行
 */
void DRV8833_Coast(void)
{
    __SetIn1PWM(0);
    __SetIn2PWM(0);
}

4.使用

使用旋转编码器控制电机转动,旋转编码器顺时针转实现电机正转,并且越转越快。
旋转编码器逆时针转实现电机反转并且越转越快
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PA0,PA1刚好是定时器2的1通道和2通道
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
使用屏幕配置i2c

5.代码

#include "drv8833.h"
#include "oled.h"
#include <stdio.h>
#define MAX_COUNT 20
int main(void)
{




  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  OLED_Init();
  HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);//打开编码器计数
  DRV8833_Init();//打开PWM通道
  int count;
  char message[50]="";
  int speed;//电机的占空比0~100
  __HAL_TIM_SET_COUNTER(&htim1,MAX_COUNT);//先设置为20,让电机不转
  
  while (1)
  {
	  count=__HAL_TIM_GET_COUNTER(&htim1);//获取编码器计数
	  if(count>60000)//逆时针转      //保证编码器计数在0~40
	  {
		  count=0;
		  __HAL_TIM_SET_COUNTER(&htim1,0);


	  }
	  else if(count>MAX_COUNT*2)
	  {
		  count=MAX_COUNT*2;
		 __HAL_TIM_SET_COUNTER(&htim1,MAX_COUNT*2);


	  }
	  if(count<MAX_COUNT)//反转,count越接近0,越快
	  {
		  speed=(MAX_COUNT-count)*100/MAX_COUNT;//speed在0~100,先×100,如果0~20数/20会为0
		  DRV8833_Forward(speed);

	  }
	  else//正转,count越接近40,越快,count为20,speed为0,不转
	  {
		  speed=(count-MAX_COUNT)*100/MAX_COUNT;
		  DRV8833_Backward(speed);
	  }


	   OLED_NewFrame();
	   sprintf(message,"count:%d",count);//显示编码器计数
	   OLED_PrintString(10,0,message,&font16x16, OLED_COLOR_NORMAL);
	   sprintf(message,"speed:%d",speed);//显示速度
	   OLED_PrintString(10,20,message,&font16x16, OLED_COLOR_NORMAL);
	   if(count<20)
		   OLED_PrintString(10,40,"反转",&font16x16, OLED_COLOR_NORMAL);
	   else if(count>20)
		   OLED_PrintString(10,40,"正转",&font16x16, OLED_COLOR_NORMAL);



	   OLED_ShowFrame();
	   HAL_Delay(10);
 
  }

}

 DRV8833_Forward(speed);
 DRV8833_Forward(speed);//操作定时器2的1,2通道通过设置比较寄存器的值来改变占空比,控制转速

相关文章:

  • APlayer - APlayer 初识(APlayer 初识案例、APlayer 常用事件)
  • C++中常用的十大排序方法之4——希尔排序
  • 代码随想录算法训练营第三十九天| 动态规划03
  • 19.Python实战:实现对博客文章的点赞系统
  • 微信小程序中缓存数据全方位解惑
  • Unity 编辑器热更C# FastScriptReload
  • 安卓基础(Adapter)
  • JVM 底层探秘:对象创建的详细流程、内存分配机制解析以及线程安全保障策略
  • React生产环境下使用mock.js
  • VueRouter 实例
  • 单、双 链 表
  • MIMO信号检测ZF算法和MMSE算法
  • 深度求索—DeepSeek API的简单调用(Java)
  • 简单的异步图片上传
  • 游戏引擎学习第104天
  • ABB能源自动化选用宏集Cogent DataHub避免DCOM问题,实现高效、安全的数据传输
  • cuML机器学习GPU库
  • vue3的响应式的理解,与普通对象的区别
  • ROS基本功能
  • 【吾爱出品】视频素材资源搜索、解析、下载助手
  • 罕见沙尘再度入川,官方:沙尘传输高度达到平流层,远超以往
  • A股三大股指低收:银行股再度走强,两市成交11920亿元
  • 习近平出席俄罗斯纪念苏联伟大卫国战争胜利80周年庆典
  • 国家发改委:美芯片药品等领域关税影响全球科技发展,损害人类共同利益
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元
  • 奥园集团将召开债券持有人会议,拟调整“H20奥园2”本息兑付方案