​ 《STM32智能小车课程设计》

教学内容主要围绕如下几个方面展开:掌握项目开发的完整流程;掌握高效的项目概要框架设计方法,会进行科学的技术模块设计;掌握缜密的项目详细技术设计思想,根据数据流设计完善的程序接口;掌握项目开发的核心调试方法,能快速定位缺陷并及时修复;掌握前沿的嵌入式开发技术,将学过的知识灵活实践在项目开发用中;掌握KEIL4的使用,能对市场上大部分的单片机进行编程调试开发;灵活运用GPIO、中断、总线、网络通信等技术为智能小车系统提供稳定高效的功能;掌握传感器的外设使用,学会看时序图,帮助文档等参考资料;掌握主流无线通信技术,实现远程智能小车控制。

STM32智能小车开发环境搭建

1.1 STM32CubeIDE 介绍

STM32CubeIDE集成了STM32CubeMX的STM32配置与项目创建功能,以便提供一体化工具体验,并节省安装与开发时间。用户可以通过所选板卡或示例选择一个空的STM32 MCU或MPU,或者预配置微控制器或微处理器之后,将创建项目并生成初始化代码。在开发过程的任何时间,用户均可返回外设或中间件的初始化和配置阶段,并重新生成初始化代码,期间不会影响用户代码

STM32CubeIDE包含相关构建和堆栈分析仪,能够为用户提供有关项目状态和内存要求的有用信息。它还具有标准和高级调试功能,其中包括CPU内核寄存器、存储器和外设寄存器以及实时变量查看、串行线传输监测器接口或故障分析器的视图。所有功能都可通过STM32CubeMX来集成服务:STM32微控制器、微处理器、开发平台和示例项目选择引脚排列、时钟、外设和中间件配置项目创建和初始化代码生成。

STM32CubeIDE支持集成数以百计的现有插件,正是这些插件使Eclipse/CDT的功能趋于完整。它还包括STM32MP1系列支持OpenSTLinux项目、Linux支持、其他高级调试功能包括CPU内核、外设寄存器和内存视图实时变量查看视图系统分析与实时跟踪(SWV)CPU故障分析工具支持RTOS感知调试,包括Azure和ST-LINK(意法半导体)和J-Link (SEGGER)调试探头。

总之,STM32CubeIDE是一款功能强大的开发工具,可以帮助开发人员快速有效地开发STM32系列微控制器应用程序。

1.2 STM32CubeIDE下载及安装

STM32CubeIDE下载

官网https://www.st.com/zh/development-tools/stm32cubeide.html#documentation下载STM32CubeIDE

STM32CubeIDE安装:

1.选择自己系统对应的软件安装包,解压完成之后进行安装,注意选择的安装路径不能带有中文名称,否则有可能导致安装失败

image-20230604151831815

图 1.2.1选择安装路径

2.点击下一步,此时会出现是否选择安装烧写器驱动,第一个选项为 J-LINK,第二个为 ST-LINK,用户可以根据自己的烧写器进行选择,建议全部勾选上,单击install完成安装

image-20230604173254631

图1.2.2 勾选烧写驱动

image-20230604173433562

图1.2.3完成安装

1.3创建STM32工程:

1.创建工作空间

2.点击File->New->STM32 Project程序会自动打开内置的目标选择器

image-20230604173505816

图1.3.1新建工程

3.在 Part Number 中输入 STM32F103C,芯片列表会自动筛选出符合条件的芯片,选择 STM32F103C8

4.点击 Next,将工程名字命名为 test_STM32F103C8,目标语言为 C 语言

5.然后点击 Next,进入包选择页面,一般选择最新的包即可,然后代产生选项选择只拷贝必要的库,点击Finish

6.在.ioc文件界面,点击 System Core 中的 SYS 选项,Debug 中选择 Serial Wire 选项,点击“generate code”选项,就会生成基础配置的代码,完成工程创建

1.4使用JFlash烧写.hex文件入小车芯片:

