#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)
上述代码中我们在后面备注了数字,下面对其进行简单介绍下其功能:
1)定义外设的基地址,这个地址也是Block2 的基地址。

2)定义APB2 总线基地址,因为Block2 的第一个总线是APB1,而APB2 总
线地址只需要加上对应的地址偏移量即可。
3)定义GPIO 外设基地址,因为GPIOC 是挂接在APB2 总线上的,所以找到
对应的端口地址偏移量即可知道GPIOC 端口基地址。
4)定义GPIO 外设寄存器基地址,这里以GPIOC 端口为例,因为GPIOC_CRL
是GPIOC 外设的第一个寄存器,所以基地址就是GPIOC 地址,其他寄存器地址只
需要在GPIOC 基地址上加上相应的偏移量即可。
我们得到了寄存器具体的地址,那么就可以使用C 语言指针来操作读写。例
如我们需要GPIOC0 输出一个低电平或者高电平,可以使用下面语句来操作。
//控制GPIOC 第0 管脚输出一个低电平
GPIOC_BSRR = (0x01<<(16+0));
//控制GPIOC 第0 管脚输出一个高电平
GPIOC_BSRR = (0x01<<0);
我们知道GPIOC_BSRR 的值是这个寄存器的地址,但是编译器不知道它是地
址,而是把它当做立即数,所以我们必须要强制转换为(unsigned int *)指针
类型才可以对其操作,这一点特别要注意。然后再在前面加上一个“*”作取指
针操作,表示对该地址内内容进行写,读操作也同样使用“*”取指针操作。如
下:
unsigned int temp;
temp =GPIOC_IDR;
将寄存器内的数据保存在变量temp 中,使用到变量时一定要进行定义。
寄存器封装
通过前面讲解,我们已经可以对寄存器进行操作,但是还稍有不足,因为
STM32 的GPIO 比较多,我们不可能每使用一个GPIO 都做前面一样的一大堆定义。
根据GPIO 寄存器的特点,我们知道不论GPIOA 还是GPIOB 等都拥有一组功能相
同的寄存器,如GPIOA_ODR/GPIOB_ODR/GPIOC_ODR 等等,它们只是地址不一样。
为了更方便地访问寄存器,我们引入C 语言中的结构体对寄存器进行封装,具
体代码如下:
typedef unsigned int uint32_t; /*无符号32 位变量*/
typedef unsigned short int uint16_t; /*无符号16 位变量*/
/* GPIO 寄存器列表*/
typedef struct
{
uint32_t CRL; /*GPIO 端口配置低寄存器地址偏移: 0x00 */
uint32_t CRH; /*GPIO 端口配置高寄存器地址偏移: 0x04 */
uint32_t IDR; /*GPIO 数据输入寄存器地址偏移: 0x08 */
uint32_t ODR; /*GPIO 数据输出寄存器地址偏移: 0x0C */
uint32_t BSRR; /*GPIO 位设置/清除寄存器地址偏移: 0x10 */
uint32_t BRR; /*GPIO 端口位清除寄存器地址偏移: 0x14 */
普中STM32F1xx 开发攻略
43
uint16_t LCKR; /*GPIO 端口配置锁定寄存器地址偏移: 0x18 */
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-66178-4.html
还好输了