梦开始的地方

哔哩哔哩视频地址

硬件准备

开始学习STM32单片机前我们需要准备以下工具,以下为基本工具后面会需要更多工具

单片机*1

烧录器*1

单片机原理图

CubeMX软件

Keil5软件

本教程的所使用的开发板如图所示淘宝29元,并不一定需要跟作者一样的单片机其他单片机也是可以的,但是需要有原理图。这款性价比极高比较推荐

开发板

本教程使用的是DAP-Link,直接淘宝搜索daplink只需要能用即可,不超过15元的就可以了更贵的不代表更好用,可以使用SWD接口和虚拟串口即可,这样可以既可以做烧录器又可以当串口调试器,就不需要再购买USB转TTL工具。

软件准备

需要安装好CubeMX软件,官网链接点这里,直接下载最新版,下载需要填写一些信息随便填写即可,下载完毕直接安装。

需要安装Keil5软件,官网链接点这里,选择MDK-ARM,信息随便填写即可,下载完毕直接安装。

安装完Keil5后需要安装STM32 F4的Pack,[下载页面点这里](Arm Keil | CMSIS Packs),搜索stm32f4直接下载(如果下载没有反应建议复制下载链接用迅雷下载),下载完直接双击安装,这里需要注意必须先安装好Keil5才可以安装。

完成上述步骤后还需要将Keil5破解,注意破解最好不要再公司网络上,否则律师函警告,如何破解请自行百度

破解温馨提示注意以下两个细节基本就不会有问题

1.运行keygen.exe没有反应,而且刷新后为什么直接消失了?

答:打开设置搜索病毒和威胁防护,点击“病毒和威胁防护设置”下面的管理设置,把实时防护关闭,然后右键keygen.exe以管理员身份运行,如果没有病毒和威胁防护可以尝试把CID给其他能打开keygen.exe的电脑上生成LIC

2.为什么keil5破解时间不对,破解到更早以前去了?

答:复制完keil5的CID后需要关闭keil5,生成LIC码之后需要以管理员身份运行keil5,添加LIC,一般破解时间是在当前时间上加十年

代码风格规范

为什么要开始就要求有代码风格规范呢,拿一张图举例不知道大家能不能看懂

如果写出来的的代码只有自己看得懂或者连自己都看不明白,那这样的代码跟屎山代码无异,为了培养以后的代码规范和代码风格,我认为学习开始的时候就要有代码规范意识

接下来是作者个人的一些代码风格,仅供参考,希望对大家的代码风格起到帮助,如果是纯小白的话可以先看顺眼,以后写代码再来多看看养成自己的风格

  • 等号两边加空格(可以延申到其他符号)
1
2
3
4
a = b; // 这个两边加空格
a >= b; // 这个是判断条件语句也需要两边加空格
a == b;
a++; // 这个不加空格
  • 各类循环的写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* for循环 */
for(int i = 0; i < 10; i++) // 符号两边空格,分号后面空格,但是似乎C99以前的版本不支持这样定义变量
{ // 花括号另起一行
printf("i [%d]\n", i); // 如果有多个参数每个逗号后面用空格隔开,参数%d可以用中括号括起
}
/* switch循环 */
switch(index) // switch写法的风格不同大家可以选择自己喜欢的学
{
case 0:{ // case的作用域用花括号括起
printf("index is 0\r\n");
}break; // 结尾加上break;

case 1:{
printf("index is 0\r\n");
}break;

default:{ // switch需要加上default未知错误
printf("index is err\r\n");
}break;
}
  • 命名方法,常用的就是驼峰和下划线