1.将主机与STM32F103C8智能小车相连

2.打开JFlash选择Options ->project settings…

image-20230604173524857

图1.4.1JFlash工程设置

target interface选择SWD并选择Auto seletions

image-20230604173541112

图1.4.2 选择SWD接口

CPC选择STM32F103C8

image-20230604173553167

图1.4.3 选择CPU

3.打开文件选择烧写的.hex文件

image-20230604173602355

图1.4.4 选择.hex文件

4.在Target选项卡中先点击connect连接USB,再点击Auto将文件烧写入芯片

STM32智能小车硬件及原理图分析

STM32智能小车硬件分析

基于STM32F103C8芯片的智能小车硬件设计主要包括以下几个部分:

1.电源模块:STM32F103C8芯片内置了一个内部电源模块,可以为芯片内部的各个部件提供稳定的电压和电流。同时,该芯片还具有外部电源接口,可以通过外部电源为小车提供电能。

image-20230604173613891

图2.1.1 电源模块

2.传感器模块:小车上安装了多个传感器,用于感知周围环境,如速度传感器、角速度传感器、加速度传感器等。这些传感器可以通过STM32F103C8芯片内置的ADC接口进行采样,并将采样数据传输到芯片内部进行处理。

image-20230604173624163

图2.1.2 传感模块

3.控制模块:STM32F103C8芯片内置了多个外设,如PWM、定时器、ADC等,可以实现对小车的控制。同时,该芯片还具有USB接口和串口,可以通过外部设备对小车进行控制。

4.通信模块:STM32F103C8芯片内置了蓝牙、WiFi、Zigbee等通信模块,可以实现小车与外部设备的通信。同时,该芯片还具有UART接口,可以通过串口与外部设备进行通信。

image-20230604173632049

图2.1.3 通信模块

5.硬件电路设计:小车的硬件电路设计主要包括电源线、数据线、控制线等,需要根据实际需求进行设计。

综上所述,基于STM32F103C8芯片的智能小车硬件设计相对比较简单,主要包括电源模块、传感器模块、控制模块和通信模块等部分。通过这些模块的协同工作,可以实现小车的智能控制和感知功能。

2.2STM32芯片原理图

image-20230604173645233

图2.2.1 STM32F103C8T6核心板原理图

image-20230604173658526

图2.2.2 母板模块及接口标注:

STM32智能小车手机蓝牙无线操控

3.1实验器材

硬件:

stm32模块、蓝牙模块、智能小车

软件:

手机APP或小程序:蓝牙串口工具

3.2 实验目的及原理

实验目的

使用STM32模组实现手机APP通过蓝牙控制小车前后左右停止功能。

实验原理

基于蓝牙通信,STM32PWM输出控制电机

电机供电由MVEN脚控制,MVEN脚为STM32的PB5引脚,使用电机时需将PB5引脚置高电平。电机信号脚M1+、M1-、M2+、M2-分别接在STM32的PB8、PB9、PB7、PB6引脚,这些脚分别为STM32定时器4的1、2、3、4通道。

原理图(部分)

image-20230604173710441

图3.2.1 电机供电

image-20230604173719653

图3.2.2 双路电机驱动

image-20230604173803566

图3.2.3 核心板座子

3.3关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Deal_Data_BLE()//**蓝牙接收处理函数**
{
BLE_send(BLE_receivce_buff,BLE_receive_size);
switch(BLE_receivce_buff[0])//通过蓝牙接收数据对小车进行控制
{
case ‘A’:
Motor_Control_Up(80);//电机控制
break;
case ‘B’:
Motor_Control_Down(80);
break;
case ‘C’:
Motor_Control_Left(80);
break;
case ‘D’:
Motor_Control_Right(80);
break;
case ‘F’:
Motor_Control_Stop(80);
break;
}
}

3.4烧写并观察实验结果

在编写完所有代码后,编译工程,编译无误后将程序下载进开发板,然后观察实验现象

