STM32外设系列—TB6612FNG

news2024/11/28 18:36:35

本文涉及到定时器和串口的知识,详细内容可见博主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引脚连接

引脚连接
PWMAA通道的PWM输入
AIN2A通道逻辑输入2引脚
AIN1A通道逻辑输入1引脚
STBY待机引脚,接低电平处于待机模式,接高电平开始工作
BIN1B通道逻辑输入1引脚
BIN2B通道逻辑输入2引脚
PWMBB通道PWM输入引脚
GND
VM电源输入正极,最大接15V
VCC逻辑电源正极,接3.3V
AO1A通道输出1引脚
AO2A通道输出2引脚
BO2B通道输出2引脚
BO1B通道输出1引脚

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

2.2 控制逻辑

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

IN1001
IN2010
电机运行状态停止正转反转

上述的正反转是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)   // 如果接收完成
	{
		// 解析接收内容
		pwmDuty = (gReceFifo[0] - 48) * 100;
		pwmDuty = pwmDuty + (gReceFifo[1] - 48) * 10;
		pwmDuty = pwmDuty + (gReceFifo[2] - 48);
		
		if (pwmDuty <= 100)
		{
			pwmDuty = 100;
		}
		if (pwmDuty >= 1000)
		{
			pwmDuty = 1000;
		}
		
		printf ("duty=%d\r\n",pwmDuty);
		TIM_SetCompare1(TIM2,pwmDuty);
		
		// 清空接收数组
		for (gClearCount = 0;gClearCount < gReceCount;gClearCount ++)
		{
			gReceFifo[gClearCount] = ' ';
		}
			
		gReceEndFlag = 0;   // 清除接收完成标志位
		gReceCount = 0;   // 清零接收计数变量
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP反序列化漏洞之魔术方法

一、魔术方法 PHP魔术方法&#xff08;Magic Methods&#xff09;是一组特殊的方法&#xff0c;它们在特定的情况下会被自动调用&#xff0c;用于实现对象的特殊行为或提供额外功能。这些方法的名称都以双下划线开头和结尾&#xff0c;例如: __construct()、__toString()等。 …

java项目之网络视频播放器(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的网络视频播放器。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&a…

Arduino RP2040 两个CDC虚拟串口通讯

Arduino RP2040 两个CDC虚拟串口通讯 &#x1f3ac;通讯效果演示&#xff1a; &#x1f33f;基于Earle F. Philhower的固件开发平台&#xff1a; https://github.com/earlephilhower/arduino-pico&#x1f516;USB配置参考&#xff1a;https://arduino-pico.readthedocs.io/en/…

【算法基础:数学知识】4.1 质数

文章目录 质数例题列表866. 试除法判定质数&#xff08;质数的判定&#xff09;867. 分解质因数&#xff08;&#xff09;868. 筛质数埃氏筛欧氏筛 / 线性筛 相关链接 质数 定义&#xff1a;质数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。 …

安装Electron时报错command sh -c node install.js

在安装Electron报如下错误 在指令后面添加 --ignore-scripts&#xff0c;意思是npm 将不会运行在package.json中指定的scripts npm install --save -dev electron --ignore-scripts

Linux系统安装部署MySQL完整教程(图文详解)

前言&#xff1a;最近网上翻阅了大量关于Linux安装部署MySQL的教程&#xff0c;在自己部署的时候总是存在一些小问题&#xff0c;例如&#xff1a;版本冲突&#xff0c;配置失败和启动失败等等&#xff0c;功夫不负有心人&#xff0c;最后还是安装部署成功了&#xff0c;所以本…

《TCP IP网路编程》第九章

第 9 章 套接字的多种可选项 我们进行套接字编程时往往只关注数据通信&#xff0c;而忽略了套接字具有的不同特性。但是&#xff0c;理解这些特性并根据实际需要进行更改也很重要。下面列出了一些套接字可选项。 从表中可以看出&#xff0c;套接字可选项是分层的。 IPPROTO_IP …

[java安全]TemplatesImpl在Shiro550反序列化

文章目录 【java安全】TemplatesImpl在Shiro550反序列化Shiro的原理Shiro反序列化产生演示攻击过程payload使用key加密 构造不含数组的GadGets简单调用链 改造cc6为CommonsCollctionsShiro完整POC触发Shiro550漏洞进阶POC总结 【java安全】TemplatesImpl在Shiro550反序列化 Sh…

论文工具——写论文好用的绘图工具(甘特图+流程图+网络模型图+泳道图)

文章目录 引言正文手动画图的在线画图工具tldraw开源免费ProcessOnDraw.io 网络模型图工具NN-SVG设置参数自动生成Netron上传模型自动生成PlotNeuralNet编码生成 总结 引言 在写HiFi-GAN论文的代码阅读过程中&#xff0c;我发现仅仅通过文字来描述网络结构&#xff0c;不够详细…

ORB-SLAM2学习笔记4之KITTI开源数据集运行ORB-SLAM2生成轨迹并用evo工具评估轨迹

文章目录 0 引言1 KITTI数据集1.1 下载数据1.2 真值轨迹格式转换 2 单目ORB-SLAM22.1 运行ORB-SLAM22.2 evo评估轨迹(tum格式)2.2.1 载入和对比轨迹2.2.2 计算绝对轨迹误差 3 双目ORB-SLAM23.1 运行ORB-SLAM23.2 evo评估轨迹(kitti格式)3.2.1 载入和对比轨迹3.2.2 计算绝对轨迹…

Linux服务器安装部署MongoDB数据库 - 无公网IP远程连接「内网穿透」

文章目录 前言1.配置Mongodb源2.安装MongoDB数据库3.局域网连接测试4.安装cpolar内网穿透5.配置公网访问地址6.公网远程连接7.固定连接公网地址8.使用固定公网地址连接 前言 MongoDB是一个基于分布式文件存储的数据库。由 C 语言编写&#xff0c;旨在为 WEB 应用提供可扩展的高…

升级dubbo3方案

dubbo3 新特性 1. Dubbo3 应用级服务发现设计 显著降低服务发现过程的资源消耗&#xff0c;包括提升注册中心容量上限、降低消费端地址解析资源占用等&#xff0c;使得 Dubbo3 框架能够支持更大规模集群的服务治理&#xff0c;实现无限水平扩容。适配底层基础设施服务发现模型…

【VScode/VS】解决头文件路径问题

vs 中明明包含了头文件所在路径&#xff0c;但是却找不到头文件 首先&#xff0c;将要添加的压缩包解压&#xff0c;放在任意一个盘里&#xff0c;注意&#xff0c;我们在代码里要添加的头文件路径是 #include <tensorflow/c/c_api.h> 接下来我们要添加在VS中的所有路径…

CHI协议保序之trans order保序

一致性系统中&#xff0c;使用三种保序方式&#xff1b; Transaction ordering □ 除了 comp response 来规定 RN 发出的 requeset 的执行顺序之外&#xff0c;还有一种 order 机制来定义RN<->HN,HN<->SN 之间&#xff0c;命令执行的顺序&#xff1a; □ 该机制通…

C语言编程---案例练习

文章目录 格式化输出 格式化输出 %d&#xff0c;输出整数&#xff1b; %f&#xff0c;输出浮点数&#xff1b;%.3f 保留三位小数&#xff1b; %e&#xff0c;输出双精度浮点数&#xff1b; %c&#xff0c;输出单个字符&#xff1b;将字符格式化%d&#xff0c;即转ASCII码&…

解决JMeter+Grafana+influxdb 配置出现transaction无数据情形

问题描述 JMeterGrafanainfluxdb 配置时&#xff0c;Darren洋发现jmeter中明明已经配置好了事务条件以及接口实例信息&#xff0c;但就是在grafana的头部导航栏中的transaction按钮下来没有相应事务数据信息&#xff0c;经过相关资料查询&#xff0c;Darren洋发现执行以下两个步…

EAP系统如何助力光伏制造行业实现数据采集和控制的自动化?

光伏制造行业作为清洁能源领域的重要组成部分&#xff0c;随着市场的扩大和技术的进步&#xff0c;对生产效率、产品质量和成本控制的要求也越来越高。在这个竞争激烈的行业中&#xff0c;企业需要寻求自动化解决方案来提高生产效率和降低人工成本。 图.光伏面板生产&#xff0…

155.最小栈-C++

题目来源&#xff1a;力扣 题目描述&#xff1a; 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部…

数据库redis作业

数据库redis作业 redis9种数据类型的基本操作 redis持久化&#xff1a;分别启用rdb和aof&#xff0c;并查看是否有对应文件生成 作业1&#xff1a;redis9种数据类型的基本操作 1、key操作 key * #查询所有的key keys *exists 参数 #参数&#xff1a;key #判断该key是否存…

网络安全防御篇之安全问题及防火墙简介

网络安全常识及术语 网络的脆弱性 什么样的网络是安全的