STM32F103控制DRV8833驱动一个两相步进电机(输出互补方波)+ 电机不转的原因总结

STM32F103控制DRV8833驱动芯片驱动一个两相步进电机(输出互补方波)

前言

本文主要以两相步进电机为例,为总结使用
电机规格:最大电压5V 最大电流2A 两相步进电机
主控芯片:STM32F103C8T6
驱动芯片:DRV8833双H桥

DRV8833:(后面补充,记得!!!)

使用:

OUT1——A+;OUT2——A-;OUT3——B+;OUT4——B-

INT1——PB6(方向) ;INT2——PA9 (PWM);

INT3——PA8(PWM);INT4——PB7(方向);

SLEEP——PB3(拉高)

VCC——5v

GND——接地

代码:

main.c

//2024/4/2 14点左右 电机带负载转动,震动比较小,可接受,转很久不烫。
/***********
*宏定义部分
*
***********/
/***********
*头文件部分
*
***********/
#include "main.h"
/*****************************
*函数实现
*****************************/
int main(void)
{  
   //delay_init(72000000); //72M

   TIM1_PWM_Init(11999,17);//720khz  org:99 0  1000 17

   Motor_Init();

   TIM_Cmd(TIM1, ENABLE);

   Delay_ms(10);  

   while(1)
  {
    // 控制步进电机
//    /*IN1---1  IN2---PWM  正转 慢速衰减 占空比越小速度越快*/
//    /*IN1---PWM  IN2---0 正转  快速衰减 占空比越大速度越快*/
		GPIO_SetBits(GPIOA, GPIO_Pin_8);
		TIM_SetCompare1(TIM1, 6000);
		
		Delay_ms(300);
			   
		GPIO_ResetBits(GPIOB, GPIO_Pin_13);
		TIM_SetCompare1(TIM1, 6000);
  }	
}

pwm.c

#include "pwm.h"
#include "main.h"
/********************************************
* @brief      TIM1 PWM初始化
* @param      arr
*             psc
* @retval     void
*********************************************/
void TIM1_PWM_Init(u32 arr, u16 psc)
{
  GPIO_InitTypeDef GPIO_InitStructure; //定义引脚初始化结构体
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; //定义定时中断结构体	
  TIM_OCInitTypeDef TIM_OCInitTypeStrue; //定义PWM输出结构体
  TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE); //使能GPIOA时钟  /*开启端口时钟*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//启动AFIO
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); //使能通用定时器2时钟  /*开启定时器时钟*/
  //PA8 PB13:PWM
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//定时器引脚PA8 CH1   PB13 CH1N
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出模式,A0引脚复用
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //引脚输出速度为
  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化引脚GPIO

  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;//定时器引脚PA8 CH1   PB13 CH1N
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出模式,A0引脚复用
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //引脚输出速度为
  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化引脚GPIO 
  /* Time Base configuration */
  TIM_TimeBaseInitStrue.TIM_Period=arr; //计数周期
  TIM_TimeBaseInitStrue.TIM_Prescaler=psc -1; //预分频系数
  TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
  TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //一般不使用,默认TIM_CKD_DIV1 //org :TIM_CKD_DIV1
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStrue); //初始化定时器TIM1
	
  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  //初始化TIM1 比较模式,输出比较翻转触发模式(当计数值与比较/捕获寄存器值相同时,翻转输出引脚的电平)
  TIM_OCInitTypeStrue.TIM_OCMode=TIM_OCMode_Toggle ; //TIM_OCMode_PWM1 PWM模式1,定时器计数小于 TIM_Pulse时,输出有效电平  TIM_OCMode_Toggle
  TIM_OCInitTypeStrue.TIM_OCPolarity=TIM_OCPolarity_High; //输出有效电平为高电平
  TIM_OCInitTypeStrue.TIM_OCNPolarity=TIM_OCNPolarity_High;
  TIM_OCInitTypeStrue.TIM_OutputState=TIM_OutputState_Enable; //使能PWM输出
  TIM_OCInitTypeStrue.TIM_OutputNState=TIM_OutputNState_Enable;
  TIM_OCInitTypeStrue.TIM_OCIdleState = TIM_OCIdleState_Reset;	//OIS1位
  TIM_OCInitTypeStrue.TIM_OCNIdleState = TIM_OCNIdleState_Set; //CR2的OIS1N位,当MOE位0时,输出空闲状态位OIS1N  //TIM_OCNIdleState_Reset
  TIM_OCInitTypeStrue.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  TIM_OC1Init(TIM1, &TIM_OCInitTypeStrue); //初始化定时器1通道1
  
    //刹车和死区设置
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; 	//OSSR:运行模式下“关闭状态”选择
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; 	//OSSI:空闲模式下“关闭状态”选择
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; 			//锁定设 置,级别为1
  TIM_BDTRInitStructure.TIM_DeadTime = 0x0AC;					//死区延时时间
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;			//禁止刹车输入   //Disable  4/1update
  TIM_BDTRInitStructure.TIM_BreakPolarity =TIM_BreakPolarity_High;// 刹车输入极性    //TIM_BreakPolarity_Low
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能
  TIM_BDTRConfig( TIM1, &TIM_BDTRInitStructure );

  TIM_CtrlPWMOutputs( TIM1, ENABLE );
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH2预装载使能 //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置)
  TIM_ARRPreloadConfig(TIM1, ENABLE); //预装载使能 //启用ARR的影子寄存器(直到产生更新事件才更改设置)

	// 主输出使能,当使用的是通用定时器时,这句不需要
  TIM_CtrlPWMOutputs(TIM1, ENABLE);

}

