欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

STM32固件库的学习及使用固件库编写工程模板

程序员文章站 2022-03-11 15:28:19
一、配置固件库在一个文件夹下建立如下子文件夹...

初识固件库

引用野火老师讲的初识固件库一节的课件

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。
}

配置固件库

在一个文件夹下建立如下子文件夹

STM32固件库的学习及使用固件库编写工程模板
Doc:工程说明文件
LIbraries:添加的固件库文件
Project:建立的工程文件
User:自己编写的函数文件

在Keil中建立如下如下文件夹

STM32固件库的学习及使用固件库编写工程模板
STARTUP:启动文件所在位置
CMSIS:Cortex-M 软件接口标准(内核相关的文件)
FWLIB:固件库文件所在位置
USER:用户文件所在位置
DOC:工程说明文件所在位置
STM32固件库的学习及使用固件库编写工程模板

启动文件

启动文件简介

启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
1、初始化堆栈指针SP=_initial_sp
2、初始化PC 指针=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界

启动文件的选择

不同型号的单片机用的启动文件不一样,有关每个启动文件的详细说明见下表
STM32固件库的学习及使用固件库编写工程模板

位带操作

位操作就是可以单独的对一个比特位读和写,在STM32 通过访问位带别名区来实现位操作。

在STM32 中,有两个地方实现了位带,一个是SRAM区的最低1MB 空间,令一个是外设区最低1MB 空间。这两个1MB 的空间除了可以像正常的RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这1MB 的空间的每一个位膨胀成一个32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。

STM32固件库的学习及使用固件库编写工程模板

外设外带区的地址为: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

相关标签: STM32 单片机