打开手机APP,连接蓝牙,然后在APP上可通过蓝牙控制小车状态

STM32智能小车超声波定距避障

4.1实验器材

硬件:stm32 模块、蓝牙模块、智能小车

软件:手机 APP 或小程序:蓝牙串口工具

4.2实验任务

使用 STM32 模组实现小车定距功能。

4.3实验背景、资料

1.模拟电路、数字电路相关知识回顾;

2.STM32F103_数据手册(中文);

3.C 语言程序设计;

4.STM32HAL 库函数手册;

4.4实验原理图

image-20230604173819251

图4.4 超声波接口及核心板

4.5****实验步骤

1.关键代码

在 main 函数中进行超声波判断,设定距离为 10cm,大于则前进,小于则后退,等于则

停止。

image-20230604173831201

图4.5.1 关键代码

2.STM32CubeIDE 代码编写

在图形化配置界面中配置超声波引脚,将PB11即TRIG引脚设置为输出模式将PB12即ECHO引脚设置为外部中断边沿触发模式并开启中断,如下图所示

image-20230604173839550

图4.5.2 引脚设置

配置好工程后打开 main.c,在 main 函数中编写图4.5.1代码.

3.执行文件烧写

在编写完所有代码后,编译工程,编译无误后将程序下载进开发板,然后观察实验现象。

4.实验结果

程序运行后小车与前方障碍物始终保持 10cm 左右距离。

STM32智能小车红外寻迹

5.1实验器材

硬件:stm32 模块、蓝牙模块、智能小车

软件:手机 APP 或小程序:蓝牙串口工具

5.2实验任务

使用 STM32 模组实现黑线循迹功能。

5.3实验背景、资料

1.模拟电路、数字电路相关知识回顾;

2.STM32F103_数据手册(中文);

3.C 语言程序设计;

4.STM32HAL 库函数手册;

5.4实验步骤

1.原理图

image-20230604173901439

图5.2.1 寻迹原理图

2.在tracing.c和tracing.h中编写红外检测功能函数。

image-20230604173912976

图5.2.2 关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 //在 main.c 中定义红外循迹时小车的速度:

#define HIGH_SPEED 100//默认的高速(实际上的全速运行)
#define DEFAULT_SPEED 80//默认速度为 196
#define TRACING_UP_DEFAULT 75//默认的寻迹模式下直走速度
#define MAX_TURN_SPEED 70
#define MIN_TURN_SPEED 65
/* USER CODE END PD */


//在 main 函数中编写循迹算法:

/* Infinite loop */
/* USER CODE BEGIN WHILE */
BLE_Init();
Steering_Init();
Motor_Control_Init();

BLE_send((uint8_t *)"start",5);
uint8_t tracing_info_now;
//当前寻迹的四个红外状态,使用低四位
while (1)
{
tracing_info_now = Get_State_Infrared(); //读取寻迹的四个红外的状态
switch(tracing_info_now)
//根据当前的状态选择控制
{
case 6: //中间两条检测到
Motor_Control_Up(TRACING_UP_DEFAULT);
//直走
break;
case 1: //加快右转
Motor_Control_Right(MIN_TURN_SPEED);
break;
case 2: //右转
Motor_Control_All(TRACING_UP_DEFAULT,0,MAX_TURN_SPEED,0);
break;
case 8: //加快左转
Motor_Control_Left(MIN_TURN_SPEED);
break;
case 4: //右转
Motor_Control_All(MAX_TURN_SPEED,0,TRACING_UP_DEFAULT,0);
break;
default:
break;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */


3.STM32CubeIDE 代码编写

1)在工程新建一个文件夹用于存放自己编写的代码并命名为 My_Code.

2),在 My_Code 文件加下新建一个专门存放头文件的文件夹 Inc,和专门存放.c 文件

的文件加 Src。

3)然后右建 Inc 文件夹新建 tracking.h,在 Src 文件夹新建 tracking.c 文件,然后编写我们

