前面把基础部分讲得差不多,比如说什么是寄存器,寄存器映射,怎么样来寄存器编程,寄存器编程的时候应该参考官方的什么手册,
前面讲了什么是寄存器 怎么使用寄存器编程 寄存器编程的时候应该 参考哪些手册 接下来我们开始利用固件库编程,今天开始从 最底层开始写库函数 《在零死角玩转STM32》 第九章 l利用我们上节课的历程 下面这些是7个GPIO口的寄存器映射我们到GPIO口的寄存器映射,这些是最底层的东西,我们基本上已经学会了,那么接下来我们 进入固件库编程在真正进入固件库编程之前,我们应该了解固件库与寄存器的联系,参考《零死角玩转STM32F103-霸道》第九章 自己写库构建库函数雏形针对霸道 和指南者
上图是我们上节课的历程,是我们对上节课 寄存器的映射,每一个寄存器都实现了寄存器的映射,GPIO口的寄存器有7个,但是如果寄存器多的话,这样的代码要写好多 就不太方便了,那么今天就要来对他进行优化
我们来看一下上图中的寄存器映射,比如说我们要操作GPIOB ,那么就要操作 端口B外设的基地址 :GPIOB_BASE,地址在C语言里就是指针,而且他是32位的,那么他就指向了4个字节的内存,那么我们的 GPIOB_BASE就指向GPIOB的第一个地址,那么如果我们操作 GPIOB_BASE 这个指针,那么他访问的就是CRL这个寄存器,而且我们可以看到这些寄存器都是有规律的分布的,地址都是以4个字节递增,这个就跟C语言当中的结构体是类似的,因此我们在 定义一个结构体,这个结构体也有7个成员,类型叫做 GPIO_Type,我们刚刚说了GPIOB_BASE 是一个32位的通过我们这个指针他只能访问4个字节的内存,那么如果说我们想基于这个地址来访问GPIO的所有寄存器的话,该怎么办呢?如果GPIOB_BASE 这个指针是下图中的GPIO_Type的结构体类型的话,它就可以访问GPIO的所有寄存器的话了,所以说如果我这个指针和外设的基地址是一样的话那我们就可以通过一个结构体的方式访问这个寄存器了,比起上节课讲的每一个寄存器都要找到他的绝对地址这样子要方便很多,那么怎样将我们的GPIO_BASE转化成GPIO_Type这种结构体类型的指针呢? C语言当中有一种 叫强制类型转化
然后再将上面的类型定义成一个宏
那么这个GPIOB可以指向GPIO_Type的所有成员,这里只要GPIO_Type成员的名字对应的实际地址不变那么,那么这个结构体的成员名可以 随便定义
以下的代码中就是通过GPIOB的结构体类型指针去访问他的成员变量,利用->这个 符号就可以指向他的各个成员。
总结;实现结构体方式访问的原理:1.先声明一个结构体,结构体中包含很多成员, 结构体成员的类型与分布的顺序都与我们寄存器的排列方式是一样的(上图8.5中寄存器的排列方式与我们结构体中的排列都是一致的,而且我们每一个寄存器都是u32类型的,与实际的寄存器大小一致,这样就做到了结构体GPIO_Type的成员与外设寄存器的一一对应)
2找到外设的基地址例如是GPIOB_BASE,然后把这个地址强制转化成上面的结构体类型
经过强制类型转换后,它就指向了GPIO_Type这里的所有成员,那么这样我们就可以通过C语言的结构体方式来操作stm32的所有外设。
关键字:STM32 库函数 寄存器 结构体定义
引用地址:
STM32 (5) 自己写库 构建库函数雏形1 寄存器结构体定义
推荐阅读最新更新时间:2024-10-23 11:15
STM32 (5) 自己写库 构建库函数雏形1 寄存器结构体定义
前面把基础部分讲得差不多,比如说什么是寄存器,寄存器映射,怎么样来寄存器编程,寄存器编程的时候应该参考官方的什么手册, 前面讲了什么是寄存器 怎么使用寄存器编程 寄存器编程的时候应该 参考哪些手册 接下来我们开始利用固件库编程,今天开始从 最底层开始写库函数 《在零死角玩转STM32》 第九章 l利用我们上节课的历程 下面这些是7个GPIO口的寄存器映射我们到GPIO口的寄存器映射,这些是最底层的东西,我们基本上已经学会了,那么接下来我们 进入固件库编程在真正进入固件库编程之前,我们应该了解固件库与寄存器的联系,参考《零死角玩转STM32F103-霸道》第九章 自己写库构建库函数雏形针对霸道 和指南者 上图是我们
[单片机]
STM32 (5) 自己写库 构建库函数雏形1 寄存器结构体定义
前面把基础部分讲得差不多,比如说什么是寄存器,寄存器映射,怎么样来寄存器编程,寄存器编程的时候应该参考官方的什么手册, 前面讲了什么是寄存器 怎么使用寄存器编程 寄存器编程的时候应该 参考哪些手册 接下来我们开始利用固件库编程,今天开始从 最底层开始写库函数 《在零死角玩转STM32》 第九章 l利用我们上节课的历程 下面这些是7个GPIO口的寄存器映射我们到GPIO口的寄存器映射,这些是最底层的东西,我们基本上已经学会了,那么接下来我们 进入固件库编程在真正进入固件库编程之前,我们应该了解固件库与寄存器的联系,参考《零死角玩转STM32F103-霸道》第九章 自己写库构建库函数雏形针对霸道 和指南者 上图是我们上
[单片机]
stm32专题十一:USART(三)初始化结构体和标准库函数分析
在之前的博客中分析了stm32串口的结构,和详细的发送、接受过程。现在来分析固件库中对于USART的标准函数 typedef struct { uint32_t USART_BaudRate; // 波特率 uint16_t USART_WordLength; // 帧数据长度(8位还是9位) uint16_t USART_StopBits; // 停止位 uint16_t USART_Parity; // 校验 uint16_t USART_Mode; // 模式:单收、单发或收发 uint16_t USART_HardwareFlowCo
[单片机]
STM32中的结构体是如何组织同类寄存器的
#define PERIPH_BASE ((u32)0x40000000)//端口地址 ?xml:namespace prefix = o ns = urn:schemas-microsoft-com:office:office / #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)//端口地址 #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)//端口地址 #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)// typedef unsigned long u32; typedef volatil
[单片机]
STM32外设结构体定义和时钟初始化语句顺序导致编译
1.编写外设初始化函数时候需要定义外设的结构体,以及初始化外设时钟等 但是今天偶然间把代码语句写反了,然后编译不通过,提示错误信息为:dac.c(41): error: #268: declaration may not appear after executable statement in block DAC_InitTypeDef DAC_InitStructure;这个错误提示之前一篇博文也出现过,但是原因好像不是这个,还是贴出来作为经验吧。 void DAC_Mode_Config(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); DAC_In
[单片机]
STM32采用结构体定义FSMC的地址
LCD地址设置 图中只画出了数据线与地址线 其他的线我没有花,请各位脑部一下,实在不行去看原子提供的LCD的原理图。 LCD有一个引脚是D/C引脚,用来区分往LCD中写入的数据是命令还是数据Data/Command 比如说我要给LCD控制器的X寄存器写入数据Y 那么我需要先给LCD发送一个命令----X寄存器的地址,此时D/C引脚为低电平 然后再发送一个数据Y,此时D/C引脚为高电平。但是正常的FSMC总线中没有控制命令与数据的功能(或许我不知道)。 正常的FSMC是绝对地址寻址。也就是需要硬件地址线A0-AX(X为地址的长度)去控制。 所以STM32使用了一根地址线不是说往LCD控制的的某个地址写入数据。而是用这一
[单片机]
STM32 结构体定义地址对齐
在MDK下定义一个结构体,对一段报文,强制转换为结构体类型,实际运行地址错位。 Heartbeat_Message *tmp_Heartbeat; tmp_Heartbeat=(Heartbeat_Message *) &sen_dma_tmpbuf ; typedef struct { uint16_t Sync; uint16_t Packet_Length; uint8_t ID ; uint8_t Frame_Type; uint8_t Packet_Type; uint32_t time; uint16_t CRC16; }Heartbeat_Message;
[单片机]
STM32F103VET6——ADC库函数结构体
结构体 typedef struct { uint32_t ADC_Mode; /*! Configures the ADC to operate in independent or dual mode. This parameter can be a value of @ref ADC_mode */ FunctionalState ADC_ScanConvMode; /*! Specifies whether the conversion is performed in
[单片机]