(四)STM32F407 cubemx定时器PWM驱动tb6612

(四)STM32F407 cubemx定时器PWM驱动tb6612

这篇文章主要是个人的学习经验,想分享出来供大家提供思路,如果其中有不足之处请批评指正哈。

废话不多说直接开始主题,本人是基于STM32F407VET6芯片,但是意在你看懂这篇文章后,不管是F1,F4,H7等一系列系统定时器PWM配置都能明白如何通过参考手册去学习配置。而不是Ctrl c,Ctrl v。
本人参考引用了这位大佬的文章推荐大家去看看链接: http://t.csdnimg.cn/aknR8
有必要文字大概讲述一下定时器PWM的工作原理,一定是看过那位大佬的客观讲解(不然不会明白我在说什么的),我会用我精简的话的带大家理解。
为什么PWM一般和定时器绑在一起,首先要明白PWM就是一个单位周期内高电平或者低电平所占的比例。
在这里插入图片描述如图,假设单位周期为10ms,高电平T1所占时间比例为50%,低电平T2所占时间比例为50%,即高电平的时间为10ms50%=5ms,若100%占空比的电压为12V,则此时刻输出的电压为12V50%=6V(是高电平占比)。由此得出可以通过调节占空比0-100%从而调节0-12V的电压。
这就好比水坝,上游通过疯狂开关水闸(现实不可能),一个湍急的河流被你控制了流速,在没有瀑布的情况下流速再快也不能快于河流的流速(明白意思就行,别怼我了)
PWM还有一个关键,单位周期的产生,最好最便捷的方式之一就是定时器固定时间周期。
在这里插入图片描述定时器这几个重要的点需要好好说一说。

1.Prescaler预分频器,在哪见过呢?

在这里插入图片描述
预分频的作用就是将定时器的时钟频率分频,比如F407APB1上的定时器时钟频率为84Mhz。在这里插入图片描述当预分频配置为84时,我的定时器所用的频率就仅仅是84MHZ/84=1MHZ

2.Counter Period (AutoReload Register)
在这里插入图片描述
ARR也就是周期频率,在你分频后1MHZ的基础之上,10^6/100=10KHZ这才是设置的工作频率,单位周期也就是T=1/f。你是在这个单位周期的基础上调节占空比。比如12V想要输出6V,占空比为50%,高电平所占的时间为t=1/10KHZ*50%=0.00005s=0.05ms。整个周期长也可以表示成100(计数次数为100)乘以10的负6次方=10负4次方所以你的占空比CRR不要超过ARR的数值,此情况也就是100。0-100对应的占空比就是0%-100%也就是0-12V.
明白了定时器相关内容之后开始讲解TB6612。

TB6612

在这里插入图片描述本人的TB6612是参考数据手册,和常用的红色款TB6612设计的,放心使用效果是一模一样,长得也一模一样。
数据手册里面写到本产品具有MOS结构,对静电放电敏感。操作本产品时,请使用接地带、导电垫和电离器防止静电放电。确保环境温度和相对湿度保持在合理的水平。所以尽量不要直接收触碰,特别是芯片贴片时本人打电赛时焊坏了3块贴片现在才知道为什么。
芯片驱动电机使用的是mos管得好好讲讲。

场效应管(MOS管)
在这里插入图片描述mos管特性,栅极易被静电击穿。因为栅极输入阻抗高,感应电荷很难释放,产生的高压易把绝缘层击穿,使MOS管永久损坏。失去了绝缘层,形成了栅极和源极电流
在这里插入图片描述可以看出,无论是N沟道还是P沟道,寄生二极管的方向总是跟箭头的方向是一致的。

通常是将衬底(基板)与源极S接在一起。根据导电方式的不同,MOSFET又分增强型、耗尽型。在一般使用中,更多是使用N沟道增强型或者P沟道增强型MOS管,耗尽型的管子比较少使用到。

增强型是指:当V_{GS}=0时管子是呈截止状态,加上正确的VGS后,多数载流子被吸引到栅极,从而“增强”了该区域的载流子,形成导电沟道。

耗尽型是指:当V_{GS}=0时即形成沟道,加上正确的VGS时,能使多数载流子流出沟道,因而“耗尽”了载流子,使管子转向截止。

借鉴大佬图片原文链接:https://blog.csdn.net/weixin_44914259/article/details/124051231

