目录
前言
一、材料清单
二、系统概述
三、硬件设计
1、HC-SR04超声波模块
2、HC-05/06蓝牙模块
3、L298n电机驱动模块
四、代码
1、引脚设置
2、遥控部分
3、超声波报警部分
总结
前言
进行基于STM32 HAL库设计的多功能小车,通过蓝牙连接手机进行小车的前进、后退、左转、右右等基本行动。搭载超声波测距仪,检测到前方有障碍物时,连接蜂鸣器进行报警提示,从而通过蓝牙设备进行路径的调整。
一、材料清单
元器件清单
1、stm32c8t6最小系统板x1
2、L298n电机驱动模块x2
3、直流电机x4
4、HC-06蓝牙模块x1
5、蜂鸣器x1
6、LEDx1
7、小车底板x1
8、杜邦线若干
9、HC-SR04超声波模块x1
10、12V电源x1
11、USB转TTL模块x1
12、12V转5V、3.3V电源模块x1
二、系统概述
小车主要由电机系统、单片机、蓝牙系统、超声波测距系统、蜂鸣器等系统组成。基于STM32将程序下载到电机中,从而实现小车的运动。利用蓝牙系统HC-06,将小车的运动与手机蓝牙连接起来,调节蓝牙系统的步骤:给蓝牙上电、有线串口连接、蓝牙引脚连接、打开串口调试助手,输入指令。系统检测距离的原理是通过单片机发出40 kHz的方波脉冲信号后, 检测接收端是否能够接收到遇障碍物反射的回波。单片机利用收到回波所用的时间得到的声速计算出距离,同时显示出当前距离。测量距离范围为2~450cm。可距离显示,误差小,精度高。蜂鸣器预警和距离采样频率动态变化,距离越远,采样越慢。
三、硬件设计
硬件设计主要包括以下几个模块:超声波收发系统、蓝牙接收系统、L298n电机驱动模块。
1、HC-SR04超声波模块
HC-SR04超声波测距模块可提供 2cm-400cm的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。
基本工作原理:
(1)采用I\O 触发测距,给最少10us 的高电平信号。
(2)模块自动发送8 个40KHZ 的方波,自动检测是否有信号返回。
(3)有信号返回,通过IO 口ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。
2、HC-05/06蓝牙模块
HC-05/06 蓝牙串口通信模块,是基于 Bluetooth Specification V2.0 带 EDR 蓝牙协议的 数传模块。无线工作频段为 2.4GHz ISM,调制方式是 GFSK。模块最大发射功率为 4dBm, 接收灵敏度-85dBm,板载 PCB 天线,可以实现 10 米距离通信。
由于蓝牙有主从机之分,模块出厂默认为从机模式。如果需要设置为主机,需要通过AT指令对蓝牙进行设置模块与供电系统为3.3V的MCU连接时,串口交叉连接即可(模块的 RX接MCU的TX、模块的TX接MCU的RX);模块与供电系统为5V 的MCU连接时,可在模块的RX端串接一个220R~1K电阻再接MCU 的TX,模块的TX直接接MCU的RX,无需串接电阻。
3、L298n电机驱动模块
如图,中间的三个接线端从左到右分别为VCC、GND、+5,其中VCC为12V供电,GND为供电地,+5为5V供电;左右两边的接线端分别为输出A和输出B;排针部分引脚分别为ENA、IN1、IN2、IN3、IN4、ENB,其中IN1~4为逻辑输入,ENA和ENB为PWM使能,已经默认被接到5V,若要使用PWM调速可取下跳帽使用。
四、代码
1、引脚设置
PA0 | 指示灯 | PA1 | 左前轮 | PA2 | 左前轮 | PA3 | 左后轮 | PA4 | 左后轮 | PA5 | 右前轮 | PA6 | 右前轮 | PA7 | 右后轮 | PA8 | 右后轮 | PA9 | 蓝牙RX | PA10 | 蓝牙TX | PB0 | 超声波模块ECHO引脚 | PB1 | 超声波模块TRIG引脚 | PB3 | 蜂鸣器 |
2、遥控部分
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
//遥控指示灯
#define L1_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
#define L1_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
//小车的电机驱动设置
//定义左前侧车轮驱动
#define CLF1_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
#define CLF1_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
#define CLF2_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
#define CLF2_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
//定义左后侧车轮驱动
#define CLB1_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
#define CLB1_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
#define CLB2_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
#define CLB2_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
//定义右后侧车轮驱动
#define CRF1_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
#define CRF1_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
#define CRF2_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
#define CRF2_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET);
//定义右后侧车轮驱动
#define CRB1_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
#define CRB1_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
#define CRB2_ON() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
#define CRB2_OFF() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
//串行通信发送语句
uint8_t Tx_str1[] = "hello world!\r\n";
uint8_t Tx_str2[] = "LEFT!\r\n";
uint8_t Tx_str3[] = "RIGHT!\r\n";
uint8_t Tx_str4[] = "FORWARD!\r\n";
uint8_t Tx_str5[] = "BACKWARD!\r\n";
uint8_t Tx_str6[] = "STOP!\r\n";
uint8_t Rx_dat;
//串行通信返回函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(Rx_dat == '1')//左转
{
CLF1_OFF();
CLF2_OFF();
CLB1_OFF();
CLB2_OFF();
CRF1_OFF();
CRF2_ON();
CRB1_OFF();
CRB2_ON();
L1_ON();//指示灯闪烁
HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),10000);//返回LEFT
L1_OFF();//指示灯关闭
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
else if (Rx_dat == '2')//右转
{
CLF1_OFF();
CLF2_ON();
CLB1_ON();
CLB2_OFF();
CRF1_OFF();
CRF2_OFF();
CRB1_OFF();
CRB2_OFF();
L1_ON();
HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),10000);返回RIGHT
L1_OFF();
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
else if (Rx_dat == '3')//前进
{
CLF1_OFF();
CLF2_ON();
CLB1_ON();
CLB2_OFF();
CRF1_OFF();
CRF2_ON();
CRB1_OFF();
CRB2_ON();
L1_ON();
HAL_UART_Transmit(&huart1,Tx_str4,sizeof(Tx_str4),10000);
//返回FORWARD
L1_OFF();
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
else if (Rx_dat == '4')//后退
{
CLF1_ON();
CLF2_OFF();
CLB1_OFF();
CLB2_ON();
CRF1_ON();
CRF2_OFF();
CRB1_ON();
CRB2_OFF();
L1_ON();
HAL_UART_Transmit(&huart1,Tx_str5,sizeof(Tx_str5),10000);
//返回BACKWARD
L1_OFF();
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
else if(Rx_dat == '5')//停车
{
CLF1_OFF();
CLF2_OFF();
CLB1_OFF();
CLB2_OFF();
CRF1_OFF();
CRF2_OFF();
CRB1_OFF();
CRB2_OFF();
L1_ON();
HAL_UART_Transmit(&huart1,Tx_str6,sizeof(Tx_str6),10000);//返回STOP
L1_OFF();
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
}
}
L1_ON();//指示灯亮
HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),10000);
L1_OFF();//指示灯灭
while (1)
{
HAL_UART_Receive_IT(&huart1,&Rx_dat,1); //串口接受函数
}
}
3、超声波报警部分
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
float S1,S2,DISTANCE;
int BEE = 0;
#define TRIG_ON() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); //TRIG引脚拉高
#define TRIG_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
//TRIG引脚拉低
#define BEE_ON() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET);
#define BEE_OFF() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //蜂鸣器
HAL_TIM_Base_Start_IT(&htim2);//开启时钟
while (1)
{
htim2.Instance->CNT=0;
TRIG_OFF();
TRIG_ON();
HAL_Delay(1);
TRIG_OFF();//在TRIG引脚产生小于10us的高电平
//echo引脚/检测是否有信号返回
while(HAL_GPIO_ReadPin(ECHO_GPIO_Port,ECHO_Pin)==0);
S1 = htim2.Instance->CNT;
while(HAL_GPIO_ReadPin(ECHO_GPIO_Port,ECHO_Pin)==1);
S2 = htim2.Instance->CNT;
DISTANCE=(S2-S1)*0.034/2;//计算距离
printf("DISTANCE = %0.1f cm\r\n",DISTANCE);//串口输出距离
if(DISTANCE <= 20) //判断前方20cm是否有障碍物
{
while(BEE <= 500)//蜂鸣器报警5s
{
BEE_ON();
HAL_Delay(1);
BEE_OFF();
HAL_Delay(1);
BEE++;
}
BEE = 0;
}
HAL_Delay(500);
}
总结
本系统以STM32为核心系统,实现小车多功能的动作,通过蓝牙系统与手机进行连接从而能够对小车的动作进行操纵,超声波测距能够检测障碍物并且通过蜂鸣器进行报警。
工程文件链接链接:
https://pan.baidu.com/s/1dBYIKyR1CpdSnt1MisBvhA?pwd=he0d 提取码:he0d --来自百度网盘超级会员V2的分享
?
|