STM32编写时的技巧(适用于新手)

本文是我在知乎上的一篇回答,有兴趣的朋友可以参考下面的链接,不过两篇文章是一样的。
https://www.zhihu.com/question/66634764/answer/696095626
本文适用于初学者。

硬件功能方面,十分建议学习好TIM,systick,GPIO,USART,NVIC这几个东西,最好能深入理解,因为这几个东西常常是出现在很多个项目当中的,非常重要的东西。

一,环境的搭建与程序的烧录

初学者的第一道门槛是解决两个问题:搭建环境以及烧录程序

1.1 软件选择?

首先,选择编程软件,是keil v5还是IAR?

我长期使用的是keil v5,不过IAR也是不错的,IAR适用的单片机更多一点。比如STM8系列的单片机,只能用IAR来编程。我们老师推荐我们先学STM8,因为它和51是类似的8位处理器,但功能更加全面,不过51的资料比STM8的要多。

keil v5软件及F103系列安装包

链接:https://pan.baidu.com/s/1O_1Kn6AqMiTLEVu9b-Q3Yw 提取码:ok10

其他系列的单片机需要去官网下载对应的安装包

IAR 7.7

链接:https://pan.baidu.com/s/1sIQsBfCR_huXlA0B1M9dkw 提取码:ze4d

这是STM32cube中文网:http://www.stm32cube.com/,打开网站点击“资源下载”,里面有许多有用的资料。

1.2 建立keil v5的编程环境

Project - New uVision Project 可以新建工程,选择保存的位置后,再选择对应的硬件型号。
在这里插入图片描述
图中,第1个图标用于修改工程配置,第2个图标用于管理工程内的文件。

在图标2中添加对应的.s启动文件以及.c文件(你需要用到什么文件就加什么文件,.h文件可以不加入)
在这里插入图片描述
由于软件此时不知道.c文件中调用的.h头文件具体在哪里,所以需要你手动添加。在图标1中添加头文件的目录位置。

在这里插入图片描述
由于本人不擅长IAR,故也不在此误人子弟了。

1.3 Debug调试与程序烧录

我是用的是J-Link仿真器,将对应的管脚相连,如果你不知道怎么连接,看看这张图。仿真器上有对应的表示。此图是某些STM32单片机上的两排引脚的含义图(注意不要接反了)
在这里插入图片描述

将仿真器与单片机相连以后,将仿真器接入电脑。此时,仿真器和STM32都应该有灯亮起来。

还没完,还需要修改程序配置。

修改Option的设置

1.Debug下,选择J-LInk。接着点击右侧的Settings
在这里插入图片描述

2.Port:选为SW

Max Clock:选为2MHz
在这里插入图片描述

再设置Flash Downlod ,修改为128k的

在这里插入图片描述

4.修改完后,在Option-Utilities下,改为J-Link

在这里插入图片描述

1.4 Debug与烧录

在编译成功以后,选择Load,即可烧录
在这里插入图片描述

使用Debug可以进行逐句的检查和调试
在这里插入图片描述

在Debug模式下,选择Peripherals - General Purpose L/O - GPIOA

可以打开GPIOA的管脚电平情况示意图
在这里插入图片描述

你可以在此图中检查你的编程是否按你的要求进行了操作。如果你配置了GPIOA中的0管脚为推挽输出模式,并且使得它在此时呈现高电平,那么在此图中会显示GPIOA_ODR那一行,第0列为√的形态。

你也可以手动点击该框格,如果此时STM32外部连接了一个LED灯的话,你可以发现你对框格的操作将立即生效。

二,官方手册的使用指南

知道了怎么配置环境,以及如何烧录,再来谈一谈编程的思路。

首先,准备好官方的固件库手册。

1.初始化:

(这一步用STM32cube易于实现。)一般要配置这些内容:时钟,中断(有些不用),GPIO引脚配置,相关的结构体。

此处以配置TIM1举例:

我要实现TIM1的功能,打开固件库手册,打开文件stm32f10x_tim1.h,注意打开的是.h文件。
在这里插入图片描述

看到在开头,有几个结构体类型TIM1_TimeBaseInitTypeDef以及其他结构体类型,这些东西就是你可以配置的东西,那么哪些结构体类型你需要配置,哪些结构体类型你没必要配置呢?

就需要参考官方的例程,或者其他人的例程,这个很好找。找到后,看看人家配置了哪些功能,你只要对应着照猫画虎地配置就好了。

在该.h文件下有着丰富的信息。比如你建立了结构体变量,你想要配置它,可以在原来的.h文件上下找找有什么可以使用的量。(可以在结构体类型上点击右键-找到定义的地方)
在这里插入图片描述

比如这个TIM1_CouterMode这个成员,可以填写的内容就可以在.h文件的下面找到。
在这里插入图片描述

复制粘贴过去就行了,具体的其他配置,需要看视频理解其功能和原理。这里只是说一下编写时候的技巧。

还需要注意的是,每次配置完成成员以后,一定要将参数初始化,否则配置无效。
在这里插入图片描述