在这里插入图片描述TB6612每个引脚的功能以及任务参考数据手册进行讲解。
在这里插入图片描述首先接线图,STBY,AIN1,AIN2,BIN1,BIN2和STM32数字输出引脚连接,PWMA,PWMB是连接MCU的定时器PWM功能引脚。A01,A02,B01,B02和电机连接,此处画了两根线也是想告诉你此处电流较大,需要较宽的走线。VCC是连接2.7V-3.3V电源,VM1是直接连接4.5V-13.5V的外部电源。

STBY
STBY引脚: 这个引脚用于控制芯片的工作状态。设置为“L” (低电平) 时,TB6612FNG进入待机模式,即芯片不会驱动电机,功耗很低。设置为“H” (高电平) 时,TB6612FNG处于工作模式,可以正常驱动电机。

连接至高电平(VCC): 如果希望TB6612FNG正常工作并驱动电机,可以将STBY引脚连接到电源的高电平(VCC)。在这个状态下,芯片会处于工作模式。

连接至低电平(GND): 如果希望将芯片置于待机模式,可以将STBY引脚连接到地(GND)。这会将芯片设置为待机状态,降低功耗,停止电机驱动。

内部下拉电阻
TB6612FNG内部有一个200 kΩ的下拉电阻。也就是说,如果STBY引脚未连接到任何外部电压源,它会通过这个内部下拉电阻被拉到低电平(GND)。但为了确保芯片的正常操作或待机模式,最好还是根据需要明确连接该引脚。

实际应用建议
正常工作模式: 将STBY引脚直接连接到电源的正极(如VCC),确保TB6612FNG能够正常驱动电机。
待机模式: 将STBY引脚连接到地(GND),确保芯片进入低功耗的待机状态。

AIN1,AIN2,BIN1,BIN2
引脚信号输入口,控制电机正反转的引脚。
当输入信号为1时在这里插入图片描述上侧Pmos管导通,内部电流连接VCC,高电平状态。


当输入信号为0时
在这里插入图片描述
下侧Nmos管导通,内部电流连接GND,低电平状态。
AO1,AO2,BO1,BO2
输出引脚直接与电机连接,控制电机正反转的引脚。
在这里插入图片描述
同侧的MOS管是连接在一起同时连接input信号引脚的(见上图),当AIN1为1,AIN2为0时,VM电压12V,电流走向为红色箭头方向。

在这里插入图片描述
当AIN1为0,AIN2为1时,VM电压,电流走向为红色箭头方向。还有几个停的我就不讲了,就是电压差为0.
以上就是电机正反转的工作原理俗称H桥电路。
在这里插入图片描述工作状态最重要的是上面几种情况你会发现STBY一般情况都是高电平,所以你既可以用一个引脚高电平输出驱动,也可以直接接VCC,本人采用的是第二种情况。

在这里插入图片描述注意一下PWM波的工作频率不要超过100KHZ就行(99.9KHZ,10HZ都行,但是101KHZ不行),本人使用的10KHZ没问题。
讲完理论方面开始CUBEMX配置。
最基础的配置我就不讲了,直接上重点。

定时器配置
在这里插入图片描述

输出引脚配置
在这里插入图片描述


主函数代码示例

#include "tb6612.h"
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&TB6612_TIMX,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&TB6612_TIMX,TIM_CHANNEL_2);
	IN1_1;IN2_0;
	IN3_1;IN4_0;
	__HAL_TIM_SET_COMPARE(&TB6612_TIMX,TIM_CHANNEL_1,100);//右轮
	__HAL_TIM_SET_COMPARE(&TB6612_TIMX,TIM_CHANNEL_2,100);//左轮
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


TB6612.h

#ifndef __TB6612_H__
#define __TB6612_H__

#include "main.h"
#include "tim.h"
#include "gpio.h"

#define IN1_0    HAL_GPIO_WritePin(GPIOA,AIN1_1_Pin,GPIO_PIN_RESET)    //车轮
#define IN1_1    HAL_GPIO_WritePin(GPIOA,AIN1_1_Pin,GPIO_PIN_SET)
#define IN2_0    HAL_GPIO_WritePin(GPIOA,AIN2_1_Pin,GPIO_PIN_RESET)
#define IN2_1    HAL_GPIO_WritePin(GPIOA,AIN2_1_Pin,GPIO_PIN_SET)
#define IN3_0    HAL_GPIO_WritePin(GPIOD,BIN1_1_Pin,GPIO_PIN_RESET)
#define IN3_1    HAL_GPIO_WritePin(GPIOD,BIN1_1_Pin,GPIO_PIN_SET)
#define IN4_0    HAL_GPIO_WritePin(GPIOD,BIN2_1_Pin,GPIO_PIN_RESET)
#define IN4_1    HAL_GPIO_WritePin(GPIOD,BIN2_1_Pin,GPIO_PIN_SET)

