STM32外设寄存器地址定义

发布者:心语乐章最新更新时间:2017-10-30 来源: eefocus关键字:STM32  外设寄存器  地址定义 手机看文章 扫描二维码
随时随地手机看文章

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

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

首先在stm32f4xx.h中


  1. typedef struct  

  2. {  

  3.   __IO uint16_t SR;         /*!< USART Status register,                   Address offset: 0x00 */  

  4.   uint16_t      RESERVED0;  /*!< Reserved, 0x02                                                */  

  5.   __IO uint16_t DR;         /*!< USART Data register,                     Address offset: 0x04 */  

  6.   uint16_t      RESERVED1;  /*!< Reserved, 0x06                                                */  

  7.   __IO uint16_t BRR;        /*!< USART Baud rate register,                Address offset: 0x08 */  

  8.   uint16_t      RESERVED2;  /*!< Reserved, 0x0A                                                */  

  9.   __IO uint16_t CR1;        /*!< USART Control register 1,                Address offset: 0x0C */  

  10.   uint16_t      RESERVED3;  /*!< Reserved, 0x0E                                                */  

  11.   __IO uint16_t CR2;        /*!< USART Control register 2,                Address offset: 0x10 */  

  12.   uint16_t      RESERVED4;  /*!< Reserved, 0x12                                                */  

  13.   __IO uint16_t CR3;        /*!< USART Control register 3,                Address offset: 0x14 */  

  14.   uint16_t      RESERVED5;  /*!< Reserved, 0x16                                                */  

  15.   __IO uint16_t GTPR;       /*!< USART Guard time and prescaler register, Address offset: 0x18 */  

  16.   uint16_t      RESERVED6;  /*!< Reserved, 0x1A                                                */  

  17. } USART_TypeDef;  

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


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

  2. USART1.SR = 0x0000 0001;  

或者 


  1. USART_TypeDef*   USART1  

  2. USART1->SR = 0x0000 0001;  


  1. (*USART1).SR = 0x0000 0011;  


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

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


  1. #define PERIPH_BASE           ((uint32_t)0x40000000)  

  2. /*!< Peripheral base address in the alias region*/  

  3.    

  4. /*!< Peripheral memory map */  

  5. #define APB1PERIPH_BASE       PERIPH_BASE  

  6.    

  7. #define USART2_BASE           (APB1PERIPH_BASE + 0x4400)  

  8. #define USART3_BASE           (APB1PERIPH_BASE + 0x4800)  

  9. #define UART4_BASE            (APB1PERIPH_BASE + 0x4C00)  

  10. #define UART5_BASE            (APB1PERIPH_BASE + 0x5000)  

  11.    

  12. #define USART2              ((USART_TypeDef *) USART2_BASE)  

  13. #define USART3              ((USART_TypeDef *) USART3_BASE)  

  14. #define UART4               ((USART_TypeDef *) UART4_BASE)  

  15. #define UART5               ((USART_TypeDef *) UART5_BASE)  

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


  1. USART_Cmd(USART2, ENABLE);  

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


  1. void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)  

  2. {  

  3.   /* Check the parameters */  

  4.   assert_param(IS_USART_ALL_PERIPH(USARTx));  

  5.   assert_param(IS_FUNCTIONAL_STATE(NewState));  

  6.     

  7.   if (NewState != DISABLE)  

  8.   {  

  9.     /* Enable the selected USART by setting the UE bit in the CR1 register */  

  10.     USARTx->CR1 |= USART_CR1_UE;  

  11.   }  

  12.   else  

  13.   {  

  14.     /* Disable the selected USART by clearing the UE bit in the CR1 register */  

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

  16.   }  

  17. }  

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


关键字:STM32  外设寄存器  地址定义 引用地址:STM32外设寄存器地址定义

上一篇:STM32F407 单通道ADC采样,DMA传输
下一篇:关于STM32的USART的使用(一)--- 初始化过程

推荐阅读最新更新时间:2024-03-16 15:42

