【对于寄存器地址和指针的关系】

首先我们知道指针在C语言是一个核心内容,那么我们是怎么通过指针来操控单片机的呢?单片机就是一个寄存器,那么我们以51单片机为来说,51单片机的P0端口的地址是0X80,我们就需要控制0X80的位置,首先在keil中不支持指针对51单片机操作,所以这里引入了汇编的sfr和sbit,sfr这个指令是控制一个8位的寄存器地址,sbit是控制一位地址

sfr P0 = 0X80;

int main(void)
{
	P0 = 0XFE;
	while(1);
}
这样就达到了实现控制P0口的寄存器的效果,但是如果我们
利用指针该怎么做呢?这里举个例,51是不能用指针的不知
道为什么是不能用指针操作的
#define P0 ((volatile unsigned char*)(0X80))

int main(void)
{
	P0 = 0XFE;
	while(1);
}

我们用volatile关键字修饰,为了防止编译器对这段代码进行优化,unsignd char是一个8位数据,
这里因为51单片机的寄存器是8位,这样也能实现对寄存器的操作,但是可能是编译器的原因51单片机不能这么使用,但是STM32单片机可以,这里我们已经对指针操作寄存器有所了解了,那么下面我就用STM32正式写一个寄存器操作单片机的代码

/* 
	我们发现这几个寄存器之间的地址偏移量刚好是4
	对应着32位数据的地址在结构体中的偏移量,那么
	我们正好用一个结构体来定义IO控制
*/
typedef struct
{
  volatile uint32_t CRL;
  volatile  uint32_t CRH;
  volatile uint32_t IDR;
  volatile uint32_t ODR;
  volatile uint32_t BSRR;
  volatile uint32_t BRR;
  volatile uint32_t LCKR;
} GPIO_TypeDef;

/* 这里0X0X40010800是GPIOA的寄存器地址 */

#define GPIOA ((GPIO_TypeDef*)((uint32_t)(0X40010800)))
/* RCC时钟的结构体 */
typedef struct
{
  volatile uint32_t CR;
  volatile uint32_t CFGR;
  volatile uint32_t CIR;
  volatile uint32_t APB2RSTR;
  volatile uint32_t APB1RSTR;
  volatile uint32_t AHBENR;
  volatile uint32_t APB2ENR;
  volatile uint32_t APB1ENR;
  volatile uint32_t BDCR;
  volatile uint32_t CSR;
} RCC_TypeDef;

/* RCC时钟地址映射 */
#define RCC ((RCC_TypeDef*)((uint32_t)(0x4000030000)))

这样以后我们就可以用这两个结构体对GPIOA端口进行操作了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值