STM32外设系列之TB6612FNG驱动模块详解

本文涉及到定时器和串口的知识,详细内容可见博主STM32速成笔记专栏

文章目录

  • 一、TB6612简介
  • 二、TB6612使用方法
  • 2.1 TB6612引脚连接
  • 2.2 控制逻辑
  • 2.3 电机调速
  • 三、实战项目
  • 3.1 项目简介
  • 3.2 初始化GPIO
  • 3.3 PWM初始化
  • 3.3 电机控制程序
  • 3.4 串口接收处理函数
  • 一、TB6612简介

    TB6612FNG是东芝半导体的一款驱动电机的IC。一个TB6612FNG可以驱动两个电机,每一个驱动都有两个逻辑输入引脚,一个输出引脚和一个PWM引脚。可以通过给两个逻辑输入引脚不同的电平来控制电机的运行状态,通过PWM输入引脚实现电机调速。TB6612FNG还具有以下特点

  • 电源电压最大可到15V
  • 输出电流最大可达3.2A
  • 内置热停机电路和低压检测电路
  • 有正转,反转,短制动和停止四种模式
  • TB6612FNG

    二、TB6612使用方法

    2.1 TB6612引脚连接

    引脚 连接
    PWMA A通道的PWM输入
    AIN2 A通道逻辑输入2引脚
    AIN1 A通道逻辑输入1引脚
    STBY 待机引脚,接低电平处于待机模式,接高电平开始工作
    BIN1 B通道逻辑输入1引脚
    BIN2 B通道逻辑输入2引脚
    PWMB B通道PWM输入引脚
    GND
    VM 电源输入正极,最大接15V
    VCC 逻辑电源正极,接3.3V
    AO1 A通道输出1引脚
    AO2 A通道输出2引脚
    BO2 B通道输出2引脚
    BO1 B通道输出1引脚

    使用时VM接电机电源的正极,GND接电机电源的负极。IN1和IN2接逻辑输入,PWM接PWM输出引脚。O1和O2接电机的正负极。

    2.2 控制逻辑

    IN1和IN2的高低电平状态对应不同的电机运行状态,二者的对应关系如下

    IN1 0 0 1
    IN2 0 1 0
    电机运行状态 停止 正转 反转

    上述的正反转是AO1接电机正极,AO2接电机负极的对应关系。

    2.3 电机调速

    电机调速的远离比较简单,只需要给TB6612FNG的PWM输入引脚输入10KHz的PWM波。调节占空比即可调节转速。需要注意的是如果PWM配置的极性是低电平,那么设置占空比时的值越大,电机转速越低。相反,如果PWM配置的极性是高电平,那么设置占空比时的值越大,电机转速越高。

    三、实战项目

    3.1 项目简介

    本项目比较简单,使用TB6612驱动一个12V减速电机。利用串口发送占空比,实现电机的调速。

    3.2 初始化GPIO

    初始化GPIO完成的工作是初始化逻辑控制引脚,程序如下

    /*
     *==============================================================================
     *函数名称:Drv_MotorGpio_Init
     *函数功能:初始化Motor的GPIO
     *输入参数:无
     *返回值:无
     *备  注:这里只初始化了逻辑控制IO,PWM的IO在定时器配置PWM时初始化
     *==============================================================================
     */
    void Drv_MotorGpio_Init (void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure;   // 定义结构体
    	// 开启时钟
    	RCC_APB2PeriphClockCmd(MOTOR_GPIO_TIM,ENABLE);
    
    	// 配置结构体
    	GPIO_InitStructure.GPIO_Pin = MOTOR_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽式输出
    	GPIO_Init(MOTOR_GPIO, &GPIO_InitStructure);
    }
    

    宏定义如下

    // 电机逻辑控制GPIO
    #define MOTOR_GPIO_TIM   RCC_APB2Periph_GPIOC
    #define MOTOR_GPIO   GPIOC
    #define MOTOR_GPIO_PIN   GPIO_Pin_7 | GPIO_Pin_8
    

    3.3 PWM初始化

    PWM初始化程序如下

    /*
     *==============================================================================
     *函数名称:TIM2_CH1_PWM_Init
     *函数功能:初始化定时器2的PWM通道1
     *输入参数:per:自动重装载值;psc:预分频系数
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void TIM2_CH1_PWM_Init (u16 per,u16 psc)
    {
    	// 结构体定义
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    	TIM_OCInitTypeDef TIM_OCInitStructure;
    	GPIO_InitTypeDef GPIO_InitStructure;
    	
    	// 开启时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	// 初始化GPIO
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    	
    	// 初始化定时器参数
    	TIM_TimeBaseInitStructure.TIM_Period = per;   // 自动装载值
    	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;   // 分频系数
    	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 设置向上计数模式
    	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);	
    	
    	// 初始化PWM参数
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   // 比较输出模式
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;   // 输出极性
    	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   // 输出使能
    	TIM_OC1Init(TIM2,&TIM_OCInitStructure);   // 输出比较通道1初始化
    	
    	TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);   // 使能TIMx在 CCR1 上的预装载寄存器
    	TIM_ARRPreloadConfig(TIM2,ENABLE);   // 使能预装载寄存器
    	
    	TIM_Cmd(TIM2,ENABLE);   // 使能定时器	
    }
    

    初始化时配置如下,配置为10KHz

    	TIM2_CH1_PWM_Init(1000,71);   // 初始化PWM
    

    3.3 电机控制程序

    电机正反转和停止控制程序如下

    /*
     *==============================================================================
     *函数名称:Med_Motor_Go
     *函数功能:电机正转
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Med_Motor_Go (void)
    {
    	MOTOR_IN1 = 1;
    	MOTOR_IN2 = 0;
    }
    /*
     *==============================================================================
     *函数名称:Med_Motor_Stop
     *函数功能:电机停转
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Med_Motor_Stop (void)
    {
    	MOTOR_IN1 = 0;
    	MOTOR_IN2 = 0;
    }
    /*
     *==============================================================================
     *函数名称:Med_Motor_Reverse
     *函数功能:电机反转
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Med_Motor_Reverse (void)
    {
    	MOTOR_IN1 = 0;
    	MOTOR_IN2 = 1;
    }
    
    

    宏定义如下

    // 电机逻辑控制引脚
    #define MOTOR_IN1   PCout(7)
    #define MOTOR_IN2   PCout(8)
    

    3.4 串口接收处理函数

    串口需要根据接收到的占空比来配置输出PWM的占空比,配置占空比使用的库函数是

    void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
    

    串口只支持输入大于100小于1000的占空比,串口接收处理程序如下

    /*
     *==============================================================================
     *函数名称:USART1_IRQHandler
     *函数功能:USART1中断服务函数
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    u32 gReceCount = 0;   // 接收计数变量
    u32 gClearCount = 0;   // 清空接收数组计数变量
    u8 gReceFifo[1500];   // 接收数组
    u8 gReceEndFlag = 0;   // 接收完成标志位 
    
    void USART1_IRQHandler(void)  
    {
    	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   //接收到一个字节  
    	{
    		gReceFifo[gReceCount++] = USART_ReceiveData(USART1);
    	}
    	else if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)   //接收到一帧数据
    	{
    		USART1->SR;   // 先读SR
    		USART1->DR;   // 再读DR
    		
    		gReceEndFlag = 1;   // 接收完成标志置1 
    	} 
    }
    /*
     *==============================================================================
     *函数名称:Uart_Rece_Pares
     *函数功能:解析串口接收内容
     *输入参数:无
     *返回值:无
     *备  注:无
     *==============================================================================
     */
    void Uart_Rece_Pares(void)   // 串口接收内容解析函数
    {
    	u16 pwmDuty = 0;   // 接收串口发送来的占空比
    	
    	if (gReceEndFlag  == 1)   // 如果接收完成
    	{
    		// 解析接收内容
    		
    		// 一位数
    		if (gReceCount == 3)
    		{
    			pwmDuty = (gReceFifo[0] - 48);
    		}
    		else if (gReceCount == 4)
    		{
    			pwmDuty = (gReceFifo[0] - 48) * 10;
    			pwmDuty = pwmDuty + (gReceFifo[1] - 48);
    		}
    		else if (gReceCount == 5)
    		{
    			pwmDuty = (gReceFifo[0] - 48) * 100;
    			pwmDuty = pwmDuty + (gReceFifo[1] - 48) * 10;
    			pwmDuty = pwmDuty + (gReceFifo[2] - 48);
    		}
    		
    		printf ("duty=%d\r\n",pwmDuty);
    		TIM_SetCompare1(TIM2,pwmDuty);
    		
    		// 清空接收数组
    		for (gClearCount = 0;gClearCount < gReceCount;gClearCount ++)
    		{
    			gReceFifo[gClearCount] = ' ';
    		}
    			
    		gReceEndFlag = 0;   // 清除接收完成标志位
    		gReceCount = 0;   // 清零接收计数变量
    	}
    }
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32外设系列之TB6612FNG驱动模块详解

    发表评论