C语言对寄存器封装

来源:互联网 发布:ftp服务器软件 se 编辑:程序博客网 时间:2024/05/08 04:58

一、封装外设
用C语言代码把外设地址映射用宏定义封装

/* 外设基地址 */#define  PERIPH_BASE    ((unsigned int)0x40000000)/* 总线基地址 */#define APB1PERIPH_BASE   PERIPH_BASE#define APB2PERIPH_BASE   (PERIPH_BASE + Ox00010000)../* GPIO外设基地址 */#define GPIOA_BASE     (AHB1PERIPH_BASE + 0x0000)#defien GPIOB_BAAE     (AHB1PERIPH_BASE + 0x0400)../* 寄存器基地址,以GPIOA为例 */#define GPIOA_MODER    (GPIOA_BASE+0x00)#define GPIOA_OTYPER   (GPIOA_BASE+0x04)..

总结:定义“片上外设”基地址PERIPH_BASE,接着在PERIPH_BASE上加上各个总线的地址偏移,得到总线的相应地址,然后在加上各寄存器的地址偏移就得到特定寄存器的地址。

二、封装寄存器

typedef unsigned          int uint32_t;   //无符号32位变量typedef unsigned short    int uint16_t;   //无符号16位变量/* GPIO寄存器列表 */typedef struct{    uint32_t MODER;       /*GPIO模式寄存器      地址偏移:0x00*/    uint32_t OTYPER;      /*GPIO输出类型寄存器   地址偏移:0x04*/    uint32_t OSPEEDR;     /*GPIO输出速度寄存器   地址偏移:0x08*/    uint32_t PUPDR;       /*GPIO上拉/下拉寄存器  地址偏移:0x0C*/    .    .    .}GPIO_TypeDef;

上面这段代码用typedef关键字声明了名为 GPIO_TypeDef的结构体类型。

使用宏定义定义各个GPIO端口的首地址

/* 使用GPIO_TypeDef把地址强制转换成指针 */#define GPIOA              ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB              ((GPIO_TypeDef *) GPIOB_BASE)../* 使用定义好评的宏直接访问 *//* 访问GPIOA端口的寄存器*/GPIOA->BSRRL = 0XFFFF;    //通过指针访问并修改GPIOA_BSRRL寄存器GPIOA->MODER = OxFFFFFFF; //修改GPIOA_MODER寄存器

总结:用结构体封装一类寄存器,然后强制转换成指针,通过宏定义执行端口基地址,再加上相应的偏移地址就可以直接访问相应的寄存器。

修改寄存器的某一位
在51单片机中通过关键字sbit来实现位定义,但是M4中没有这个关键字。下面先说说C语言如何操作某一位。
1、把变量的某位清零

//定义一个变量a = 1001 1111b (二进制)unsigned char a = 0x9F;//对bit2清零a  &= ~(1<<2);//括号中的1左移两位,(1<<2)得二进制:0000 0100b//按位取反,~(1<<2)得1111 1011b//假如a中原来的值为二进制:a=1001 1111b//所有的数与a作“位与&”运算,a=(1001 1111b) & (1111 1011b)//运算后,a = 1001 1011b

2、把变量的某几个连续位清零

//若把a中的二进制位分为2个一组a &= ~(3<<2*1);//括号中的3左移两位, 然后在取反,得到1111 0011b//然后“位与&”,得到 1001 0011b

这里面涉及到运算符的优先级*的优先级高于<<,所以(3<<2*1)是把3左移3位。
下次在学习M4中的位带操作,因为里面涉及的知识比较多。

0 1
原创粉丝点击