当前位置:首页 > stm32笔记
view sourceprint?
01./* BYTE Registers */ 02.
03.sfr P0 = 0x80; 04.
05.sfr P1 = 0x90; 06.
07.sfr P2 = 0xA0; 08.
09.sfr P3 = 0xB0; 10.
11.sfr PSW = 0xD0; 12.
13.sfr ACC = 0xE0; 14.
15.sfr B = 0xF0; 16.
17.sfr SP = 0x81; 18.
19.sfr DPL = 0x82; 20.
21.sfr DPH = 0x83; 22.
23.sfr PCON = 0x87; 24.
25.sfr TCON = 0x88; 26.
27.sfr TMOD = 0x89; 28.
29.sfr TL0 = 0x8A; 30.
31.sfr TL1 = 0x8B; 32.
33.sfr TH0 = 0x8C; 34.
35.sfr TH1 = 0x8D; 36.
37.sfr IE = 0xA8; 38.
39.sfr IP = 0xB8; 40.
41.sfr SCON = 0x98; 42.
43.sfr SBUF = 0x99;
这些定义被称为地址映射。
所谓地址映射,就是将芯片上的存储器甚至I/O等资源与地址建立一一对应的关系。如果某地址对应着某寄存器,我们就可以运用c语言的指针来寻址并修改这个地址上的内容,从而实现修改该寄存器的内容。
正是因为
Cortex-M3的地址映射也是类似的。Cortex-M3有32根地址线,所以它的寻址空间大小为2^32 bit=4GB。ARM公司设计时,预先把这4GB的寻址空间大致地分配好了。它把地址从0x4000 0000至0x5FFF FFFF( 512MB )的地址分配给片上外设。通过把片上外设的寄存器映射到这个地址区,就可以简单地以访问内存的方式,访问这些外设的寄存器,从而控制外设的工作。结果,片上外设可以使用 C 语言来操作。M3存储器映射见图 5-7
图 5-7
stm32f10x.h这个文件中重要的内容就是把STM32的所有寄存器进行地址映射。如同51单片机的
不进行这些宏定义的缺点有: 1、地址容易写错
2、我们需要查大量的手册来确定哪个地址对应哪个寄存器
3、看起来还不好看,且容易造成编程的错误,效率低,影响开发进度。
当然,这些工作都是由ST的固件工程师来完成的,只有设计M3的人才是最了解M3的,才能写出完美的库。
在这里我们以外接了LED灯的外设GPIOC为例,在这个文件中有这样的一系列宏定义:
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define PERIPH_BASE ((uint32_t)0x40000000)
这几个宏定义是从文件中的几个部分抽离出来的,具体的读者可参考stm32f10x.h源码。
外设基地址
首先看到PERIPH_BASE这个宏,宏展开为0x4000 0000,并把它强制转换为uint32_t的32位类型数据,这是因为地STM32的地址是32位的,是不是觉得0x4000 0000这个地址很熟?是的,这个是Cortex-M3核分配给片上外设的从0x4000 0000至0x5FFF FFFF的512MB寻址空间中的第一个地址,我们把0x4000 0000称为外设基地址。
总线基地址
接下来是宏APB2PERIPH_BASE,宏展开为PERIPH_BASE(外设基地址)加上偏移地址0x1 0000,即指向的地址为0x4001 0000。这个APB2PERIPH_BASE宏是什么地址呢?STM32不同的外设是挂载在不同的总线上的,见图 5-8。有AHB总线、APB2总线、APB1总线,挂载在这些总线上的外设有特定的地址范围。
图 5-8
其中像GPIO、串口1、ADC及部分定时器是挂载这个被称为APB2的总线上,挂载到APB2总线上的外设地址空间是从0x4001 0000至地址0x4001 3FFF。这里的第一个地址,也就是0x4001 0000,被称为APB2PERIPH_BASE (APB2总线外设的基地址)。
而APB2总线基地址相对于外设基地址的偏移量为0x1 0000个地址,即为APB2相对外设基地址的偏移地址。
见表:
由这个表我们可以知道,stm32f10x.h这个文件中必然还有以下的宏: #define APB1PERIPH_BASE PERIPH_BASE 因为偏移量为零,所以APB1的地址直接就等于外设基地址 寄存器组基地址
最后到了宏GPIOC_BASE,宏展开为APB2PERIPH_BASE (APB2总线外设的基地址)加上相对APB2总线基地址的偏移量0x1000得到了GPIOC端口的寄存器组的基地址。这个所谓的寄存器组又是什么呢?它包括什么寄存器?
细看stm32f10x.h文件,我们还可以发现以下类似的宏: #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) #define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
除了GPIOC寄存器组的地址,还有GPIOA、GPIOB、GPIOD的地址,并且这些地址是不一样的。
前面提到,每组GPIO都对应着独立的一组寄存器,查看stm32的datasheet,看到寄存器说明如下图:
共分享92篇相关文档