#define SPEED_MAX     90
#define SPEED_MINI   0
#define TB6612_TIMX htim2

实现图片
在这里插入图片描述本人电池只有10V了一半刚好5V。

程序即参考资料链接:
链接: https://pan.baidu.com/s/1ByQX3bYszb35eLHMvk4okw?pwd=diic
提取码:diic

<think>好的,我现在需要帮用户解决一个关于STM32F103C8T6智能小车的编程问题。用户的需求是使用Keil和C语言,结合HCSR04超声波模块、TB6612电机驱动路灰度传感器、直流电机和蜂鸣器,实现以下功能:当超声波检测到障碍物30cm时停止并报警,灰度传感器识别到白色停止、黑色行驶,并沿黑线巡线拐弯。还需要主程序和库函数的结构。 首先,我需要理清各个硬件模块的连接和驱动方式。STM32F103C8T6的引脚分配是关键。比如,HCSR04需要Trig和Echo引脚,TB6612的电机控制需要PWM和方向引脚,路灰度传感器需要ADC或数字输入,蜂鸣器需要一个GPIO控制。 接下来,考虑主程序的逻辑。主循环中需要不断读取超声波距离和灰度传感器数据,根据条件判断是否停止或行驶。巡线逻辑通常是通过比较路传感器的值,决定电机的转向,比如左边传感器检测到黑线则左转,右边则右转,中间两个则直行。 然后,库函数部分需要模块化每个硬件的驱动,比如超声波、电机、灰度传感器和蜂鸣器的初始化及控制函数。超声波测距可能需要定时器来计算Echo的高电平时间,转换成距离。电机驱动需要PWM配置,控制速度和方向。灰度传感器可能需要ADC读取模拟值或数字输入判断黑白。 需要注意的难点包括超声波测距的准确性和实时性,以及巡线算法的响应速度。此外,中断和定时器的使用可能会影响系统性能,需要合理配置。代码中需要处理边界情况,比如所有传感器都未检测到黑线时的处理策略,可能停车或原地旋转寻找。 可能的问题:用户是否了解如何配置STM32的时钟和引脚?是否需要提供详细的初始化步骤?PWM频率和占空比如何设置电机速度?灰度传感器的阈值可能需要实际校准,代码中是否需要预设或留出调整接口? 最后,代码结构要清晰,主程序调用各个模块的函数,库函数封装底层操作,方便维护和调试。需要确保语法正确,特别是Keil对C语言的支持,比如标准库的使用、头文件包含等。 总结步骤:1. 硬件引脚分配;2. 各模块驱动函数编写;3. 主程序逻辑整合;4. 巡线算法实现;5. 异常处理与测试。</think>以下是为STM32F103C8T6智能小车设计的代码框架,采用模块化编程思想: ```c /* 硬件引脚定义(根据实际接线修改)*/ #define TRIG_PIN GPIO_Pin_0 #define ECHO_PIN GPIO_Pin_1 #define BUZZER_PIN GPIO_Pin_2 #define MOTOR_PWMA_PIN GPIO_Pin_3 #define MOTOR_PWMB_PIN GPIO_Pin_4 #define GRAY_SENSOR1_PIN GPIO_Pin_5 // 左外侧 #define GRAY_SENSOR2_PIN GPIO_Pin_6 // 左内侧 #define GRAY_SENSOR3_PIN GPIO_Pin_7 // 右内侧 #define GRAY_SENSOR4_PIN GPIO_Pin_8 // 右外侧 /* 库函数头文件 */ #include "stm32f10x.h" #include "motor.h" #include "hcsr04.h" #include "graysensor.h" #include "buzzer.h" /* 全局变量 */ volatile uint32_t ultrasonic_distance = 0; uint8_t gray_status = 0; int main(void) { // 硬件初始化 SystemInit(); HCSR04_Init(TRIG_PIN, ECHO_PIN); Motor_Init(MOTOR_PWMA_PIN, MOTOR_PWMB_PIN); Buzzer_Init(BUZZER_PIN); GraySensor_Init(GRAY_SENSOR1_PIN | GRAY_SENSOR2_PIN | GRAY_SENSOR3_PIN | GRAY_SENSOR4_PIN); while(1) { // 超声波测距 ultrasonic_distance = HCSR04_GetDistance(); // 安全检测(30cm障碍物判断) if(ultrasonic_distance <= 30) { Motor_Stop(); Buzzer_Alert(500); // 500ms间隔报警 continue; // 跳过后续控制 } // 灰度传感器状态采集 gray_status = GraySensor_Read(); // 运动控制决策 if((gray_status & 0x0F) == 0x00) { // 全白检测 Motor_Stop(); } else { LineFollowing_Control(gray_status); } } } /* 库函数实现(部分关键函数)*/ // motor.c void Motor_Init(GPIO_TypeDef* GPIOx, uint16_t PWMA_Pin, uint16_t PWMB_Pin) { // PWM初始化(需要根据实际使用定时器配置) GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // ...具体PWM配置代码... } void LineFollowing_Control(uint8_t sensor_status) { /* 巡线控制逻辑 */ // 典型路传感器巡线逻辑 switch(sensor_status) { case 0x06: // 0011 左转 Motor_TurnLeft(50); // 50%占空比 break; case 0x03: // 0110 右转 Motor_TurnRight(50); break; case 0x02: // 0100 大左转 Motor_TurnLeft(70); break; case 0x01: // 1000 大右转 Motor_TurnRight(70); break; default: // 直行 Motor_Forward(60); } } // hcsr04.c uint32_t HCSR04_GetDistance(void) { // 发送10us触发脉冲 GPIO_SetBits(TRIG_PORT, TRIG_PIN); delay_us(10); GPIO_ResetBits(TRIG_PORT, TRIG_PIN); // 测量回波高电平时间 while(!GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN)); uint32_t start = TIM2->CNT; while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN)); uint32_t duration = TIM2->CNT - start; return (duration * 340) / (2 * 10000); // 单位:厘米 } // graysensor.c uint8_t GraySensor_Read(void) { uint8_t status = 0; status |= (GPIO_ReadInputDataBit(GRAY_PORT, GRAY_SENSOR1_PIN) << 3); status |= (GPIO_ReadInputDataBit(GRAY_PORT, GRAY_SENSOR2_PIN) << 2); status |= (GPIO_ReadInputDataBit(GRAY_PORT, GRAY_SENSOR3_PIN) << 1); status |= GPIO_ReadInputDataBit(GRAY_PORT, GRAY_SENSOR4_PIN); return status; } ``` 代码说明及使用要点: 1. 硬件连接建议: - TB6612PWMA/PWMB接PWM输出,AIN1/AIN2/BIN1/BIN2接GPIO控制方向 - 灰度传感器:建议使用比较器模块,输出数字信号(黑线=1,白底=0) - HCSR04:Trig接普通GPIO,Echo接定时器输入捕获引脚 2. 关键参数调整: ```c #define ULTRASONIC_THRESHOLD 30 // 30cm阈值 #define LINE_FOLLOW_SPEED 60 // 巡线基础速度(占空比%) ``` 3. 功能扩展建议: - 添加软件去抖滤波处理传感器数据 - 使用PID算法优化巡线控制 - 增加蓝牙/WiFi模块进行远程控制 - 添加OLED显示实时状态信息 4. 开发注意事项: - 需在Keil中正确配置时钟树(推荐使用72MHz主频) - 根据实际硬件连接修改引脚定义 - PWM频率建议设置在1k-10kHz之间 - 超声波测量需使用定时器输入捕获功能 - 灰度传感器阈值需根据实际环境校准 建议将代码分为以下模块: 1. main.c - 主控制逻辑 2. motor.[c/h] - 电机驱动 3. hcsr04.[c/h] - 超声波模块驱动 4. graysensor.[c/h] - 灰度传感器处理 5. buzzer.[c/h] - 蜂鸣器控制 实际开发时需要根据具体硬件连接修改引脚定义,并补充完整的GPIO和定时器初始化代码。建议使用STM32CubeMX生成基础工程框架,再添加业务逻辑代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RouDragon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值