第3章
基本I/O端口控制
学习STM32之前,建议有8位单片机的学习基础,例如51单片机、AMEG8等,这对于学习新的CortexM3处理器有很大帮助。在第2章已经安装好了MDK软件,版本为V4.72,STM32设计操作包括直接寄存器操作和库函数操作,直接寄存器操作与51单片机控制很接近,库函数操作与学过8位控制器的读者来说有很大的不同,开始阅读本章的读者可能会比较困惑,不要着急,稍后会详细介绍库的含义和使用方法。接下来通过一个简单的寄存器操作对STM32有个初步地介绍,就从流水灯开始STM32的学习之旅吧。
3.1MDK新建工程
(1) 单击桌面UVision4图标,启动软件。如果是第一次使用会打开一个自带的工程文件,可以通过工具栏Project→Close Project选项关掉。
(2) 新建的工程文件保存在一个文件夹里面。首先创建一个名为“流水灯”的文件夹,在“流水灯”文件夹里建几个文件夹: Doc、Libraries、 Listing、 Output 、Project、 User(为了使读者先有个感性认识,可以参考书中附带的例子,从例子中添加这些代码,后续会陆续解释其含义),工程“流水灯”文件夹的子文件夹如图31所示。
图31流水灯工程的子文件夹
① Doc用来存放一些说明文档,一般文件格式为XXX.TXT。
② Libraries用来存放ST库最核心的文件,包含FWlib和CMSIS两个文件夹。
FWlib用来存放STM32库里的inc和src两个文件,这两个文件包含了芯片上的所有驱动。
inc和src两个文件夹也是直接从ST的库里复制过来的。
inc里是ST片上资源的驱动头文件,如果用到某个资源,则必须把相应的头文件包含进来。
src里是ST片上资源的驱动文件,这些驱动涉及了大量的C语言知识,是学习库的重点。
CMSIS用来存放库自带的启动文件和一些M3系列通用的文件。CMSIS存放的文件适合任何M3内核的单片机。CMSIS为Cortex Microcontroller Software Interface Standard的缩写,是ARM Cortex微控制器软件接口标准,是ARM公司为芯片厂商提供的一套通用且独立于芯片厂商的处理器软件接口。
③ Listing用来保存编译后生成的链接文件。
④ Output用来保存软件编译后输出的文件。
⑤ Project建立工程文件的路径。
⑥ User用来存放用户编写的驱动文件。
(3) 在工具栏Project→New μVision Project,新建工程文件,如图32所示。
图32Project新建工程
(4) 在Project文件夹里创建一个工程,名字为liushuideng,如图33所示。
图33Project中新建liushuideng
(5) 选择芯片的型号,本书使用的芯片是ST公司的STM32F103RC。选择窗口如图34所示。
图34器件选择窗口
(6) 接下来询问是否需要复制STM32的启动代码到工程文件中,这个启动代码在M3系列中都是适用的,一般情况下单击“是”按钮,这里用的是ST库,库文件也自带了一份启动代码,为了保持库的完整性,就不需要开发环境自带的启动代码了,稍后手动添加启动代码,这里单击“否”按钮,如图35所示。
图35STM32启动代码是否复制到工程文件中的询问对话框
(7) 此时工程新建成功,打开如图36所示的界面。工程中还没有任何文件,接下来在工程中添加所需文件。
图36新建工程成功后的界面
(8) 把Target1的名称改为“流水灯”,其实不改也可以,改了只是为了见名知义,如图37所示线条圈出部分。
图37Target1改为“流水灯”
(9) 往工程里面添加5个组文件夹,并命名为STARTUP、CMSIS、FWLIB、USER、DOC。选择Add Group,如图38、图39所示。
图38Add Group界面
图39添加文件夹界面
从名字就可以看得出是用它来存放启动代码,USER用来存放用户自定义的应用程序,FWLIB用来存放库文件,CMSIS用来存放M3系列单片机通用的文件。
(10) 接下来往这些新建的组中添加文件,双击哪个组就可以往哪个组里添加文件,如果该组已经有文件,双击则把组里的文件都显示出来,然后再双击该组,可以继续添加文件。
在对话框的文件类型里选择ALL files(*.*),否则有些文件会显示不出来,如图310所示。
图310新建组中添加文件
① 在STARTCOKE里添加startup_stm32f10x_hd.s。
② 在USER组里添加main.c、stm32f10x_it.c两个文件。
其中,stm32f10x_conf.h、stm32f10x_it.h两个头文件不需要添加,即使添加也添加不进来,因为.h文件不是通过这种方式进入到工程里面的。头文件都包含在.c文件中,当编译工程时,.h文件就自然包含进来了。
③ 在FWLIB组里添加src里的全部驱动文件,当然,src的驱动文件也可以需要哪个就添加哪个。这里将它们全部添加进去是为了后续开发
方便,况且可以通过配置stm32f10x_conf.h头文件来选择性添加,只有在stm32f10x_conf.h文件中配置的文件才会被编译。
④ 在CMSIS里添加以下文件。注意,这些组里添加的都是汇编文件和C文件,头文件是不需要添加。
⑤ 在DOC文件夹添加readme.txt文档对程序重要信息进行说明,如果使用的I/O端口,配置后的工程如图311所示。
图311配置后的工程
至此,“流水灯”工程已经基本建好,但是还有一些工作需要完成。下面来配置MDK的选项。
3.2MDK工程配置
(1) 单击工具栏中的魔术棒按钮,弹出配置菜单,可以看到配置菜单关于Device、Target、Output、Listing、User、C/C++、Asm、Linker、Debug和Utilities选项的设置。
(2) Device在新建工程时已经选定了器件,单击Target选项卡,勾选微库,这样是为了后面的串口例程可以使用printf函数,如图312所示。
图312Target选项卡
(3) 单击Output选项卡,再单击Select Folder for Objects…按钮,设置编译后输出文件保存的位置。同时把Debug Information、Create HEX File和Browse information复选框都勾选上,如图313所示。
图313Output选项卡
(4) 在Listing选项卡中,单击Select Folder Listings…按钮,定位到模板中的Listing文件夹,如图314所示。
图314Listing选项卡
(5) 在C/C++选项卡上需要设置的比较多。
① 在Define里输入添加STM32F10X_HD,USE_STDPERIPH_DRIVER两个宏。添加USE_STDPERIPH_DRIVER是为了屏蔽编译器的默认搜索路径,转而使用添加到工程中的ST的库,添加STM32F10X_HD是因为用的芯片是大容量的,添加了STM32F10X_HD宏之后,库文件为大容量定义的寄存器就可以用了。芯片是小或中容量时,宏要换成STM32F10X_LD或者STM32F10X_MD。
② 在Include Paths栏添加库文件的搜索路径,就可以屏蔽掉默认的搜索路径。
③ 当编译器在指定的路径下搜索不到,还是会回到标准目录去搜索,就像有些ANSIC C的库文件,例如stdin.h、stdio.h。
库文件路径修改成功之后,如图315所示。
图315C/C++选项卡
(6) 单击Debug选项卡,选择Use Simulator,软件仿真设置完成,如图316所示。
图316Debug选项卡
(7) 单击菜单栏中的编译按钮,对该工程进行编译,弹出编译信息,编译成功。
linking...
Program Size: Code=1000 RO-data=252 RW-data=0 ZI-data=1024
FromELF: creating hex file...
"..\Output\liushuideng.axf" - 0 Errors, 0 Warning(s).
3.3寄存器法操作代码分析
在main.c文件里输入以下代码,实现流水灯的闪烁,其中led接到STM32的GPIOB口的8~15号引脚,如图317所示。
有过单片机编程经历的人很容易看懂这段代码,主要涉及几个寄存器,RCC→APB2ENR,GPIOB→CRH和GPIOB→ODR。STM32普通I/O端口的使用过程大致步骤如下:
① 先开启对应I/O端口时钟(RCC→APB2ENR);
② 配置I/O端口(GPIOB→CRH);
③ 给I/O端口赋值(GPIOB→ODR)。
这3步完成一个I/O端口的最基本操作,代码如图318所示。
……