爱球论坛

经过限度体例

STM32入门系列-操纵C语言封装存放器

wangjimima
wangjimima

2017-11-24

后面先容了存储器映射、存放器和存放器映射。

全体实例:限度 GPIOC 端口的第 0 管脚输入一个低电平。足球现场直播。首先我们需要知道GPIOC 端口外设是挂接在哪个总线上的,然后遵照总线基地址和自己的偏移地址取得 GPIOC 外设基地址。

总线和外设基地址封装

遵照存放器的概念。

//定义外设基地址

#define PERIPH_BASE ((unsigned int)0x) 1),足球现场直播。

//定义 APB2 总线基地址

#define APB2PERIPH_BASE (PERIPH_BASE + 0x000) 2),足球现场直播。

//定义 GPIOC 外设基地址

#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) 3),足球直播论坛

//定义存放器基地址 这里以 GPIOC 为例

#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00) 4),足球社区。

#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)

#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08),第一足球网论坛。

#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C),虎扑足球论坛。

#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10),足球社区互动。

#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14),足球现场直播。

#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18),STM32入门系足球现场直播列。

上述代码中我们在背面备注了数字。

·

定义外设的基地址,这个地址也是 Block2 的基地址。

·

·

定义APB2 总线基地址,因为 Block2 的第一个总线是 APB1。操作C谈话封装寄存器。

·

·

定义 GPIO 外设基地址,因为 GPIOC 是挂接在 APB2 总线上的。

·

·

定义GPIO 外设存放器基地址,所以基地址就是 GPIOC 地址,爱球论坛。因GPIOC_CRL是 GPIOC 外设的第一个存放器,这里以 GPIOC 端口为例。

·

我们取得了存放器全体的地址,那么就没关系操纵 C 语言指针来操作读写。足球直播论坛。例如我们需要 GPIOC0 输入一个低电平可能高电平。stm32。

//限度 GPIOC 第 0 管脚输入一个低电平

GPIOC_BSRR = (0x01<<(16+0));

//限度 GPIOC 第 0 管脚输入一个高电平

GPIOC_BSRR = (0x01<<0);

我们知道 GPIOC_BSRR 的值是这个存放器的地址,所以我们必需要逼迫转换为(unsigned int *)指针类型才没关系对其操作,stm。而是把它当做登时数,入门。但是编译器不知道它是地址。嵌入式物联网智能硬件等体例学习企鹅意义气呜呜吧久零就易,然后再在后面加上一个“*”作取指针操作,表示对该地址内形式举办写。

unsigned int temp;

temp =GPIOC_IDR;

将存放器内的数据留存在变量 temp 中。

存放器封装

经由过程后面讲明,如GPIOA_ODR/GPIOB_ODR/GPIOC_ODR等等,我们知道非论GPIOA还是GPIOB等都拥有一组效力肖似的存放器,足球。 我们不可能每操纵一个GPIO都做后面一样的一大堆定义。遵照GPIO存放器的特性,现场直播。因为STM32的GPIO角力计算多,但是还稍有不敷,我们已经没关系对存放器举办操作。

为了更容易地拜谒存放器,我们引入C语言中的布局体对存放器举办封装。操作。

typedef unsigned int uint32_t; /*无符号 32 位变量*/,c。

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 */,直播。

uint16_t LCKR; /*GPIO 端口配置锁定存放器 地址偏移: 0x18 */,论坛。

}GPIO_TypeDef;

这段代码用 typedef 关键字声明了名为GPIO_TypeDef的布局体类型,其中32位的变量占用4个字节,STM32入门系足球现场直播列。布局体内变量的存储空间是一口气的,操作C谈话封装寄存器。变量名正好对应存放器的名字。C 语言的语法正派,布局体内有7 个成员变量。

于是,其它成员变量绝对待布局体首地址的偏移,爱球论坛。正是代表CRH所占用的4个字节地址的偏移量,足球直播论坛。加上的这个0x04,那么布局体中第二个成员变量CRH的地址即为0x4001 1000 +0x04,倘使这个布局体的首地址为0x4001 1000(这也是第一个成员变量 CRL的地址),我们定义的GPIO_TypeDef。

这样的地址偏移与STM32 GPIO外设定义的存放器地址偏移一一对应,比方我们还是将GPIOC0输入低电平,足球。然后就能以布局体的形式拜谒存放器了,现场直播。就能把布局体内成员的地址判断上去,只要给布局体设置好首地址。

GPIO_TypeDef * GPIOx; //定义一个GPIO_TypeDef型布局体指针GPIOx

GPIOx = GPIOC_BASE; //把指针地址设置为宏 GPIOC_BASE 地址

GPIOx->BSRR =(1<<(16+0)); //经由过程指针拜谒并修削 GPIOC_BSRR 存放器

这段代码先用GPIO_TypeDef类型定义一个布局体指针GPIOx,而且指针指向各个GPIO端口的首地址,我们直接操纵宏定义好GPIO_TypeDef类型的指针,用GPIOx->BSRR写存放器。为了操作更简易灵便,然后遵照C语言拜谒布局体的形式,地址判断上去,并让指针指向GPIOC基地址GPIOC_BASE。

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)

#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)

#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)

#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

GPIOC->BSRR = (1<<(16+0));

我们这里仅仅以GPIO这个外设为例,他们把STM32一共外设都已经封装好了,我们都是操纵ST公司提供的固件库,对待其他的外设也是操纵异样步骤。其实到了背面的实验轨范的编写,给公共讲明了如何操纵C语言对存放器封装。


回帖

评论1

总共 , 如今 /
首页 | 登录 | 注册 | 前往顶部↑
手机版 | 电脑版
版权一共 Copyright(C) 2016 CE China