第3章 存储器与寄存器介绍
1.什么是存储器映射
2.什么是寄存器及寄存器映射
3.如何访问STM32寄存器内容
1.什么是存储器映射
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程称为存储器映射,如果再分配一个地址就叫重映射(具体地址分配参考芯片数据手册及中文参考手册)
2.什么是寄存器及寄存器映射
通过给有特定功能的内存单元起一个别名,这个别名就是我们所说的寄存器。给已经分配好地址的有特定功能的内存单元起别名的过程就叫寄存器映射。
3.如何访问STM32寄存器内容
我们知道寄存器就是一些有特定功能的内存单元,所以要访问STM32寄存器也就是操作STM32的内存单元,根据C语言指针的特点,可以使用指针来操作STM32的内存单元。
假如我们要让STM32的GPIOF的第9管脚输出低电平,我们怎么使用C语言来处理?
首先我们要知道GPIOF挂接在哪个总线上,需要知道基地址,STM32总线地址如下:
所以使用C语言宏可以定义外设基地址:
#define PERIPH_BASE((unsigned int)0x40000000)
然后分别定义各总线基地址:
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE+0x00010000)
#define APB1PERIPH_BASE (PERIPH_BASE+0x00020000)
#define AHB2PERIPH_BASE (PERIPH_BASE+0x10000000)
然后还需要知道端口外设地址,
同样使用C语言宏定义其端口地址:
#define GPIOA_BASE (AHB1PERIPH_BASE+0x0000)
#define GPIOB_BASE (AHB1PERIPH_BASE+0x0400)
#define GPIOC_BASE (AHB1PERIPH_BASE+0x0800)
#define GPIOD_BASE (AHB1PERIPH_BASE+0x0C00)
#define GPIOE_BASE (AHB1PERIPH_BASE+0x1000)
#define GPIOF_BASE (AHB1PERIPH_BASE+0x1400)
#define GPIOG_BASE (AHB1PERIPH_BASE+0x1800)
#define GPIOH_BASE (AHB1PERIPH_BASE+0x1C00)
有了外设端口地址后,还需要知道GPIOF端口的寄存地址,如下表格:
同样使用C语言宏定义其端口寄存器地址:
#define GPIOF_MODER(GPIOF_BASE+0x00)
#define GPIOF_OTYPER(GPIOF_BASE+0x04)
#define GPIOF_OSPEEDR(GPIOF_BASE+0x08)
#define GPIOF_PUPDR(GPIOF_BASE+0x0C)
#define GPIOF_IDR(GPIOF_BASE+0x10)
#define GPIOF_ODR(GPIOF_BASE+0x14)
#define GPIOF_BSRR(GPIOF_BASE+0x18)
#define GPIOF_LCKR(GPIOF_BASE+0x1C)
#define GPIOF_AFRL(GPIOF_BASE+0x20)
#define GPIOF_AFRH(GPIOF_BASE+0x24)
这些寄存器具体的功能可以参考STM32F4中文参考手册。
控制GPIOF引脚9输出低电平(即通过BSRR寄存器的BR9置1)即:
*(unsigned int *)GPIOF_BSRR=(0x01<<(16+9));
控制GPIOF引脚9输出高电平(即通过BSRR寄存器的BS9置1)
*(unsigned int *)GPIOF_BSRR=0x01<<9;
读取GPIOF端口所有引脚的电平(读IDR寄存器)
unsigned int temp;
temp=*(unsigned int *)GPIOF_IDR;
我们这里仅仅以GPIO这个外设为例,给大家讲解了如何使用C语言对寄存器封装的,对于其他的外设也是使用同样方法。其实到了后面的实验程序的编写时,我们都是使用ST公司提供的固件库,他把STM32所有外设都已经封装好了,我们这里分析这个封装过程只是想让大家更加清楚理解如何使用C来封装寄存器的。