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

1、总体设计方案

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

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

基于HAL库的32智能小车(一)_第1张图片

 2、让小车动起来

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

基于HAL库的32智能小车(一)_第2张图片基于HAL库的32智能小车(一)_第3张图片

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

基于HAL库的32智能小车(一)_第4张图片 基于HAL库的32智能小车(一)_第5张图片

接线方式:

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系列芯片  基于HAL库的32智能小车(一)_第6张图片

(2)配置RCC时钟和SYS:

基于HAL库的32智能小车(一)_第7张图片

基于HAL库的32智能小车(一)_第8张图片

(3)GPIO引脚配置:

基于HAL库的32智能小车(一)_第9张图片

基于HAL库的32智能小车(一)_第10张图片

基于HAL库的32智能小车(一)_第11张图片

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

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

基于HAL库的32智能小车(一)_第12张图片

 基于HAL库的32智能小车(一)_第13张图片基于HAL库的32智能小车(一)_第14张图片

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,嵌入式硬件)