1.​​​​​​芯片架构简图(详见参考手册存储器和总线架构部分,可以了解内核和外设间的通信方式)

 

黄色部分位ARM公司设计的驱动部分(内设),粉色部分为ST公司设计的被动部分(外设)。

1)内核M3通过ICode总线读取Flash烧录程序内容;2)DCode总线,即DataCode,用于读取常量或变量;3)DMA同样会读取数据,这时需要总线矩阵区分哪个总线在读取数据;4)System主要用来读取寄存器;

1)Flash用于存放程序;2)SRAM用于存放变量;3)FSMC用于驱动外存;4)AHB-APB,其中AHB、APB1为高速总线,APB2为低速总线;

2.存储器映射(详见数据手册存储器映射)

        STM32芯片有32位,2的32次方即为4GB内存,4G内存分为8块(block0-block7),每块512M。flash只能放到中block0(512KB);SARM只能放到block1中(64KB),block2存储Peripherals(外设);block3、4存储FSMC;block5存储FSMC的register(寄存器);block6没有使用;block7存储Cortex-M3的外设;

            STM32为32位单片机,也就有高16位和低16位,类比51单片机(8位单片机)的高4位和低4位,这也就是32单片机地址格式的来源,同时在32单片机同一级别的成员间,在地址同一位上差值为4。

        将外设按地址值进行编号后放入相应的内存中就是存储器映射。

3.什么是寄存器映射

寄存器定义:有特定功能的内存单元所取的别名。

寄存器映射:将分配好地址且有特定功能的内存单元取名。

4.寄存器地址查找(以GPIOB的BSRR寄存器为例)

参考手册存储器映像:找到端口基地址

参考手册端口寄存器描述:找到地址偏移量

总线基地址(0x4001 0000)+外设偏移地址(0x0C00)=外设基地址(0x4001 0C00)

外设基地址+寄存器偏移地址(0x10)=外设寄存器基地址(外设绝对地址:0x4001 0C10)

1)为寄存器的名称;2)为寄存器偏移地址与寄存器复位状态;3)说明寄存器存在的位是否可以读写;4)对寄存器位进行介绍,说明寄存器置位功能;

5.自建库文件寄存器编程(以GPIOB为例)

#ifndef __stm32f10x_h__
#define __stm32f10x_h__
//STM32寄存器映射代码

//外设(peripheral)总线映射
#define PERIPHERAL_BASE (unsigned int)0x40000000 //定义外设总线基地址
#define APB1PERIPHERAL_BASE PERIPHERAL_BASE //定义APB1总线地址
#define APB2PERIPHERAL_BASE (PERIPHERAL_BASE+0x10000) //定义APB2总线地址
#define AHBPERIPHERAL_BASE (PERIPHERAL_BASE+0x20000) //定义AHB总线地址

//寄存器映射
#define RCC_BASE (AHBPERIPHERAL_BASE+0x1000) //RCC寄存器地址
#define GPIOB_BASE (APB2PERIPHERAL_BASE+0x0C00) //GPIOB地址

//端口寄存器映射
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18) //APB2ENR寄存器地址并转化为指针

#define GPIOB_CRL *(unsigned int*)(GPIOB_BASE+0x00) //GPIOB_CRL寄存器地址并转化为指针
#define GPIOB_CRH *(unsigned int*)(GPIOB_BASE+0x04) //GPIOB_CRH寄存器地址并转化为指针
#define GPIOB_IDR *(unsigned int*)(GPIOB_BASE+0x08) //GPIOB_IDR寄存器地址并转化为指针
#define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C) //GPIOB_ODR寄存器地址并转化为指针
#define GPIOB_BSRR *(unsigned int*)(GPIOB_BASE+0x10) //GPIOB_BSRR寄存器地址并转化为指针
#define GPIOB_BRR *(unsigned int*)(GPIOB_BASE+0x14) //GPIOB_BRR寄存器地址并转化为指针
#define GPIOB_LCKR *(unsigned int*)(GPIOB_BASE+0x18) //GPIOB_LCKR寄存器地址并转化为指针

#endif // __stm32f10x_h__

       此方法通过头文件宏定义的方式,利用地址间的运算关系,将寄存器的名称与地址一一对应。这样可以通过寄存器名称对寄存器进行操作,加强了代码的可读性。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