STM32使用SWD连接报错总结
使用SWD通过J-Flash烧写STM32时,会出现各式各样的错误; 总结下原因: 1、复位脚被拉低了,这次我遇到的就是复位引脚的电容焊反了(钽电容),可以正常连接,但是烧写程序时会出现如下报错 – - Erasing affected sectors … - ERROR: RAM check failed @ address 0x20000000. - ERROR: Write: 0x03020100 07060504 - ERROR: Read: 0x00000000 00000000 - ERROR: (0 bytes of RAM have been checked successfully) - ERROR: Fail
[单片机]
STM32串口USART通讯
1. USART和UART USART(Universal Synchronous Asynchronous Receiver and Transmitter)即通用同步异步收发器,它是一个串行通信设备,与外部设备可灵活进行全双工数据交换。在这之前我们常用到的是UART(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能,只有异步通信。区分同步和异步最简单的方法就是看通信时需不需要对外提供时钟输出,我们平时使用的串口通信基本都是UART。关于串口通信其他基本概念,在上一篇文章http://blog.csdn.net/qq_29344757
[单片机]
<font color='red'>STM32</font>串口USART通讯
STM32的USB多包数据传送
SMT32F103,根据例程 Custom_HID 修改,利用 EP1 以 EP_INTERRUPT 的方式发送包,原来的例程每次发送 2 个字节,现在修改后包的长度不超过 64 字节时发送是正常的,但当一个包长超过 64 字节时就发送失败,没有数据出来(程序没有死机),该改的地方都已经修改了,不知道哪个地方还没有改到位,谢谢! 现象就是超过63字节的包死活也发不出去,而且发送包的大小还与 CustomHID_ConfigDescriptor 里面的EP1 IN endpoint描述里包大小有关,没道理啊,其他的MCU这地方设置为8 照样发送 256B以上的包。 在 Custom_HID 例程上修改了如下代码: 1
[单片机]
stm32学习笔记(九)PWM输出
#include pwm.h #include led.h ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK Mini STM32开发板 //PWM 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2010/12/03 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 正点原子 2009-2019 //All rights reserved
[单片机]
意法半导体发布STM32C0系列MCU 让成本敏感的8位应用也能享受32 位性能
意法半导体发布STM32C0系列MCU 让成本敏感的8位应用也能享受32 位性能 STM32系列高性价比入门级产品,现已量产并发货,享受 10 年产品寿命保障 2023年1月31日,中国 ---- 服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST;)推出迄今为止STM32 微控制器 (MCU)产品家族中性价比最高的STM32C0系列产品,为开发者降低STM32入门门槛 。 全球已有数十亿个智能工业、医疗和消费产品采用 STM32 MCU 。STM32现有产品型号达数千种,让产品设计人员总能选到价格适中、功能和性能皆满意的产品。 在保障供货的同时, 意法
[单片机]
意法半导体发布STM32C0系列MCU  让成本敏感的8位应用也能享受32 位性能
STM32如何分配原理图IO
在画原理图之前,一般的做法是先把引脚分类好,然后才开始画原理图。 要想根据功能来分配 IO,那就得先知道每个 IO 的功能说明,这个我们可以从官方的数据手册里面找到。在学习的时候,有两个官方资料我们会经常用到,一个是参考手册(英文叫 Referencemanual),另外一个是数据手册(英文叫 Data Sheet)。两者的具体区别见下表。 数据手册主要用于芯片选型和设计原理图时参考,参考手册主要用于在编程的时候查阅。在数据手册中,有关引脚定义的部分在 Pinouts and pin description 这个小节中。数据手册中对引脚定义具体定义见下表。 对上表中引脚定义的解读,见下图。 举例,如果MCU 型号是 S
[单片机]
<font color='red'>STM32</font>如何分配原理图IO
基于嵌入式系统原型设计的STM32开放式开发环境详解
市场上涌现各种价格亲民的经济型微控制器,助力新一代开发者创造令人兴奋的新型嵌入式应用。如今的开发工具非常好用,软硬件均呈现模块化趋势,插接安装简单容易,使得产品设计评估和原型开发周期大幅缩短。STM32开放式开发环境是业内独一无二的软硬件开发平台,堆叠式插接电路板集成各种模块化硬件,同时模块化软件覆盖从驱动程序到应用层的全部软件,帮助设计人员将创意快速变成产品原型,顺利转化成最终设计。 STM32开放式开发环境是什么? STM32开放式开发环境 是意法半导体开发的嵌入式系统原型设计开发环境,以简化嵌入式项目设计为目标,通过开源形式提供全部重要功能模块,组件包括: -价格极低的STM32 Nucleo开发板(STM32微控制
[单片机]
基于嵌入式系统原型设计的<font color='red'>STM32</font>开放式开发环境详解
stm32串口接收中断触发原理
如果在STM32微控制器的串口通信中,接收中断无法触发,可能有以下几个可能的原因: 1. 串口接收中断未使能:在初始化串口时,可能未正确使能接收中断。请确保在初始化代码中设置了正确的控制寄存器位来使能串口接收中断。例如,使用`USART_ITConfig()`函数或设置相应的寄存器位。 2. 中断优先级设置错误:如果其他中断具有更高的优先级,可能会导致串口接收中断无法触发。请确保正确配置了中断优先级,并确保串口接收中断的优先级高于其他中断。 3. 接收缓冲区溢出:如果接收缓冲区溢出,可能会导致串口接收中断无法触发。确保在接收中断处理函数中及时读取接收数据寄存器,以避免缓冲区溢出。 4. 硬件连接错误:检查串口接收引脚是否正确连接,
[单片机]
<font color='red'>stm32</font>串口接收中断触发原理
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved