第三篇-V1.5 TB6612电机pwm控制STM32智能小车 江科大笔记 江科大同款STM32F103C8T6单片机 嵌入式实战项目入门教程 STM32电机控制教程嵌入式教程 循迹避障跟随遥控

当前笔记版本1.5
现在有两个版本小车
V1.5.0

STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随

V3.3.0-STM32智能小车
视频
视频链接点击直达
介绍:
V1.5.0:库函数开发。功能:循迹、避障、跟随、遥控、电池电压显示等。
V3:HAL库开发、功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、视觉控制、电磁循迹等。

系统软件设计

点亮小灯

查看原理图

查阅原理图,小灯接在PC13上下面驱动PC13
在这里插入图片描述

编写驱动

在这里插入图片描述

思考题:如果同时驱动PC13与PC14,应该如何编写?(答案:应该增加下图代码)
在这里插入图片描述
LED_Init()函数的代码

void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PB,PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PC13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化
GPIOC.13
GPIO_SetBits(GPIOC,GPIO_Pin_13); //PC.13输出高
}

LED.h 部分宏定义

#define LED PCout(13)// PC13

测试

编译下载(如果没有运行,需要按复位 运行)

电机驱动

由TB6612介绍得,通过控制AO和AO2高低电平可以控制AIN1和AIN2输出。

GPIO 高低电平控制AIN和BIN

  1. 查阅原理图AIN1、AIN2、BIN1、BIN2依次接在单片机的PB13、PB12、PB1、PB0
    在这里插入图片描述
  2. 原理同GPIO输出高低电平见第二节
    TB6612 GPIO驱动函数代码
//驱动6612 的AIN1 AIN2 BIN1 BIN2
// AIN1 PB13
// AIN2 PB12
// BIN1 PB1
// BIN2 PB0
void TB6612_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13
|GPIO_Pin_12|GPIO_Pin_0|GPIO_Pin_1; //PB0 OB1 PB12 PB13端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化
GPIO_SetBits(GPIOB,GPIO_Pin_13 |GPIO_Pin_12|GPIO_Pin_0|GPIO_Pin_1);
//PB0 OB1 PB12 PB1 输出高
}

相关宏定义

#define AIN1 PBout(13)// PB13
#define AIN2 PBout(12)// PB12
#define BIN1 PBout(1)// PB1
#define BIN2 PBout(0)// PB0

PWM控制PWMA和PWMB

将 PWM输出实验 的 timer 文件移植到我们前面点灯的工程中,更改驱动文件

  1. 查看原理图 PWMA 和PWMB依次连接PA11和PA8

  2. 查看 参考手册 关于定时器复用功能重映射的介绍(中文参考手册第119页)
    在这里插入图片描述

  3. 初始化外设
    配置对应引脚功能
    初始化TIM1
    初始化TIM1 相应通道的 PWM模式
    使能
    注意输出使能 高级定时器必须使用:TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx,
    FunctionalState NewState);

//TIM1 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//使能对应定时器
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,
ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE); //Timer3部分重映射
TIM3_CH2->PB5
//配置对应引脚功能
//设置该引脚为复用输出功能,输出TIM1 CH1 和CH4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11; //TIM_CH1 TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//初始化TIM1
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重
装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预
分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据
TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM1 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽
度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使
能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输
出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3
OC2
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装
载寄存器
//初始化TIM1 Channel4 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽
度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使
能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输
出比较极性高
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3
OC2
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装
载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能,高级定时器必须开启这}

调用初始化函数、改变占空比。

TIM1_PWM_Init(1999,359);
//TIM1挂在APB2为72M ,故计算 72 000 000 /(359+1)/(1999+1) = 100 Hz,
//故设置了频率为100 Hz、自动重装载值 1999
TIM_SetCompare1(TIM1,100); //设置 TIM1 通道1 捕获/比较寄存器值 为 1000 可以
计算出占空比
//PA8 PWMB
TIM_SetCompare4(TIM1,1900); //设置
//PA11 PWMA

通过软件仿真

逻辑分析仪观察波形输出、显示PWM波形
设置好仿真环境
在这里插入图片描述
打开逻辑分析仪

在这里插入图片描述
添加要观察的引脚
在这里插入图片描述
跳到设置对应程序位置,打开仿真
在这里插入图片描述
打开实时更新选项
在这里插入图片描述
调节观察分析仪
在这里插入图片描述
产生的如图方波就是一种PWM波
在这里插入图片描述
在这里插入图片描述
那么在程序哪里设置的这些参数那
时钟预分频数 决定了PWM 频率和周期

TIM1_PWM_Init(1999,359);
//TIM1挂在APB2为72M ,故计算 72 000 000 /(359+1)/(1999+1) = 100 Hz,

那么谁调节占空比那?
在这里插入图片描述

  1. 非常好理解、定时器的计数器向上计数就是越来越大。
  2. PWM 模式我们可以看手册
    在这里插入图片描述
    3.这里的TIM_OCPolarity_High 就是把有效电平设置为高
    举个栗子:如果我们设置上面的示例参数,工作过程应该是怎么的呐?
    在这里插入图片描述
    电机控制通过AIN1、AIN2、BIN1、BIN2控制电机正反转,通过PWMA、PWMB控制电机转速
