STM32固件库的学习及使用固件库编写工程模板
初识固件库
引用野火老师讲的初识固件库一节的课件
1-汇编编写的启动文件
startup_stm32f10x_hd.s:设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、对用C库函数_main最终去到C的世界
2-时钟配置文件
system_stm32f10x.c:把外部时钟HSE=8M,经过PLL倍频为72M。
3-外设相关的
stm32f10x.h:实现了内核之外的外设的寄存器映射
xxx:GPIO、USRAT、I2C、SPI、FSMC
stm32f10x_xx.c:外设的驱动函数库文件
stm32f10x_xx.h:存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明
4-内核相关的
CMSIS - Cortex 微控制器软件接口标准
core_cm3.h:实现了内核里面外设的寄存器映射
core_cm3.c:内核外设的驱动固件库
NVIC(嵌套向量中断控制器)、SysTick(系统滴答定时器)
misc.h
misc.c
5-头文件的配置文件
stm32f10x_conf.h:头文件的头文件
//stm32f10x_usart.h
//stm32f10x_i2c.h
//stm32f10x_spi.h
//stm32f10x_adc.h
//stm32f10x_fsmc.h
…
6-专门存放中断服务函数的C文件
stm32f10x_it.c
stm32f10x_it.h
中断服务函数你可以随意放在其他的地方,并不是一定要放在stm32f10x_it.c
#include “stm32f10x.h” // 相当于51单片机中的 #include <reg51.h>
int main(void)
{
// 来到这里的时候,系统的时钟已经被配置成72M。
}
配置固件库
在一个文件夹下建立如下子文件夹
Doc:工程说明文件
LIbraries:添加的固件库文件
Project:建立的工程文件
User:自己编写的函数文件
在Keil中建立如下如下文件夹
STARTUP:启动文件所在位置
CMSIS:Cortex-M 软件接口标准(内核相关的文件)
FWLIB:固件库文件所在位置
USER:用户文件所在位置
DOC:工程说明文件所在位置
启动文件
启动文件简介
启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
1、初始化堆栈指针SP=_initial_sp
2、初始化PC 指针=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界
启动文件的选择
不同型号的单片机用的启动文件不一样,有关每个启动文件的详细说明见下表
位带操作
位操作就是可以单独的对一个比特位读和写,在STM32 通过访问位带别名区来实现位操作。
在STM32 中,有两个地方实现了位带,一个是SRAM区的最低1MB 空间,令一个是外设区最低1MB 空间。这两个1MB 的空间除了可以像正常的RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这1MB 的空间的每一个位膨胀成一个32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。
外设外带区的地址为:0X40000000~0X40100000,大小为1MB,这1MB 的大小在103系列大/中/小容量型号的单片机中包含了片上外设的全部寄存器,这些寄存器的地址为:0X40000000~0X40029FFF 。外设位带区经过膨胀后的位带别名区地址为:0X42000000~0X43FFFFFF,这个地址仍然在CM3 片上外设的地址空间中。
SRAM的位带区的地址为:0X2000 0000~X2010 0000,大小为1MB,经过膨胀后的位带别名区地址为:0X2200 0000~0X23FF FFFF,大小为32MB。操作SRAM 的比特位这个用得很少。
位带区和位带别名区地址转换
外设: AliasAddr == 0x42000000+ (A-0x40000000) * 8 * 4 +n * 4
(0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有8 位,所以 * 8,一个位膨胀后是4 个字节,所以 * 4,n 表示该比特在A 地址的序号,因为一个位经过膨胀后是四个字节,所以也*4。)
SRAM: AliasAddr == 0x22000000+ (A-0x20000000) * 8 * 4 +n * 4
(分析同上)
公式合二为一,统一公式
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))
addr & 0xF0000000 是为了区别SRAM还是外设,实际效果就是取出4 或者2,如果是外设,则取出的是4,+0X02000000 之后就等于0X42000000,0X42000000 是外设别名区的起始地址。如果是SRAM,则取出的是2,+0X02000000 之后就等于0X22000000,0X22000000 是SRAM别名区的起始地址。
addr & 0x00FFFFFF 屏蔽了高三位,相当于减去0X20000000 或者0X40000000,但是为什么是屏蔽高三位?因为外设的最高地址是:0X2010 0000,跟起始地址0X20000000 相减的时候,总是低5 位才有效,所以干脆就把高三位屏蔽掉来达到减去起始地址的效果,具体屏蔽掉多少位跟最高地址有关。SRAM 同理分析即可。<<5 相当于84,<<2 相当于*4,这两个我们在上面分析过。
如:
#define GPIOB_ODR_Addr (GPIOB_BASE+0x0c) #define PBout(bit) *(unsigned int*)((GPIOB_ODR_Addr&0xf0000000)+0x02000000+((GPIOB_ODR_Addr&0x00ffffff)<<5)+(bit<<2)) #define GPIOA_IDR_Addr (GPIOA_BASE+0x08) #define PAin(bit) *(unsigned int*)((GPIOA_IDR_Addr&0xf0000000)+0x02000000+((GPIOA_IDR_Addr&0x00ffffff)<<5)+(bit<<2)) #define GPIOC_IDR_Addr (GPIOC_BASE+0x08) #define PCin(bit) *(unsigned int*)((GPIOC_IDR_Addr&0xf0000000)+0x02000000+((GPIOC_IDR_Addr&0x00ffffff)<<5)+(bit<<2))
本文地址:https://blog.csdn.net/Brave_Runer/article/details/107753187