1
2
3
4
5
6
7
8
9
10
11
12
/*
* 大驼峰命名和下滑行命名都比较不错
* 但是最好在一个完整的项目中只用一种命名方法
* 这里因为函数名字和变量用同一种命名方法名字容易冲突,所以可以参考一下HAL库
* 比如把函数开头用同一的缩写表示属于那部分的函数
* 例如:HAL_Delay
* 实际上HAL库使用的都是大驼峰命名,只是函数开头加上HAL_用来表征函数和所属
*/
int HelloWorld // 这是大驼峰所有单词首字母大写,小驼峰是第一个单词是小写的
void HelloWorld(void);
int hello_world // 这个是下划线命名法,单词由下划线连接,单词全小写
void hello_world(void);
  • 注释方法
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
/*
* 方法一
* 这种注释可以多行写,就可以写很多注释也可以不超出屏幕
* 一般用于文件头部的著作声明和函数说明
*/

/* 方法二,独占一行的注释,一般用于说明功能 */

// 方法三,只写少量注释,一般用于代码屁屁上的简单说明

/*
* 以下是一个简单的示范
* 示范三种注释方法的使用和适用情况
* 但是无论怎么注释都要注意代码和注释不能超出屏幕
* 如果超出就另起一行
*/
int Buf = 0; // 注意加空格
for(int i = 0; i < 10; i++) // 循环10次
{
if(i > 5){
/* 如果i大于5 */
printf("i > 5\r\n"); // 打印调试消息
}else{
/* 如果i小于5 */
printf("i < 5\r\n"); // 打印调试消息
}
}
  • 代码对齐
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
/* 例如宏定义对齐 */
#define DEFINE1 1
#define DEFINE2 1
#define DEFINE3 1
#define DEFINE_DEFINE_DEFINE 1
#define DEFINE4 1

/* 上面是统一对齐,如果这种特别长的比较少可以挪到最后单独对齐,比如下面的 */
#define DEFINE1 1
#define DEFINE2 1
#define DEFINE3 1
#define DEFINE4 1
#define DEFINE_DEFINE_DEFINE 1
#define DEFINE1_DEFINE1_DEFINE1 1

/* 结构体定义时的对齐以下两种赋值方式,例如HAL库的GPIO */
GPIO_InitTypeDef GPIO_InitStruct = { // 方式一
.Pin = LED_R_Pin,
.Mode = GPIO_MODE_OUTPUT_PP,
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_FREQ_LOW,
};

/* 无论时方式一还是二都要等于号对齐 */
GPIO_InitStruct.Pin = LED_R_Pin; // 方式二
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

/* 数组结构体定义时注释对齐等等 */

只要多行相似结构的情况下就要考虑到代码对齐和不能过长超出屏幕,这里只列举几项效果最明显最常用的规范,其实在工程中还有很多细节上的规范大家可以多多观察别人写的好的代码比如HAL库,再提几个小点:

  • 代码0错误0警告,大家务必做到这点
  • 如果有库的明确功能函数就不要尝试自己去调用底层参数或者函数其他参数(这点可能需要有点写库经验的人好理解,如果大家都去调底层那不是逼作者用C++写库)
  • 多了解使用学习一些别人写的成熟且使用广泛的库,这样可以很快提升自己的理解
  • 不用的代码先注释,确认完成之后没用到再删
  • 注释尽量用母语,注释应该要指明代码想要实现的功能,而不是翻译代码
  • 多写记录文档,如果不是小白就要学会使用Git做好代码保存和版本管理,如果不会Git作者也写了Git安装使用方法(已发布“TortoiseGit安装与Github使用”)

代码格式配置

作者的个人偏好是使用UTF-8编码方式,TAB为4空格对齐

这样的配置相比于GB2312和制表符对齐有什么更好的吗?

  • UTF-8出现乱码的情况比GB2312少很多,异常情况也少很多
  • 使用空格对齐而不是制表符对齐就可以避免不同编辑器或者查看器缩进长度不一致的情况,比如我在Keil里面是对齐的但是到VScode里面打开看就是歪的
  • 四格缩进可以让代码看上去没有那么紧凑,看的比较舒服,写代码也是一样的多加空格换行,防止代码写成一团
Keil5配置

配置代码格式

VScode配置

步骤略多,但是教程很多自行百度,只要配置成这个样子就可以了