一、AT8870是什么?

AT8870是一款刷式直流有刷电机驱动器,VM单电源供电,内置电荷泵。兼容DRV8870/A4950电机芯片,适用于打印机、电器、 工业设备以及其他小型机器。内部关断功能包含过流保护,短路保护,欠压锁定和过温保护。

1、工作原理

两个逻辑输入控制H桥驱动器,该驱动器由四个N-MOS组成,能够以高达3.6A的峰值电流双向控制电机。该芯片利用电流衰减预置最大输出电流, 能够将电流限制在某一已知水平。利用电流衰减模式,可通过对输入进行脉宽调制(PWM) 来控制电机转速。如果将两个输入均置为低电平,则电机驱动器将进入低功耗休眠模式。
在这里插入图片描述

2、引脚说明

在这里插入图片描述

1.GND:GND管脚接到电源地
2.PPAD:芯片裸焊盘接到电源
3.IN2:输入管脚2,控制H桥输出状态,内置下拉电阻
4.IN1:输入管脚1,控制H桥输出状态,内置下拉电阻
5.VREF:H桥参考电压输入,来设定驱动峰值电流
6.VM:芯片电源,要做好电源滤波
7.OUT1:H桥输出1
8.ISEN: H桥检流端,接检流电阻到地,若不需要限流,直接接地
9.OUT1:H桥输出2

3、典型应用电路

在这里插入图片描述

注意事项:
1.PCB 板上应覆设大块的散热片,地线的连接应有很宽的地线覆线。为了优化电路的电特性和热参数性能,芯 片应该直接紧贴在散热片上。
2.对电极电源 VM,应该连接不小于 47uF 的电解电容对地耦合,电容应尽可能的靠近器件摆放。
3.为了避免因高速 dv/dt 变换引起的电容耦合问题,驱动电路输出端电路覆线应远离逻辑控制输入端的覆线。
4.逻辑控制端的引线应采用低阻抗的走线以降低热阻引起的噪声。

4、H 桥控制逻辑

4.1 电平控制

在这里插入图片描述

4.1.1 初始化代码如下(示例):
/*******************************************************************************
 * 函数名:Moto_GPIO_Init
 * 描述  :电机引脚初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void Moto_GPIO_Init(void)
{
		/*定义一个GPIO_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure;

		/*开启Moto相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd(Moto_GPIO_RCC, ENABLE);

		/*设置引脚模式为通用推挽输出*/
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

		/*设置引脚速率为50MHz */   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = AIN1_Pin | AIN2_Pin;	
	
		/*调用库函数,初始化GPIO*/
		GPIO_Init(Moto_GPIO_Port, &GPIO_InitStructure);		
}
4.1.2 电机状态代码如下(示例):
/*******************************************************************************
 * 函数名:Moto_Dormancy
 * 描述  :电机休眠
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Dormancy(void)
{
		Moto_AIN1_LOW();
		Moto_AIN2_LOW();//00			
}

/*******************************************************************************
 * 函数名:Moto_Forword
 * 描述  :电机正转
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Forword(void)
{
		Moto_AIN1_HIGH();
		Moto_AIN2_LOW();//10			
}

/*******************************************************************************
 * 函数名:Moto_Reversal
 * 描述  :电机反转
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Reversal(void)
{
		Moto_AIN1_LOW();
		Moto_AIN2_HIGH();//01			
}

/*******************************************************************************
 * 函数名:Moto_Brake
 * 描述  :电机刹车
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Brake(void)
{
		Moto_AIN1_HIGH();
		Moto_AIN2_HIGH();//11		
}
4.1.3 电机测试代码如下(示例):
/*******************************************************************************
 * 函数名:Moto_Test1
 * 描述  :电机测试1(非调速版本)
 * 输入  :void
 * 输出  :void
 * 调用  :100ms
 * 备注  :先正转再反转(要用PWM才能调速)
*******************************************************************************/
void Moto_Test1(void)
{
    if (moto_dir == 0) // 正转
    {
        moto_count++;
        if (moto_count > 100)
        {
            moto_count = 0;
            moto_dir = 1;
        }
        Moto_Forword();
        printf("Moto_Forword\r\n");							
    }			
    else  // 反转
    {
        moto_count++;
        if (moto_count > 100)
        {
            moto_count = 0;
            moto_dir = 0;
        }
        Moto_Reversal();	
        printf("Moto_Reversal\r\n");						
    }			
}