AIN1 = 1;
AIN2 = 0;
BIN1 = 1;
BIN2 = 0;
TIM_SetCompare4(TIM1,1500); //设置 A
TIM_SetCompare1(TIM1,1500); //设置B

让小车跑一跑吧

小车电机线正确接法
在这里插入图片描述
错误接法
在这里插入图片描述
小车直行

void Forward(void)
{
AIN1 = 1;
AIN2 = 0;
BIN1 = 1;
BIN2 = 0;
TIM_SetCompare4(TIM1,1500); //设置 A
TIM_SetCompare1(TIM1,1500); //设置B
}

小车后退

void Backward(void)
{
AIN1 = 0;
AIN2 = 1;
BIN1 = 0;
BIN2 = 1;
TIM_SetCompare4(TIM1,1500); //设置 A
TIM_SetCompare1(TIM1,1500); //设置B
}

小车左转

void Leftward(void)
{
AIN1 = 0;
AIN2 = 1;
BIN1 = 1;
BIN2 = 0;
TIM_SetCompare4(TIM1,1500); //设置 A
TIM_SetCompare1(TIM1,1500); //设置B
}

小车右转

void Rightward(void)
{
AIN1 = 1;
AIN2 = 0;
BIN1 = 0;
BIN2 = 1;
TIM_SetCompare4(TIM1,1500); //设置 A
TIM_SetCompare1(TIM1,1500); //设置B
}

STM32F103C8T6是一个基于ARM Cortex-M3内核的微控制器,广泛应用于各种嵌入式系统中。它具有多种外设,包括定时器、ADC、USART等,非常适合用于控制电机TB6612是半桥驱动器芯片,主要用于驱动直流电机或步进电机。其特点是可以接受PWM信号输入,并通过内部电路产生两个互补的驱动信号,以驱动直流电机正反转。 使用STM32F103C8T6TB6612PWM控制电机MG310P20速度的大致步骤如下: ### 步骤一:硬件连接 1. **电源连接**:将电机的电源接入到STM32TB6612之间。通常,TB6612需要接5V电源,而电机则直接连在这两电源之间。 2. **TB6612连接**:将TB6612的四个引脚分别连接至STM32的GPIO端口。其中,两个IN1和IN2引脚用于接收来自STM32PWM信号;另一对是电源和地线;还有一对是使能和停止控制引脚,可以选配控制电机的启动和停止。 - IN1 和 IN2 需要对应 STM32 的 GPIO 引脚,这些引脚应配置为 PWM 输出模式。 - VCC 和 GND 分别连接到 STM32 的 5V 供电和接地。 ### 步骤二:软件设置 1. **初始化GPIO**:在程序开始部分,初始化GPIO口为PWM输出。这通常涉及到配置寄存器如GPIOx_CRH、GPIOx_CRL、GPIOx_BRR 等。 ```c RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // 根据实际连接调整PIN号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Alternate Function Push Pull GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化其他相关GPIO ``` 2. **配置TIM(定时器)**:选择一个合适的定时器作为PWM生成源,通常会选择支持PWM功能的定时器。配置定时器的频率、预分频值、比较通道以及中断触发等。 ```c TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Period = 1000; // 调整周期时间,以毫秒为单位,例如:1ms=1000 TIM_InitStruct.TIM_Prescaler = 7200; // 根据系统主频计算,这里假设SYSCLK为72MHz TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_InitStruct.TIM_RepetitionCounter = 0; TIM_OC_InitTypeDef TIM_OCInitStruct; TIM_OCInitStruct.TIM_OCMode = TIM_OCM_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OCState_Enable; TIM_OCInitStruct.TIM_Pulse = 500; // 比较值,用于生成一定占空比的PWM信号 TIM_Cmd(TIM_chn, ENABLE); // 启动定时器 TIM_CtrlPWMOutputs(TIM_chn, ENABLE); ``` 3. **设置PWM输出**:根据所需的速度调整TIM的比较值(TIM_Pulse)。这决定了输出脉冲宽度的比例,进而控制电机的转速。 4. **使用中断或循环更新PWM值**:你可以使用中断来动态改变PWM的占空比,从而改变电机速度,也可以在循环中手动更新PWM值。 ```c void updatePWM(int speed) { uint16_t pwmValue = (uint16_t)((float)speed / 100 * 1000); // 将速度百分比转换为PWM脉宽 TIM_OC1PreloadConfig(TIM_chn, TIM_OCPreload_Enable); TIM_OC1Compare chiar(TIM_chn, pwmValue); } ``` ### 相关问题: 1. **如何精确控制电机速度?** 使用PWM的占空比来调节电机转速是一种常见的方法,越高的占空比意味着更多的电流通过电机,导致电机加速转动。 2. **在STM32TB6612之间设置安全操作限制?** 需要考虑电机的最大电流容量,避免超过TB6612电机的额定电流能力,防止过热或损坏设备。 3. **调试过程中遇到的问题排查?** 可能涉及硬件连接错误、软件配置不当、电源电压波动、信号干扰等问题。确保硬件连接正确无误,检查代码是否有逻辑错误,注意环境因素影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值