的红外检测代码。

4)按下 ALT+ENTER 快捷键进入工程配置界面,然后选择 Paths and Symbols,添加刚

刚新建的存放头文件的路径。

4.执行文件烧写

5.实验结果

将小车放在黑线中,小车跟随黑线轨迹行驶

实训总结

首先,要进行智能小车的开发,需要有一定的电子技术基础和STM32F103C8开发板的硬件设计能力。在开发过程中,需要熟悉STM32F103C8开发板的硬件原理图和电路设计,了解各个硬件模块的功能和连接方式。同时,还需要学习智能小车的控制算法和通信协议,以便实现小车的智能控制和通信功能。

其次,智能小车的开发需要使用相应的开发工具和调试环境。开发工具包括STM32F103C8开发板的IDE和烧写器,以及调试环境包括实时操作系统和仿真器等。在开发过程中,需要熟悉开发工具的使用方法,并进行调试和测试,以确保小车的功能和性能达到预期。

最后,智能小车的开发需要注重硬件设计的可靠性和稳定性,以及软件设计的灵活性和可扩展性。在开发过程中,需要考虑到硬件的耐久性和可维护性,以及软件的可扩展性和可维护性,以确保小车的稳定运行和长期可靠性。总之,STM32F103C8智能小车的开发需要有一定的电子技术基础和开发能力,需要使用相应的开发工具和调试环境,并注重硬件设计的可靠性和稳定性,以及软件设计的灵活性和可扩展性。

附件:项目硬件及代码

7.1 项目硬件(附图及说明)

image-20230604152644992

图1 .STM32F103C8芯片智能小车

image-20230604173939175

图2. 蓝牙模块

image-20230604173946336

图3.STM32F103C8芯片

image-20230604173954385

图4.超声波模块

7.2****函数流程图

image-20230604174002515

图5. 主函数流程图

image-20230604174013179

图6.寻迹模式流程图

7.3 项目代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include "total.h"

uint8_t car_mode = Bluetooth_Mode; //默认蓝牙控制模式
uint8_t bluetooth_cmd = BT_Car_Stop; //蓝牙控制指令

//蓝牙控制模式功能函数
void Bluetooth_Fun(void)
{
switch(bluetooth_cmd)
{
case BT_Car_Stop: //停止
Motor_Control_Stop();
break;
case BT_Car_Go: //前进
Motor_Control_Up(80);
break;
case BT_Car_Back: //后退
Motor_Control_Down(80);
break;
case BT_Car_Left: //左转
Motor_Control_Left(80);
break;
case BT_Car_Right: //右转
Motor_Control_Right(80);
break;
}
}
//定距模式功能函数
void Distance_Fun(void)
{
int DestDistance = 100; //目标距离10cm
int difference=0; //与目标距离的差值
Steering_Change_angle(ANGLE_DEFAULT); //转到90度
Distance_Send_Start(); //测量正前方距离.
difference = DestDistance - (int)distance_mm;
if(difference >= 0 && difference <= 1)
{
Motor_Control_Stop();
}
else if(difference<0) //远了,要前进
{
Motor_Control_Up(3*(uint16_t)difference+57); //简单的算法,离目标越近速度越慢
}
else if(difference>1) //近了,要后退
{
Motor_Control_Down(3*(uint16_t)difference+57); //简单的算法,离目标越近速度越慢
}
}