2.实现对应的功能

2.1库函数编写

你先要明白对于这个硬件,你能用什么函数?要想知道这个,你必须要查固件库手册
在这里插入图片描述

比如我要看看TIM1中究竟可以调用哪些函数?官方的固件库手册里可是帮你整理好了。都写在了一个表里,我从描述中找到需要的功能函数,再从目录里面查找那个函数。

比如,我看中了TIM1_DMAConfig 这个函数。
在这里插入图片描述

找到说明,你可以很明显的知道你要输入什么和输出什么。如果有些参数你不知道怎么填写,比如图中的DMA传输起始地址。

那么你有三种方式查找:一,百度。二,翻阅.h文件看看有没有相关的宏定义。三,查看相关的例程。

这里的传输起始位置,就在下面已经有了,不过不建议直接用下面的来表达,因为你的固件库手册的版本不一定和你自己工程当中的固件库版本匹配,必须要查看stm32f10x_tim1.h文件下是怎么定义这个宏的。
在这里插入图片描述
在这里,我就查找到了,所以可以直接使用。如果没有查找到,自己手动翻一下.h文件。

在这里插入图片描述
以上说的是库函数的使用办法,查阅的是STM32F103xx固件库使用手册_v3.5版本.pdf这个文件。

2.2寄存器编写

如果你想用寄存器编写,需要查阅STM32F103xx官方参考手册(源享科技).pdf这个文件,还是用类似的思路查询:这个硬件下有哪些寄存器?它们的哪一位能实现什么功能?看中了某一个功能以后,再在工程中进行配置。

不过寄存器编写的程序对于我来说可读性不怎么好。所以,我只要在库函数不够用的时候,才会去用寄存器的方式编写。

大家看这张图,明显和库函数编写时候有很大的差异,它没有一个表格,把所有寄存器的功能给一起简述出来。不如库函数查找功能时那么方便。如果你要找到你想要的功能的话,有时得把TIM寄存器这一整节都看完。

我觉得,如果你想从事这个行业的话,那么必然要熟悉这些底层的寄存器,但是,如果只是业余爱好的话,不建议接触这些寄存器。因为你要记忆大量的寄存器的某些位对应的功能。
在这里插入图片描述

在stm32f10x_tim1.c文件当中,有一些利用宏定义安排好的寄存器位置,可以方便你调用
在这里插入图片描述

反过来,如果你是在某个例程当中,看不懂寄存器编写的代码,那你就可以来查询这个手册。

三,宏定义

宏定义是一个强大的东西,必须要利用好,这样可以很方便的帮助后期更改硬件及参数。

我把宏定义单独放在了一个文件里面:User_Macros.h。

1.看到开头有一个

#ifndef __User_Macros_H

#define __User_Macros_H

//接下来的内容

#endif //别忘了在结尾加上这个。。

这个是用于防止重复引用的,如果文件A调用了这个头文件,那么文件B再调用这个头文件时,软件就不会再次编译了。这句话防止了重复定义等错误。
在这里插入图片描述

2.可以利用宏定义,建立一些模式:

#define Test_Mode 1

在对应的地方使用:

#if Test_Mode ==1

//测试程序

#endif

这里可以实现切换诸多的功能。如果不想使用该模式了,打开User_Macros.h将Test_Mode修改成0即可。

也可以添加其他的模式,比如OLED的IIC模式与8080并行模式,或者加入操作系统也可以。
在这里插入图片描述

3.我建议将数值都改为我这种表达方式,比如PA.0口,我用Huoer_Input来代替。以后我要修改霍尔传感器所接引脚,只需要修改这里的两行代码就行了,不需要再去翻阅代码那么麻烦。

4.我十分建议在.h文件当中把注释写的丰富一些,方便后期修改调试。

四,工程模板

为了方便今后的编写,我建立了工程模板,把我曾经写过的通用函数封装起来,放在这个模板里面,以后直接复制粘贴调用就好了。

这个也是一个十分有用的技巧。可以有效地减少前期初始化配置地操作次数。
在这里插入图片描述

五,STM32Cube

这个软件用于可视化的对STM32的配置,学习这个的好处是编写速度变快。不需要花费很多的时间在诸多的硬件功能初始化上。

不过这个软件有个门槛,就是英语。它导出的工程是使用HAL库或者LL库编写的,而这两个库的编程手册我查了很久,全是英文的,没有中文手册。有能力的同学,十分建议学习STM32Cube,可以提高编写的效率。

六,初学者可能遇到的错误

我使用的是keilv5,所以以下内容针对的是使用keil v5的同学。

1.中断函数重复定义

这个错误可能大部分人都会遇到。自己编写的中断函数与stm32f10x_it.c下的某个函数冲突了???自己又不敢随意动这个文件。

首先,大家在编写完中断函数(注意,中断函数有固定名称)以后,一定要将stm32f10x_it.c下的同名称的中断函数给注释掉。

其次,不能直接把stm32f10x_it.c下所有中断函数全部注释掉,否则会报错。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值