当前位置:首页 > 单片机 > 单片机
[导读]一直都是用STM32做项目中的主控芯片,在编程的时候,之前一直忽视了一个问题,那就是寄存器的位置是如何定义的,为什么用一个USART1->CR操作就能够给这个CR寄存器赋值?其实这是一个比较底层的问题,不懂这方面的知识

一直都是用STM32做项目中的主控芯片,在编程的时候,之前一直忽视了一个问题,那就是寄存器的位置是如何定义的,为什么用一个USART1->CR操作就能够给这个CR寄存器赋值?其实这是一个比较底层的问题,不懂这方面的知识也并不影响使用STM32,因为底层的定义工作,厂家一般都会做好,但是多了解一点原理性的东西,对自己还是很有帮助的。

这里我就以STM32F407的USART寄存器为例,介绍一下ST厂家是如何做寄存器定义的。

首先在stm32f4xx.h中


typedefstruct

{

__IOuint16_tSR;/*!

uint16_tRESERVED0;/*!

__IOuint16_tDR;/*!

uint16_tRESERVED1;/*!

__IOuint16_tBRR;/*!

uint16_tRESERVED2;/*!

__IOuint16_tCR1;/*!

uint16_tRESERVED3;/*!

__IOuint16_tCR2;/*!

uint16_tRESERVED4;/*!

__IOuint16_tCR3;/*!

uint16_tRESERVED5;/*!

__IOuint16_tGTPR;/*!

uint16_tRESERVED6;/*!

}USART_TypeDef;

这是因为USART的寄存器组包括SR,DR,BRR,CR1,CR2,CR3,GPTR这几个寄存器,所以用一个USART_TypeDef结构体包含这些寄存器。如果在别的程序中用到这些寄存器,只需要如下:


USART_TypeDefUSART1//任意取名,尽量与Datasheet中给出的名字一致便于理解

USART1.SR=0x00000001;

或者


USART_TypeDef*USART1

USART1->SR=0x00000001;


(*USART1).SR=0x00000011;


那么具体到各个寄存器的位置到底是怎样的呢?从Datasheet和reference manual中可以看到

USART2属于APB1管理的外设,起始地址是0x4000 4400,STM32上所有的外设的基地址都是0x4000 0000(这其实是ARM公司规定的),这也是APB1的起始地址,然后USART2的起始地址在APB1外设基地址的基础上偏移0x4400,于是便可以按照下面代码来分配各个外设的起始地址了


#definePERIPH_BASE((uint32_t)0x40000000)

/*!

/*!

#defineAPB1PERIPH_BASEPERIPH_BASE

#defineUSART2_BASE(APB1PERIPH_BASE+0x4400)

#defineUSART3_BASE(APB1PERIPH_BASE+0x4800)

#defineUART4_BASE(APB1PERIPH_BASE+0x4C00)

#defineUART5_BASE(APB1PERIPH_BASE+0x5000)

#defineUSART2((USART_TypeDef*)USART2_BASE)

#defineUSART3((USART_TypeDef*)USART3_BASE)

#defineUART4((USART_TypeDef*)UART4_BASE)

#defineUART5((USART_TypeDef*)UART5_BASE)

有了这些外设的基地址,加上上面提到的寄存器结构体,便可以操作各个寄存器了,例如,只需要如下语句,便可以使能USART2


USART_Cmd(USART2,ENABLE);

USART_Cmd这是ST官方给出的库函数,具体定义如下


voidUSART_Cmd(USART_TypeDef*USARTx,FunctionalStateNewState)

{

/*Checktheparameters*/

assert_param(IS_USART_ALL_PERIPH(USARTx));

assert_param(IS_FUNCTIONAL_STATE(NewState));

if(NewState!=DISABLE)

{

/*EnabletheselectedUSARTbysettingtheUEbitintheCR1register*/

USARTx->CR1|=USART_CR1_UE;

}

else

{

/*DisabletheselectedUSARTbyclearingtheUEbitintheCR1register*/

USARTx->CR1&=(uint16_t)~((uint16_t)USART_CR1_UE);

}

}

