STM32外设系列—TB6612FNG
🎀 文章作者:二土电子
🌸 关注文末公众号获取其他资料和工程文件!
🐸 期待大家一起学习交流!
本文涉及到定时器和串口的知识,详细内容可见博主STM32速成笔记专栏。
文章目录
- 一、TB6612简介
- 二、TB6612使用方法
- 2.1 TB6612引脚连接
- 2.2 控制逻辑
- 2.3 电机调速
- 三、实战项目
- 3.1 项目简介
- 3.2 初始化GPIO
- 3.3 PWM初始化
- 3.4 电机控制程序
- 3.5 串口接收处理函数
一、TB6612简介
TB6612FNG是东芝半导体的一款驱动电机的IC。一个TB6612FNG可以驱动两个电机,每一个驱动都有两个逻辑输入引脚,一个输出引脚和一个PWM引脚。可以通过给两个逻辑输入引脚不同的电平来控制电机的运行状态,通过PWM输入引脚实现电机调速。TB6612FNG还具有以下特点
- 电源电压最大可到15V
- 输出电流最大可达3.2A
- 内置热停机电路和低压检测电路
- 有正转,反转,短制动和停止四种模式
二、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.4 电机控制程序
电机正反转和停止控制程序如下
/* *============================================================================== *函数名称: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.5 串口接收处理函数
串口需要根据接收到的占空比来配置输出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
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。