bigfanofloT 发表于 2017-5-11 21:47:07

直流小电机驱动

本帖最后由 bigfanofloT 于 2017-5-16 19:42 编辑

一、直流小电机及其驱动L9110介绍
Gokit板载一个直流小电机,通过L9110来驱动。L9110是为控制和驱动电机设计的两通道推挽式功率放大专用集成电路器件,将分立电路集成在单片IC之中,使**器件成本降低,整机可靠性提高。该芯片有两个TTL/CMOS兼容电平的输入,具有良好的抗干扰性;两个输出端能直接驱动电机的正反向运动,它具有较大的电流驱动能力,每通道能通过800mA的持续电流,峰值电流能力可达1.5A;同时它具有较低的输出饱和压降;内置的钳位二极管能释放感性负载的反向冲击电流,使它在驱动继电器、直流电机、步进电机或开关功率管的使用上安全可靠。L9110被广泛应用于玩具汽车电机驱动、脉冲电磁阀门驱动,步进电机驱动和开关功率管等电路上。


低静态工作电流;宽电源电压范围:2.5V-12V;
每通道具有800mA连续电流输出能力;
较低的饱和压降;
输出具有正转、反转、高阻和刹车四种 状态;
TTL/CMOS 输出电平兼容,可直接连 CPU;
输出内置钳位二极管,适用于感性负 载;
控制和驱动集成于单片IC之中;
具备管脚高压保护功能;
工作温度:-20℃-80℃

二、硬件连线
对于gokit V2.3扩展板,板载L9110的A路输入管脚IA连接到了arduino UNO接口的D5,B路输入管脚IB连接到了arduino UNO接口的D4,通过控制D4和D5输出PWM信号即可实现控制电机转动方向和速度,如图1所示:

图1 Gokit V2.3扩展板L9110原理图
根据Nucleo-F767ZI的原理图,图2可以知道,STM32F767ZIT6的GPIO PE11连接到了Arduino UNO接口的D5,且具备PWM输出功能,为定时器1的通道2,PF14连接到了Arduino UNO接口的D4,不具备PWM功能,因此本次只能驱动电机单向转动。

图2 Nucleo-F767ZI的Arduino UNO接口原理图
三、完整程序
如下Hal_motor.h文件,十分方便移植到其它MCU:

#ifndef _HAL_MOTOR_H
#define _HAL_MOTOR_H

#include <stdio.h>
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_tim.h"


#define Motor_stop      0
#define Motor_Forward   1
#define Motor_Reverse   2


#define MOTOR_ARR 899 //8kHZ
#define MOTOR_MAX 100
#define MOTOR_MAX1 -100
#define MOTOR_MIN 0

#ifdefMOTOR_16
typedef int16_t motor_t;
#else
typedef int8_t motor_t;
#endif

void motorInit(void);
void motorStatus(motor_t status);

#endif /*_HAL_MOTOR_H*/
如下为Hal_motor.c文件:
/**
************
*
* @file      Hal_motor.c
* @author    Gizwtis
* @version   V03010100
* @date      2016-07-05
*
* @brief   机智云.只为智能硬件而生
*            Gizwits Smart Cloudfor Smart Products
*            链接|增值ֵ|开放|中立|安全|自有|自由|生态
*            www.gizwits.com
*
************/
#include <math.h>
#include "Hal_motor.h"


TIM_HandleTypeDef TIM1_Handler;         //¶¨Ê±Æ÷¾ä±ú

void TIM1_PWM_Init(void)
{
          TIM_MasterConfigTypeDef sMasterConfig;
          GPIO_InitTypeDef GPIO_Initure;
    TIM_OC_InitTypeDef TIM1_CH2Handler;   //¶¨Ê±Æ÷3ͨµÀ4¾ä±ú
      
    TIM1_Handler.Instance=TIM1;            //¶¨Ê±Æ÷3
                TIM1_Handler.Channel=HAL_TIM_ACTIVE_CHANNEL_2;      
    TIM1_Handler.Init.Prescaler=9;       //¶¨Ê±Æ÷·ÖƵ
    TIM1_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//ÏòÉϼÆÊýģʽ
    TIM1_Handler.Init.Period=21600;          //×Ô¶¯ÖØ×°ÔØÖµ
    TIM1_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
          TIM1_Handler.Init.RepetitionCounter=0;      
    HAL_TIM_PWM_Init(&TIM1_Handler);       //³õʼ»¯PWM
   
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&TIM1_Handler, &sMasterConfig) != HAL_OK)
{

}
      
    TIM1_CH2Handler.OCMode=TIM_OCMODE_PWM1; //ģʽѡÔñPWM1
    TIM1_CH2Handler.Pulse=21600/2;            //ÉèÖñȽÏÖµ,´ËÖµÓÃÀ´È·¶¨Õ¼¿Õ±È£¬                                          //ĬÈϱȽÏֵΪ×Ô¶¯ÖØ×°ÔØÖµµÄÒ»°ë,¼´Õ¼¿Õ±ÈΪ50%
    TIM1_CH2Handler.OCPolarity=TIM_OCPOLARITY_LOW; //Êä³ö±È½Ï¼«ÐÔΪµÍ
         
          __HAL_RCC_TIM1_CLK_ENABLE();                        //ʹÄܶ¨Ê±Æ÷3
               
    __HAL_RCC_GPIOE_CLK_ENABLE();                        //¿ªÆôGPIOBʱÖÓ
    GPIO_Initure.Pin=GPIO_PIN_11;                   //PB1
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //¸´ÓÃÍÆÍêÊä³ö
    GPIO_Initure.Pull=GPIO_PULLUP;          //ÉÏÀ­
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;   //¸ßËÙ
          GPIO_Initure.Alternate=GPIO_AF1_TIM1;      //PB1¸´ÓÃΪTIM3_CH4
    HAL_GPIO_Init(GPIOE,&GPIO_Initure);
               
          HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH2Handler,TIM_CHANNEL_2);//ÅäÖÃTIM3ͨµÀ4
   
    HAL_TIM_PWM_Stop(&TIM1_Handler, TIM_CHANNEL_2);
}



void motorInit(void)
{
    TIM1_PWM_Init();      
          TIM1->CCR2 = 0;

}


void motorControl(uint8_t m1,uint8_t m2)
{
                        uint16_t temp = (MOTOR_ARR+1) / MOTOR_MAX;
                              
                  TIM1->CCR2 = m1*temp;
}

void motorStatus(motor_t status)
{
    if(0 == status)
    {
                        HAL_TIM_PWM_Stop(&TIM1_Handler, TIM_CHANNEL_2);
      motorControl(0,0);
    }
    else
    {
                        HAL_TIM_PWM_Start(&TIM1_Handler, TIM_CHANNEL_2);
      if(status > 0)
      {
            motorControl((abs(status)+5)*10, 0);
      }
      else
      {
            motorControl(0, (abs(status)+5)*10);
      }
    }
}


本系列帖子目录:
http://club.gizwits.com/thread-6544-1-1.html




小白爱学习 发表于 2017-5-27 17:16:34

谢谢楼主
页: [1]
查看完整版本: 直流小电机驱动