如果理解了上述所讲的内容,你会发现,这种通过结构体定义寄存器的方法非常常见,这是因为现在的处理器,各种寄存器相当多(成百上千),如果按照传统的定义方法去操作寄存器,会相当的麻烦。不只是STM32,我知道的有TI的C2000系列DSP,NXP的ARM系列MCU,瑞萨的ARM R4 RZ/T1处理器都是按这样的方法来定义寄存器。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式开发中,STM32的时钟系统因其灵活性和复杂性成为开发者关注的焦点。然而,看似简单的时钟配置背后,隐藏着诸多易被忽视的陷阱,轻则导致系统不稳定,重则引发硬件损坏。本文从时钟源选择、PLL配置、总线时钟分配等关键环...

关键字: STM32 时钟系统

在嵌入式系统开发中,STM32系列微控制器的内部温度传感器因其低成本、高集成度特性,广泛应用于设备自检、环境监测等场景。然而,受芯片工艺差异和电源噪声影响,其原始数据存在±1.5℃的固有误差。本文从硬件配置、校准算法、软...

关键字: STM32 温度传感器

在能源效率与智能化需求双重驱动下,AC-DC转换器的数字控制技术正经历从传统模拟方案向全数字架构的深刻变革。基于STM32微控制器的PFM(脉冲频率调制)+PWM(脉冲宽度调制)混合调制策略,结合动态电压调整(Dynam...

关键字: AC-DC STM32

当前智能家居产品需求不断增长 ,在这一背景下 ,对现有浇花装置缺陷进行了改进 ,设计出基于STM32单片机的全 自动家用浇花机器人。该设计主要由机械结构和控制系统构成 ,机械结构通过麦克纳姆轮底盘与喷洒装置的结合实现机器...

关键字: STM32 麦克纳姆轮 安全可靠 通过性强

用c++编程似乎是让你的Arduino项目起步的障碍吗?您想要一种更直观的微控制器编程方式吗?那你需要了解一下Visuino!这个图形化编程平台将复杂电子项目的创建变成了拖动和连接块的简单任务。在本文中,我们将带您完成使...

关键字: Visuino Arduino ESP32 STM32

基于STM32与LoRa技术的无线传感网络凭借其低功耗、广覆盖、抗干扰等特性,成为环境监测、工业自动化等场景的核心解决方案。然而,如何在复杂电磁环境中实现高效休眠调度与动态信道优化,成为提升网络能效与可靠性的关键挑战。本...

关键字: STM32 LoRa

在实时控制系统、高速通信协议处理及高精度数据采集等对时间敏感的应用场景中,中断响应延迟的优化直接决定了系统的可靠性与性能上限。STM32系列微控制器凭借其灵活的嵌套向量中断控制器(NVIC)、多通道直接内存访问(DMA)...

关键字: STM32 DMA

数字电源技术向高功率密度、高效率与高动态响应方向加速演进,STM32微控制器凭借其基于DSP库的算法加速能力与对LLC谐振变换器的精准控制架构,成为优化电源动态性能的核心平台。相较于传统模拟控制或通用型数字控制器,STM...

关键字: STM32 数字电源

STM32微控制器凭借其针对电机控制场景的深度优化,成为高精度、高可靠性驱动系统的核心选择。相较于通用型MCU,STM32在电机控制领域的核心优势集中体现在FOC(磁场定向控制)算法的硬件加速引擎与PWM死区时间的动态补...

关键字: STM32 电机控制

无线充电技术加速渗透消费电子与汽车电子领域,基于Qi协议的无线充电发射端开发成为智能设备能量补给的核心课题。传统模拟控制方案存在响应滞后、参数调整困难等问题,而基于STM32的数字PID控制结合FOD(Foreign O...

关键字: STM32 无线充电
关闭