重点:设置为输出比较模式

Motor.c

#include "Motor.h"
#include "main.h"

/********************************************
* @brief      电机GPIO初始化
* @param      void
* @retval     void
*********************************************/
void Motor_Init(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 |GPIO_Pin_3;//PB6 PB7作为方向控制  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_3);//sleep  
  GPIO_ResetBits(GPIOB, GPIO_Pin_6|GPIO_Pin_7);//PB6不接时电平为0
}

电机不转的原因:

总结自己在驱动这款电机的经验

  1. 首先明确电机的最大电压承受范围,开始研发阶段,因为占空比设置不对,经常烧电机,导致不断检查代码找不到错误,结果电机就已经坏了。解决:测试时用电机的中等电压,检查代码同时检查电机是否烧坏(驱动模块电路好的情况下),两相步进电机检查相序有很多帖子。
  2. 在使用一款新的驱动芯片时,先用最简单的方波驱动,以验证驱动芯片和电机是否适配。
  3. 看电机规格书,明确电机的最大承受电压,电流,PPS范围,步距角。
  4. 查看驱动芯片的规格书,看驱动电压范围,我用的DRV8833的最大驱动电压是5V;看有无睡眠脚需要使能等等;(其实我认为新手使用一款新驱动芯片时,可以先在网上大面积看帖子,或许前人已经总结了很多,我们要站在巨人的肩膀上,哈哈哈。如果所用驱动芯片资料很少,查看和它性能接近的芯片,看有没有帖子,最后再研究芯片手册,事半功倍。)
  5. 用万用表测驱动芯片的电压引脚,确保其正常工作。
  6. 用万用表测驱动芯片的电机输入和输出引脚,是否有电压。一般MCU没问题的话,输入电压都会有;如果没有输出电压,多半是驱动模块的供电有问题,看看是否需要外接电源。
  7. 用万用表测电机的输出引脚,如果驱动芯片有输出电压,而电机端没有电压输出,这种情况下,看看电机或者电机线是否烧坏,电机的相序是否正确。
  8. 驱动芯片输出电压正常,电机电压正常。用示波器或者逻辑分析仪看波形,我的最终需求是用正余弦原理驱动,在逻辑分析仪上,看不见正弦波,只能看见占空比的变化,但也足够。看什么,看PWM频率 。 PWM频率公式 Fpwm = 72M / ((arr+1)*(psc+1))(单位:Hz) arr 是计数值 psc 是预分频值。这两个值一确定,PWM频率就不会改变了。之前我PWM频率调的太高了,电机pps最高达2Khz,我调的50Khz(因为没有这款电机的规格书),所以即使我电流调的很小,0点几安培吧,电机也没有烧,有电流声通过电机,但是不会转,因为pps不在电机的可承受范围。所以,降低频率试试。

以上是过来人经验,希望能帮到你!

互补方波效果演示:

电机转动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值