//循迹模式功能函数
void Tracing_Fun(void)
{
uint8_t tracing_info_now; //当前寻迹的四个红外状态,使用低四位
tracing_info_now = Get_State_Infrared(); //读取寻迹的四个红外的状态
switch(tracing_info_now) //根据当前的状态选择控制
{
case 6: //中间两条检测到
Motor_Control_Up(TRACING_UP_DEFAULT); //直走
break;
case 1: //加快右转
Motor_Control_Right(MIN_TURN_SPEED);
break;
case 2: //右转
Motor_Control_All(TRACING_UP_DEFAULT,0,MAX_TURN_SPEED,0);
break;
case 8: //加快左转
Motor_Control_Left(MIN_TURN_SPEED);
break;
case 4: //右转
Motor_Control_All(MAX_TURN_SPEED,0,TRACING_UP_DEFAULT,0);
break;
default:
break;
}
}
//避障模式功能函数
void ObstacleAvoidance_Fun(void)
{
uint8_t L_State=0,R_State=0; //左右两边红外标志
Steering_Change_angle(ANGLE_DEFAULT); //转到90度
Distance_Send_Start(); //测量正前方距离.
HAL_Delay(10);
L_State = HAL_GPIO_ReadPin(LH_GPIO_Port, LH_Pin); //左红外检测,0代表有阻
R_State = HAL_GPIO_ReadPin(RH_GPIO_Port, RH_Pin); //右红外检测,0代表有阻
if(L_State!=0 && R_State!=0 && distance_mm>120) //两边没有阻挡时且正前方障碍距离大于8cm
{
Motor_Control_Up(CarSpeed); //前进
return;
}

if(L_State==0 && R_State==0) //两侧有障碍后退
{
Motor_Control_Down(CarSpeed); //后退后检测左右两边障碍距离
HAL_Delay(250);
CheckLeftRight(0);
return;
}

if(L_State==0 && R_State!=0) //左边有阻
{
Motor_Control_Right(CarSpeed); //右转后进行下次判
HAL_Delay(80);
Motor_Control_Stop(); //小车停止
return;
}
if(L_State!=0 && R_State==0) //右边有阻
{
Motor_Control_Left(CarSpeed); //左转后进行下次判
HAL_Delay(80);
Motor_Control_Stop(); //小车停止
return;
}

if(distance_mm<=120 && L_State!=0 && R_State!=0)
{
Motor_Control_Stop();
CheckLeftRight(1);
}
}

//避障模式检测左右两侧超声距离
void CheckLeftRight(uint8_t mode)
{
uint32_t L_Dis=0,R_Dis=0; //超声波传感器测的左右两边障碍物距
check:
Motor_Control_Stop(); //小车停止
Steering_Change_angle(130); //转到130度测量左边有无障
HAL_Delay(350);
Distance_Send_Start(); //测量次正前方距离
HAL_Delay(150);
L_Dis=distance_mm;

Steering_Change_angle(50); //转到50度测量右边有无障
HAL_Delay(350);
Distance_Send_Start(); //测量次正前方距离
HAL_Delay(150);
R_Dis=distance_mm;

Steering_Change_angle(ANGLE_DEFAULT); //转到90
HAL_Delay(50);
if(L_Dis<60 && R_Dis<60) //左右两边均不能走
{
Motor_Control_Down(CarSpeed); //后段距离后进行下一次判
HAL_Delay(250);
goto check; //重新判断左右两边障碍物距离
}
else
{
if(L_Dis>R_Dis) //左边障碍物距离远
{
if(mode == 1)
{
Motor_Control_Left(CarSpeed); //左转后进行下次判
if(L_Dis>50)
HAL_Delay(200);
else if(L_Dis>40 && L_Dis<=50)
HAL_Delay(300);
else
HAL_Delay(400);
}
else
{
Motor_Control_Left(CarSpeed); //左转后进行下次判
if(L_Dis>100)
HAL_Delay(400);
else
HAL_Delay(500);
}
}
else
{
if(mode==1)
{
Motor_Control_Right(CarSpeed); //右转后进行下次判
if(R_Dis>50)
HAL_Delay(200);
else if(R_Dis>40 && R_Dis<=50)
HAL_Delay(300);
else
HAL_Delay(400);
}
else
{
Motor_Control_Right(CarSpeed); //左转后进行下次判
if(R_Dis>100)
HAL_Delay(400);
else
HAL_Delay(500);
}
}
}
Motor_Control_Stop(); //小车停止
}