基于HAL库的32智能小车(一)

本文介绍了一款基于STM32F401芯片的智能小车设计方案,包括硬件选型、电路连接及软件编程等内容。小车具备自动避障、循迹等功能。

1、总体设计方案

        智能小车该项目分为三大组成部分:MCU控制部分、传感器检测部分、执行部分。小车要实现自动避障、循迹、无线蓝牙控制等(拓展)功能。

        小车MCU主控部分使用STM32F401芯片的最小系统板,搭配SG90舵机、HC-SR04超声波模块、TCRT5000红外反射传感器模块、HC-05蓝牙模块、TB6612FNG电机驱动模块、降压模块、OLED显示屏、测速光电耦传感器模块、以及电源部分,最终配合软件编程实现感知黑色导引线和障碍物可以实现自动识别路线循迹、检测到障碍物自动躲避以及无线蓝牙的控制。

 2、让小车动起来

我们采用DC3V-6V直流减速电机,供电为3V-6V。TB6612FNG电机驱动模块(淘宝三四十块一个),拥有16个引脚,电机驱动电路主要是通过改变电机的正反转实现小车的前后左右的方向选择。

因为TB6612驱动模块的VM口只能接10V以内的电源,所以我们因此接入LM2596S DC-DC可调降压模块进行稳压(淘宝三四块一个),防止芯片烧坏。

 

接线方式:

IN+ 输入正极 IN-输入负极

OUT+输出正极 OUT-输出负极

模块使用方法:

1.接入电源(3-40V),电源指示灯亮,模块正常工作。

2.调整蓝色电位器旋钮(一般顺时针旋转升压,逆时针旋转降压)并用万用表监测输出电压达到需要电压为止。需要注意:长时间工作建议在2.5A以内的电流使用,同时加上散热片(10W以上输出);由于是降压模块,为了保证输出稳定,请保持最小1.5V压差。

2.1首先我们进行CubeMX的设置

以下是我对TB6612模块的引脚设置以及真值表。

TB6612引脚分配:
     VM          PWMA--------->TIM1_CH1(PA8)
     VCC         AIN2--------->GPIOA_1
     GND         AIN1--------->GPIOA_0
     AO1         STBY--------->GPIOB_9
     AO2         BIN1--------->GPIOA_2
     BO2         BIN2--------->GPIOA_3
     BO1         PWMB--------->TIM1_CH4(PA11)
     GND         GND


真值表
     AIN1   L     H     L     H
     AIN2   L     L     H     H
     BIN1   L     H     L     H
     BIN2   L     L     H     H
           停止  正转  反转  刹车

(1)打开CubeMX先选择STM32F401CCU6系列芯片  

(2)配置RCC时钟和SYS:

(3)GPIO引脚配置:

(4)设置时钟定时器,这里我们使用高级定时器TIM1

并对它的预分频器计数器时钟周期频率以及脉冲值等进行配置,并生成工程文件

 

2.2驱动程序代码设计

motor.c

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


void PWM_INIT(void)
{
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);  //开启电机A的PWM输出定时器;打开定时器1,通道1
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);  //开启电机B的PWM输出定时器;打开定时器1,通道4
}


void car_go_straight(void)//前进
{
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,1000); //设置占空比 计数周期(8400)内,一共发送1000次
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,1000);
	
	AIN1_H;
    AIN2_L;//电机A正转
	
	BIN1_H;
	BIN2_L;//电机B正转

}

void car_go_right(void)//右转
{
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,1000); //设置占空比 计数周期(8400)内,一共发送1000次
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,1000);
	
	AIN1_H;
    AIN2_L;//电机A正转
	
	BIN1_L;
	BIN2_H;//电机B反转
	
}

void car_go_left(void)//左转
{
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,1000); //设置占空比 计数周期(8400)内,一共发送1000次
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,1000);
	
	AIN1_L;
    AIN2_H;//电机A反转
	
	BIN1_H;
	BIN2_L;//电机B正转
	
}

void car_go_ahead(void)//停止
{
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,0); //设置占空比 计数周期(8400)内,一共发送0次
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,0);
	
	AIN1_L;
    AIN2_L;//电机A停止
	
	BIN1_L;
	BIN2_L;//电机B停止

}

