首先我们知道指针在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端口进行操作了