阿尔法点亮LED灯(三) STM32模式


前言


提示:以下是本篇文章正文内容

一、原理分析

前面用C语言编写 LED 灯驱动的时候,每个寄存器的地址都需要写宏定义,这样做实在是太麻烦了,在STM32中,比如访问GPIOB 的寄存器 ODR :GPIOB->ODR

我们也可以参照32的形式将某个外设的所有寄存器写入到一个结构体里面,定义一个结构体指针指向外设的寄存器基地址,这样就可以通过这个结构体指针来访问这个外设的所有寄存器,因为在结构体中成员地址递增,并且属于同一个外设的寄存器地址基本上是相邻的(有些是保留寄存器)

在32中使用寄存器操作GPIO

GPIOE->CRL&=0XFF0FFFFF;
GPIOE->CRL|=0X00300000; //PE5 推挽输出
GPIOE->ODR|=1<<5; //PE5 输出高

需要配置GPIOE结构体指针的寄存器 CRL 和 ODR

GPIOE的宏定义:

#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)

GPIOE是一个指向地址GPIOE_BASE 的结构体指针,结构体为GPIO_TypeDef

GPIO_TypeDef结构体如下

typedef struct
{
    
    
	__IO uint32_t CRL;
	__IO uint32_t CRH;
	__IO uint32_t IDR;
	__IO uint32_t ODR;
	__IO uint32_t BSRR;
	__IO uint32_t BRR;
	__IO uint32_t LCKR;
} GPIO_TypeDef;

注:_IO是宏定义 一般是volatile修饰符

GPIO_TypeDef 结构体的成员变量有 CRL、 CRH、 IDR、 ODR,BSRR、 BRR 和 LCKR,都是 GPIO 的寄存器

每个成员变量都是 32 位(4 字节),寄存器在结构体中的位置都是按照其地址值从小到大排序的

结构体的地址的定义

#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define PERIPH_BASE ((uint32_t)0x40000000)

GPIOE_BASE 就是 GPIOE 的基地址,GPIOE指针指向这个地址,每个寄存器之间相隔4个字节,只要设置好了基地址就可以访问到结构体成员

二、MX6U寄存器定义

1.外设结构体

将同属于一个外设的所有寄存器定义到一个结构体里面

eg: 定义GPIO外设寄存器组
在这里插入图片描述
参考如下:

typedef struct 
{
    
    
	volatile unsigned int DR;							
	volatile unsigned int GDIR; 							
	volatile unsigned int PSR;								
	volatile unsigned int ICR1; 							
	volatile unsigned int ICR2; 							 
	volatile unsigned int IMR;								 
	volatile unsigned int ISR;			
	volatile unsigned int EDGE_SEL;  
}GPIO_Type;

注:每个成员都使用“volatile”进行了修饰,目的是防止编译器优化

如果某个寄存器组中中间地址不连续需要将地址保留出来
eg:
在这里插入图片描述
在这里插入图片描述
在时钟外设寄存器组中,CCM_CCGR6和CCM_CMEOR寄存器之间相差了8个字节,我们必须将空的四个字节地址留出来,如果不添加保留位来占位的话就会导致寄存器地址错位

volatile unsigned int CCGR6;
volatile unsigned int RESERVED_3[1]; 
volatile unsigned int CMEOR;	

RESERVED_3[1]就是预留出来的空间,保证了结构体地址连续递增的特点

2.结构体基地址

定义结构体寄存器组的基地址,也就是结构体中第一个成员变量

在这里插入图片描述
对于GPIO1结构体而言其基地址为:0X0209C000

#define GPIO1_BASE                  (0x0209C000)

3.结构体访问指针

定义访问结构体的指针,就可以通过该指针实现对寄存器组的操作,将结构体的基地址强制转换为结构体类型的指针

#define GPIO1				((GPIO_Type *)GPIO1_BASE)

我们就可以通过GPIO1->GDIR访问寄存器

三、编译下载

基本上和前一节的一样,Makefile和链接脚本都一样。


总结

提示:这里对文章进行总结:

猜你喜欢

转载自blog.csdn.net/qq_53144843/article/details/121580773
今日推荐