在学习野火的《零死角玩转stm32F03指南者》过程中,学到第10章初识寄存器章节,感觉包里面文件有点多,不是很好记忆,因此写个记录便于查阅。
库的来源简介:
一块单片机芯片由内核+外设组成,类比个人电脑,单片机的内核就是电脑的cpu,包含了计算单元和控制器单元,单片机的外设就是个人电脑里面的内存、硬盘、串口等外设。个人电脑上cpu是单独的一块芯片,而内存和硬盘是放在主板上的,因此我们可以从电脑主板上看到有cpu、硬盘等独立的物理硬件。而单片机把cpu、内存、硬盘等集成在一起了,所以我们看到的就是一块芯片,实际上里面是包含了内核和外设的。stm32f103芯片的内核是用的arm公司的cortex-m3,外设是ST公司设计的,并最终由ST公司生产制造芯片。
制造单片机芯片的公司很多,他们都只设计外设,内核都是用的arm的,在市面上就会有很多不同厂家的芯片,但内核是一样的,只是外设不一样。如果没有一套统一的标准,这就给产品公司带来很大的麻烦。
比如芯片厂商A和B两家公司的单片机都是用的arm的cortex-m3内核,但是外设由A和B公司自己独立设计。此时产品公司C购买了A公司的单片机,开发了一款产品,产品上市一段时间后,A公司倒闭了或者是B公司的单片机要便宜一点等因素,所以C公司想要更换为B公司的单片机。这时候C公司肯定是最希望直接把A公司的单片机替换为B公司的芯片,因为这样最节约时间又省事省钱。但是由于A公司和B公司是独立设计的外设,所以控制寄存器的配置和提供的函数接口都不太一样,此时产品公司C买了B公司的单片机后就得重新编写代码,调试,甚至要改电路板,这就给产品公司C造成了不小的损失。故此CMSIS标准顺应市场需求而生。
基于产品公司想要一套代码,能直接或改动很小就可以在不同的单片机上运行这样的需求。arm公司arm公司联合芯片厂商建立CMSIS标准(Cortex MicroController Software Interface Standard)。即建立了一套统一的驱动抽象层,这样用户的代码就尽可能减少与物理芯片的耦合性。后期换了芯片,用户也只需要改动很少的代码就可以运行起来。
自此简单介绍了一下库的来源,至于CMSIS标准的具体细节,就需要各位自行去看了。
stm32f10x的hal库是按照CMSIS标准写的,所以学习了hal库开发,也就相当于学习了一遍CMSIS标准。
一、 按功能模块分类
按照不同的功能,我们可以将单片机和库抽象成下图所示的样子,其中红色框出来的,就是五个不同的功能模块,等会我们需要导入每个部分的库文件。此图在野火的书上第10章。
①是内核外设寄存器的定义和操作函数(由arm提供,其余的由st提供),在stm32f103中只会用到的是:core_cm3.h和core_cm3.c
②是系统时钟,在stm32f103中用到的是:system_stm32f10x.h和system_stm32f10x.c
③是中断服务函数,stm32f103中用到的是:strm32f10x_it.h和strm32f10x_it.c
④是片上外设寄存器映射(也是总的头文件),stm32f103中用到的是:stm32f10x.h
⑤是片上外设驱动库,包含了uart、i2c、spi、adc等外设的驱动函数,stm32f103中用到的是stm32f10x_uart.h和stm32f10x_uart.c、stm32f10x_i2c.h和stm32f10x_i2x.c等文件。
以下⑥和⑦是工程中需要的,不在上图中,为了方便归类写在此处。
⑥片上外设配置文头文件(被包含于④中),stm32f103中用到的是stm32f10x_conf.h
⑦启动文件()由汇编语言编写,stm32f103中用到的是如startup_stm32f10x_hs.s,开发51的时候其实也有这个文件,在keil的安装目录下,编译时keil帮我们加入了,所以我们看不到。作用相当于linux下的bootloader。
二、库代码存放目录
一个单片机的内核和外设由两个公司设计。所以内核的核心代码由arm公司提供,外设的核心代码由芯片制造厂商提供,我们用是stm32f103单片机的内核代码由arm公司提供,外设代码由ST公司提供,ST公司也提供了内核时钟、内核中断、内核启动这些与内核相关的代码,这些与内核相关的我们都存放在CMSIS目录下,只与外设相关的我们存放在Driver目录下,故一级目录如下:分成CMSIS和STM32F10x_HAL_Driver。如下图,在libraries下面放了CMSIS和STM32F10x_HAL_Driver两个目录。
1.CMSIS目录下存放了下列黄色标出的文件,均与内核相关,如下图,图来自野火指南针教材
2.STM32F10x_HAL_Driver目录下建立 inc和src两个目录。存放与外设相关的驱动代码。
inc目录下存放如下头文件,src存放对应的.c文件。
三、用户代码存放目录
新建user目录,存放main.c、stm32f10x_conf.h、stm32f10x_it.h、stm32f10x_it.c四个文件。
如下图:
main.c程序主体实现。
stm32f10x_config.h:主要用于包含外设驱动头文件,而stm32f10x_config.h被包含在stm32f10x.h头文件中,故stm32f10x.h成为了stm32唯一打包的头文件。
stm32f10x_it.h/.c用于编写中断服务函数,系统异常的函数接口名已经在startup_stm32f10x_hd.s中定义好,需要我们自己实现处理逻辑,我们先去startup_stm32f10x_hd.s拷贝中断函数名,然后在stm32f10x_it.h/.c中写中断处理函数。
四、代码组织逻辑图
新建一个文件夹,作为工作空间,然后在里面建立如下文件夹,这是野火教程中的代码存放风格,可以根据公司风格来,或者自己个人风格来存放。一般都是按照功能或者模块来分目录,相似功能或者统一模块的代码放在一个目录下,不同功能或不同模块的代码放在不同的目录下。
下图蓝色的为目录,如stm32f103、CMSIS,淡红色的为文件。
至此一个简单的工程文件目录组织就搭建起来了。