4.2 PWM控制

在这里插入图片描述

4.2.1 初始化代码如下(示例):
/*******************************************************************************
 * 函数名:User_TIM4_Init
 * 描述  :定时器4初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void User_TIM4_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//开启TIM4的时钟
	RCC_APB2PeriphClockCmd(Moto_GPIO_RCC, ENABLE);//开启GPIOA的时钟
	
    /*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用   
	GPIO_InitStructure.GPIO_Pin = AIN1_Pin | AIN2_Pin;		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 	
	GPIO_Init(Moto_GPIO_Port, &GPIO_InitStructure);	
																	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM4);		//选择TIM4为内部时钟,若不调用此函数,TIM默认也为内部时钟
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义结构体变量
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;				//计数周期,即ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;				//预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
	
	/*输出比较初始化*/ 
	TIM_OCInitTypeDef TIM_OCInitStructure;				//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);                         //结构体初始化,若结构体没有完整赋值
	                                                                //则最好执行此函数,给结构体所有成员都赋一个默认值
	                                                                //避免结构体初值不确定的问题
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //输出比较模式,选择PWM模式1
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       //输出极性,选择为高,若选择极性为低,则输出高低电平取反
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出使能
	TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值
	TIM_OC3Init(TIM4, &TIM_OCInitStructure); //将结构体变量交给TIM_OC1Init,配置TIM4的输出比较通道3

	TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值
	TIM_OC4Init(TIM4, &TIM_OCInitStructure); //将结构体变量交给TIM_OC1Init,配置TIM4的输出比较通道4

	/*TIM使能*/
	TIM_Cmd(TIM4, ENABLE);			//使能TIM4,定时器开始运行	
}

4.2.2 电机状态代码如下(示例):
/*******************************************************************************
 * 函数名:Moto_Fast_PWMForword
 * 描述  :电机正转PWM,快衰减
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Fast_PWMForword(uint8_t speed)
{
		Moto_PWM1_SetCompare(speed);//PWM
		Moto_PWM2_SetCompare(0);//0			
}

/*******************************************************************************
 * 函数名:Moto_Slow_PWMForword
 * 描述  :电机正转PWM,慢衰减
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Slow_PWMForword(uint8_t speed)
{
		Moto_PWM1_SetCompare(100);//1
		Moto_PWM2_SetCompare(speed);//PWM			
}

/*******************************************************************************
 * 函数名:Moto_Fast_PWMReversal
 * 描述  :电机反转PWM,快衰减
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Fast_PWMReversal(uint8_t speed)
{
		Moto_PWM1_SetCompare(0);//0			
	    Moto_PWM2_SetCompare(speed);//PWM		
}

/*******************************************************************************
 * 函数名:Moto_Slow_PWMReversal
 * 描述  :电机反转PWM,慢衰减
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Moto_Slow_PWMReversal(uint8_t speed)
{
		Moto_PWM1_SetCompare(speed);//PWM			
	    Moto_PWM2_SetCompare(100);//1
}

4.2.3 电机测试代码如下(示例):
/*******************************************************************************
 * 函数名:Moto_Test2
 * 描述  :电机测试2(调速版本)
 * 输入  :void
 * 输出  :void
 * 调用  :100ms
 * 备注  :先电机正转PWM,快衰减再电机反转PWM,快衰减
*******************************************************************************/
void Moto_Test2(void)
{
	  if(moto_dir == 0)//电机正转PWM,快衰减
	  {
				moto_count++;
				if(moto_count > 100)
				{
                    moto_count = 0;
					moto_dir = 1; 
					printf("Moto_Fast_PWMReversal\r\n");			       		
				}			
		        Moto_Fast_PWMForword(moto_speed);					
		}	
        else //电机反转PWM,快衰减
		{
				moto_count++;
				if(moto_count > 100)
				{
                    moto_count = 0;
					moto_dir = 0;
                    printf("Moto_Fast_PWMForword\r\n");						
				}			
		    Moto_Fast_PWMReversal(moto_speed);							
		}			
}


二、总结

今天主要讲了AT8870电机驱动的简单应用,在实际应用中需要更精细的控制,就需要用到PID算法来对位置/速度/电流等控制,对电机驱动兴趣的可以下载附件参考,感谢你的观看,谢谢!

在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