void car_go_after(void)//后退
{
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,1000); //设置占空比 计数周期(8400)内,一共发送1000次
	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,1000);
	
	AIN1_L;
    AIN2_H;//电机A反转
	
	BIN1_L;
	BIN2_H;//电机B反转

}

motor.h

#ifndef __MOTOR_H_
#define __MOTOR_H_

#include "main.h"


//左轮
#define AIN1_H HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET);
#define AIN1_L HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);
#define AIN2_H HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);
#define AIN2_L HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_RESET);
//右轮
#define BIN1_H HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_SET);
#define BIN1_L HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET);
#define BIN2_H HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,GPIO_PIN_SET);
#define BIN2_L HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,GPIO_PIN_RESET);

void PWM_INIT(void);

void car_go_straight(void);//前进
void car_go_right(void);//右转
void car_go_left(void);//左转
void car_go_ahead(void);//停止
void car_go_after(void);//后退

#endif

### STM32控制八路灰度循迹小车及TB6612电机驱动的实现方案 #### 、硬件连接与初始化 在使用STM32控制八路灰度循迹小车时,需完成以下硬件配置: - **灰度传感器阵列**:通常由八个红外发射接收管组成,用于检测地面黑白对比。这些传感器通过模拟输入接口连接至STM32的ADC通道[^1]。 - **TB6612FNG电机驱动芯片**:该芯片支持两路直流电机独立控制,每路有PWM信号输入(IN1/IN2)、使能端(STBY)和方向控制(PWMA/PWMB)[^2]。 对于STM32微控制器而言,其GPIO口可以用来设置TB6612的方向控制位,而定时器产生的PWM波形则负责调节电机转速。 ```c // 初始化 GPIO 和 TIM 配置代码片段 (假设使用 HAL ) void MX_GPIO_Init(void){ __HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 PA 口时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 配置 IN1, IN2 */ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); } void MX_TIM_Init(void){ __TIM2_CLK_ENABLE(); TIM_HandleTypeDef htim2; htim2.Instance = TIM2; htim2.Init.Prescaler = SystemCoreClock / 1000000 - 1 ; // 设置预分频值为 1MHz 的计数频率 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; // PWM 周期设为 1ms 即占空比范围 [0%,100%] if(HAL_TIM_PWM_Init(&htim2)!= HAL_OK){Error_Handler();} } ``` #### 二、软件算法设计 ##### (1)灰度数据采集与处理 利用STM32内置AD转换功能获取各灰度传感器数值,并依据阈值判断当前路径状况: ```c uint16_t ReadGraySensor(uint8_t channel){ ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = channel ; sConfig.Rank = 1 ; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) Error_Handler(); HAL_ADC_Start(&hadc1); while(!__HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC)); uint16_t result=HAL_ADC_GetValue(&hadc1); return result; } ``` 随后定义个数组存储所有传感器读数并分析是否有偏离中心的趋势[^1]: ```c #define NUM_SENSORS 8 int sensor_values[NUM_SENSORS]; for(int i=0;i<NUM_SENSORS;i++)sensor_values[i]=ReadGraySensor(i+1); if(sensor_values[0]<threshold || sensor_values[1]<threshold ){ temp_out=-Kp*error;// 左偏修正向右转向 }else if(sensor_values[7]<threshold||sensor_values[6]<threshold){ temp_out= Kp*error;// 右偏修正向左转向 } else { temp_out=0; // 正常直行 } ``` 此处`temp_out`代表调整后的偏差补偿量,`Kp`作为比例增益系数可根据实际情况设定大小[^2]。 ##### (2)PID闭环控制策略应用 为了提高系统的稳定性和响应速度,在基础的比例控制基础上引入积分项I和微分项D形成完整的PID控制器结构: \[ u(t)=k_p e(t)+ k_i \int_{0}^{t}{e(\tau)d\tau } +k_d de/dt \] 其中\(u(t)\)表示最终输出给定值;\(e(t)\)为目标轨迹误差信号;\(k_p,k_i,k_d\)分别对应于比例、积分、微分环节权重参数的选择取决于具体实验环境下的反复测试结果[^2]. 最后将计算所得PWM占空比分配到左右两侧马达上达成预期运动效果. ---
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值