精华内容
下载资源
问答
  • STM32寄存器地址映射的理解
    2021-11-18 22:02:27

    在STM32中对于基地址、外设基地址定义完后,将某个IO口的地址也定义完后,给每个IO口下属的寄存器再进行地址定义过于复杂,故引入了结构体指针,通过结构体指针,使GPIO的的基地址及其后一段寄存器可以通过直接给结构体变量赋值进而对其操作,其中最重要的一段

    #define GPIOA        ((GPIO_TypeDef *) GPIOA_BASE)

    这一段先看后半部分 ((GPIO_TypeDef *) GPIOA_BASE),这一部分就是一个指针的指针变量,那么   #define GPIOA        ((GPIO_TypeDef *) GPIOA_BASE)     则是把这个指针变量的名字进行了替换,然后同样的对于一个指针而言,指针变量中存放的是对应变量的地址,而在该宏定义中,GPIOA_BASE被转化为指针变量后,其也是一个地址,那么就相当于又把这个地址赋给了GPIOA,也就是说在这段话中实行了以下几个步骤,

    1、把GPIOA_BASE转化为结构体指针变量

    2、把结构体指针变量的名字替换成为GPIOA

    3、把GPIOA_BASE的地址赋给指针变量GPIOA 

    再说一下自己的另一种理解,

    1、把GPIOA_BASE转化为结构体指针变量

    2、把结构体指针变量的名字替换成为GPIOA,也就是#define   GPIOA_BASE    GPIOA;

    3、由于定义了GPIOA_BASE是一个地址,然后因为a=b,b=c,那么a=c,所以相当于

    #define  GPIOA     地址;

    更多相关内容
  • 2、stm32是32位单片机,说明基本的寄存器是32位的,4字节。内存地址需要4位 3、基址也就是基础地址,最开始的地址,这个查看芯片手册,是人家规定的。 4、偏移,即偏移地址,一般是正整数,也是增加...

    芯片:stm32f103zet6

    1、存储单元一般应具有存储数据和读写数据的功能,一般以8位二进制作为一个存储单元,也就是一个字节.每个单元有一个地址,是一个整数编码,可以表示为二进制整数。

    2、stm32是32位单片机,说明基本的寄存器是32位的,4字节。内存地址需要4位

    3、基址也就是基础地址,最开始的地址,这个查看芯片手册,是人家规定的。

    4、偏移,即偏移地址,一般是正整数,也是增加的数字。比如基址是10,偏移是4,地址就是10+4=14.

    下面STM32F10xxx中内置外设的起始地址。

    每个外设的起始地址就是,每个外设的基址了,当然这个基址也可以再分解为基址和偏移地址。

    比如,GPIOB的起始地址是0X4001 0C00,可以分解为

    片上外设基地址:0x40000000    GPIO都挂载到APB2总线:APB2偏移:0x10000,RCC在APB2总线的偏移是 0x0C00

    GPIOB外设上有什么寄存器呢? 

     

    看看其中的CRL寄存器,偏移是0x00 。如果要找GPIOB的CRL寄存器,则起始地址0X4001 0C00+偏移0x00

     

    ODR偏移是0x0C,如果要找GPIOB的ODR寄存器,则起始地址0X4001 0C00+偏移0x0C

     来,用用吧。

    我就让我的开发板的一个LED闪烁。

    电路是这样的

    现在要让GPIOB0输出低电平,灯亮,高电平,灯灭。

    stm32使用一个外设得使能相应的时钟,即RCC。

    我现在要使用GPIOB0,首先使能GPIOB的时钟,时钟也是寄存器控制的啊,查上面的地址表,RCC的基址是

    0x40021000,使能GPIOB的时钟,它是由RCC_APB2ENR控制的,因为挂在APB2总线上。偏移是0x18

    则RCC_APB2ENR地址:0x40021000+0x18=0x40021018

    再设置GPIOB的IO模式,CRL寄存器控制。(CRL控制低8位引脚IO的模式,CRH控制高八位IO的模式,四位控制一个io的模式,一个寄存器控制8个引脚,共32位,一个寄存器)

     设置GPIOB的电平高低,ODR寄存器控制(直接对相应的引脚,写入1或者0就行,1,高电平,0,低电平)

     工程文件结构:起始文件,头文件,源文件

    /*  片上外设基地址  */
    #define PERIPH_BASE              ((unsigned int)0x40000000)
    
    /*  总线基地址,GPIO都挂载到APB2上 */
    #define APB2PERIPH_BASE			(PERIPH_BASE + 0x10000)
    
    /*  GPIOB外设基地址  */
    #define GPIOB_BASE				(APB2PERIPH_BASE + 0x0C00)
    
    /*  GPIOB寄存器地址,强制转换成指针  */
    #define GPIOB_CRL					*(unsigned int*) (GPIOB_BASE+0x00)
    #define GPIOB_CRH					*(unsigned int*) (GPIOB_BASE+0x04)
    #define GPIOB_IDR					*(unsigned int*) (GPIOB_BASE+0x08)
    #define GPIOB_ODR					*(unsigned int*) (GPIOB_BASE+0x0C)
    #define GPIOB_BSRR				*(unsigned int*) (GPIOB_BASE+0x10)
    #define GPIOB_BRR					*(unsigned int*) (GPIOB_BASE+0x14)
    #define GPIOB_LCKR				*(unsigned int*) (GPIOB_BASE+0x18)
    
    /*  RCC外设基地址   */
    #define RCC_BASE					(0x40021000  +  0x1000) 
    /* RCC的AHB1时钟使能寄存器地址,强制转换成指针  */
    #define RCC_APB2ENR				    *(unsigned int*)(RCC_BASE+0x18)
    

    SystemInit()是为了骗过启动文件,这里应该配置时钟树,下次再讲。 对于那些逻辑运算不懂,看前面的stm32编程要点。

    #include "stm32f1.h"
    
    void SystemInit()
    
    {
    
    }
    
    void delay(int t)
    
    {
    
    	 int i;
    
    	 for( ;t>0; t--)
    
    	 for(i=0;i<2000;i++);
    
    }
    
    int main(void)
    {
    	
    	RCC_APB2ENR |= (1<<3);
    
    	//清空控制PB0的端口
    	GPIOB_CRL &= ~(0x0F<<(4*0)); 
    	//配置PB0为通用推挽输出,速度为50M
    	GPIOB_CRL |= (0x03<<(4*0));
    
    	while(1)
    	{
    		
    		GPIOB_ODR =0x00;
    		delay(1000);
    		
    	
    		GPIOB_ODR =0x01;
    		delay(1000);
    		
    		
    	}
    	
    }
    

    现在我们怎么算这个偏移呢,我也是理解了好一会,只能说C语言还不够。
    有了首地址  0x4002 3830  
    也可以直接加偏移量,用宏定义。

    在正点原子中,利用的是,结构体的内存对齐原则
    **内存对齐,对齐规则是按照成员的声明顺序,依次安排内存,其偏移量为成员大小的整数倍,0看做任何成员的整数倍,最后结构体的大小为最大成员的整数倍**可以参考下面两篇文章。
    https://blog.csdn.net/shi2huang/article/details/80290192
    https://blog.csdn.net/weixin_40853073/article/details/81451792

    好好理解 变量的地址,值,内存,之间的关系。很容易懵。下面会具体举例

    再来理解  结构体  RCC_TypeDef 
    因为每个寄存器变量都是32位的值,4个字节,所以占4个内存地址

    所以每个变量代表的地址偏移量都是4的倍数,例如

    ```
    typedef struct
    {
      __IO uint32_t CR;            /*!< RCC clock control register,                                  Address offset: 0x00 */
      __IO uint32_t PLLCFGR;       /*!< RCC PLL configuration register,                              Address offset: 0x04 */
      __IO uint32_t CFGR;          /*!< RCC clock configuration register,                            Address offset: 0x08 */
      __IO uint32_t CIR;           /*!< RCC clock interrupt register,                                Address offset: 0x0C */
      __IO uint32_t AHB1RSTR;      /*!< RCC AHB1 peripheral reset register,                          Address offset: 0x10 */
      __IO uint32_t AHB2RSTR;      /*!< RCC AHB2 peripheral reset register,                          Address offset: 0x14 */
      __IO uint32_t AHB3RSTR;      /*!< RCC AHB3 peripheral reset register,                          Address offset: 0x18 */
      uint32_t      RESERVED0;     /*!< Reserved, 0x1C                                                                    */
      __IO uint32_t APB1RSTR;      /*!< RCC APB1 peripheral reset register,                          Address offset: 0x20 */
      __IO uint32_t APB2RSTR;      /*!< RCC APB2 peripheral reset register,                          Address offset: 0x24 */
      uint32_t      RESERVED1[2];  /*!< Reserved, 0x28-0x2C                                                               */
      __IO uint32_t AHB1ENR;       /*!< RCC AHB1 peripheral clock register,                          Address offset: 0x30 */
      __IO uint32_t AHB2ENR;       /*!< RCC AHB2 peripheral clock register,                          Address offset: 0x34 */
      __IO uint32_t AHB3ENR;       /*!< RCC AHB3 peripheral clock register,                          Address offset: 0x38 */
      uint32_t      RESERVED2;     /*!< Reserved, 0x3C                                                                    */
      __IO uint32_t APB1ENR;       /*!< RCC APB1 peripheral clock enable register,                   Address offset: 0x40 */
      __IO uint32_t APB2ENR;       /*!< RCC APB2 peripheral clock enable register,                   Address offset: 0x44 */
      uint32_t      RESERVED3[2];  /*!< Reserved, 0x48-0x4C                                                               */
      __IO uint32_t AHB1LPENR;     /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
      __IO uint32_t AHB2LPENR;     /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
      __IO uint32_t AHB3LPENR;     /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
      uint32_t      RESERVED4;     /*!< Reserved, 0x5C                                                                    */
      __IO uint32_t APB1LPENR;     /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
      __IO uint32_t APB2LPENR;     /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
      uint32_t      RESERVED5[2];  /*!< Reserved, 0x68-0x6C                                                               */
      __IO uint32_t BDCR;          /*!< RCC Backup domain control register,                          Address offset: 0x70 */
      __IO uint32_t CSR;           /*!< RCC clock control & status register,                         Address offset: 0x74 */
      uint32_t      RESERVED6[2];  /*!< Reserved, 0x78-0x7C                                                               */
      __IO uint32_t SSCGR;         /*!< RCC spread spectrum clock generation register,               Address offset: 0x80 */
      __IO uint32_t PLLI2SCFGR;    /*!< RCC PLLI2S configuration register,                           Address offset: 0x84 */
      __IO uint32_t PLLSAICFGR;    /*!< RCC PLLSAI configuration register,                           Address offset: 0x88 */
      __IO uint32_t DCKCFGR;       /*!< RCC Dedicated Clocks configuration register,                 Address offset: 0x8C */

    } RCC_TypeDef;
    ```

    现在可以理解:RCC->AHB1ENR|=1<<0; 

    1、把1左移0位,等于0x00000001
    2、和RCC->AHB1ENR的复位值:0x0010 0000相或,等于,0x0010 0001
    再赋值给RCC->AHB1ENR
    把外设GPIO A 时钟开启

    3、RCC->AHB1ENR换成宏定义,
    ((RCC_TypeDef *) RCC_BASE)->AHB1ENR
    RCC_TypeDef->AHB1ENR
    换成地址
    0x4002 3830

    4、这个结构体是32位的所以对它进行32位操作,
    0x4002 3830
    0x4002 3831
    0x4002 3832
    0x4002 3833
    4个地址的32位bit赋值,0x0010 0001
     


     

     

    展开全文
  • 寄存器理解

    千次阅读 2019-10-19 11:06:36
    下面为自己的一些理解,如有错误之处,还望海涵与纠正,谢谢! 内存映射 在正式进入寄存器的知识之前,首先对内存映射进行简单的介绍。此处以TI公司的DSP28335芯片为例。通过查询该芯片的官方数据手册,可获知该芯片...

    前言

    在进行嵌入式开发过程中,寄存器可以说是与嵌入式工程师打交道最多的东西,因为偏向底层的驱动开发,几乎都是利用寄存器完成的。那么,寄存器到底是什么呢?下面为自己的一些理解,如有错误之处,还望海涵与纠正,谢谢!

    内存映射

    在正式进入寄存器的知识之前,首先对内存映射进行简单的介绍。此处以TI公司的DSP28335芯片为例。通过查询该芯片的官方数据手册,可获知该芯片的内存分配图。由于该图比较大,即使贴出来也会很模糊,所以此处仅展示一部分截图,如下:
    在这里插入图片描述
    由上图可知,由于该芯片是32位,所以整个芯片支持的最大寻址范围为4GB,只是芯片厂商没有完全使用罢了。而整个芯片的内存空间又被分为很多,用于不同的功能。
    在简单了解了内存映射之后,我们开始进行寄存器的讲解。

    寄存器到底是什么

    实际上,我们在操作芯片的寄存器时,其实操作的是寄存器对应的地址虽然直接操作地址的方式,会使得代码的执行效率稍微高一点,但是可读性和可维护性便会大大降低,这样的代价对于绝大部分应用而言是不可以接受的。如果对于关键代码而言,需要确保它的执行效率,那么可以小范围的使用操作地址的方式进行。
    那我们为什么在实际编程时,并没有对相应的地址与寄存器之间建立联系呢?其实,是TI官方的文件已经帮我们完成了这个工作。其中,DSP2833x_Headers_nonBIOS.cmd文件为各个寄存器分配了地址,DSP2833x_Gpio.h文件为寄存器创建相应的结构体,而DSP2833x_GlobalVariableDefs.c文件则可以人为寄存器名称地址之间的桥梁,该文件的内容是为了定义上述cmd文件中的寄存器名称。

    总结

    通过上面的叙述,我们可以知道,寄存器实际上就是代表了一个对应的地址,说的再专业一点,这个过程就叫寄存器映射

    展开全文
  • 我用#CSDN#这个app发现了有技术含量的博客,小伙伴们求同去《STM32寄存器的简介、地址查找,与直接操作寄存器》, 一起来围观吧 https://blog.csdn.net/geek_monkey/article/details/86291377?utm_source=app&...

    我用#CSDN#这个app发现了有技术含量的博客,小伙伴们求同去《STM32寄存器的简介、地址查找,与直接操作寄存器》, 一起来围观吧 https://blog.csdn.net/geek_monkey/article/details/86291377?utm_source=app&app_version=4.21.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

    我用#CSDN#这个app发现了有技术含量的博客,小伙伴们求同去《汇编语言–32位寄存器详解》, 一起来围观吧 https://blog.csdn.net/Yun_Ge/article/details/85158670?utm_source=app&app_version=4.21.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

    内存的结构:由若干存储单元组成,以字节为单位。
    存储最小单位:“二进制位”,包含信息为0或1
    最小编址单位:字节,一个字节包含八个二进制位
    内存地址:为了便于CPU访问,给每个存储单元一个编号(第一个字节的地址是0,后面依次 是1、2、3,等等),也称为物理地址或绝对地址。内存地址是无符号整数,用16进制来表示
    内存地址空间(存储空间):内存地址的集合,也称物理空间,它是一维线性空间,其编址为0,1,2,…,n-1

    2、逻辑地址(程序地址,相对地址,虚地址)
    用户编制的源程序,存在于程序员建立的符号名字空间内,经过汇编或编译后形成若干目标代码,这些目标代码连接后形成可装入程序,这些程序通常采用相对地址的形式,其首地址为0,其余指令中的地址都相对于首地址而编址。不能用逻辑地址在内存中读取信息
    作业地址空间(地址空间):由逻辑地址组成的空间,也称为地址空间。

    通俗一点的来说,程序员在进行编码的时候,对于内存的情况是不了解的,就算了解一台计算机也没法了解别的计算机,不可能直接指定物理地址,
    例如,在2000号存储单元存放一个char数据,也许2000号在本机是空闲的,而在别的计算机运行,可能存了别的数据,这样写程序显然不合适,所以引入了逻辑地址。
    程序员在编码的时候不用考虑内存的情况,所有程序都从0号地址开始编码,运行时要完成由逻辑地址到物理地址的地址映射,这样才能正确运行程序。

    展开全文
  • //忘寄存器地址0x80赋值0x00 sfr是一种扩充数据类型,点用一个内存单位,值域为0-255.利用它可以访问51单片机内部所有的特殊功能寄存器。前一句“sfr p0=0x80”就是将P0映射到地址0x80。后一句“p0=0x00”就是往p0...
  • STM32寄存器的简介、地址查找,与直接操作寄存器

    万次阅读 多人点赞 2019-01-11 11:15:15
    什么是寄存器 提到单片机,就不得不提到寄存器。根据百度百科介绍,寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,... 存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个...
  • 在Modbus实际应用中,我们对Modbus 3区、4区的地址有的时候会出现混淆,尤其是类似于404097这种表达方式的地址,就更容易乱,因为我们常常会用串口调试,这个就容易难理解。 Modbus 中3区和4区的地址表示含义如下:...
  • STM32从地址寄存器

    千次阅读 多人点赞 2019-01-11 11:44:32
    本文希望在上一节的基础上,把指针操作过渡到寄存器的...我们把寄存器地址进行宏定义,可以增强可读性。 #define RCC_APB2ENR (*(unsigned int *)0x40021018) #define GPIOB_CRH (*(unsigned int *)0x40010c04) #d...
  • 本人比较笨,这都是平常自己的理解,只是处于好奇。 对于我学的单片机来说,所有的功能性操作都是用指令来实现的,每一个指令都是32位的。一条指令包括大部分的状态位、功能控制位,和四位的十六进制表示的共32位...
  • 寄存器模型理解

    千次阅读 2019-11-27 17:28:01
    寄存器模型 是一个model, 模拟的是reg的行为,就像reference model 模拟的是design的...包括各个寄存器字段描述、寄存器、寄存器组、寄存器地址映射等信息。 前门和后门访问 前门访问需要adapter ...
  • 寄存器理解

    千次阅读 2016-09-22 15:50:24
    寄存器和存储器 存储器在CPU外,一般指硬盘,U盘等可以在切断电源后保存资料的设备,容量一般比较大,缺点是读写速度都很慢,普通的机械硬盘读写速度一般是50MB/S左右。内存和寄存器就是为了解决存储器读写速度慢而...
  • STM32 对外设基地址,总线外设基地址寄存器地址理解 前言 本博文基于STM32F103ZET6和MDK以及V3.5.0库函数; 本博文从Cortex-M3内核的寻址空间映射一直聊到库函数是怎样配置具体的某一个寄存器; 如有...
  • 单片机外设(ram、寄存器)地址详解

    千次阅读 2020-01-05 13:01:13
    在学习汇编语言时,我们会接触到一些寄存器,比如R0、R1、还有栈指针寄存器SP、下一条指令寄存器PC 等等。这些寄存器是存在于内核(如CPU)之内的,这些寄存器是我们无法通过c语言访问到的,而只能用汇编语言操作。...
  • 1引言 我们在学习STM32的时候,把被控单元的 FLASH,RAM,FSMC和AHB 到 APB 的桥(即片上外设),这些功能部件共同排列在一个 4GB 的地址空间...给已经分配好地址的特定功能的内存单元取别名的过程就叫寄存器映射。 然
  • 寄存器,寄存器是什么意思

    千次阅读 2021-07-28 06:43:33
    寄存器,寄存器是什么意思寄存器定义寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器...
  • modbus协议中的寄存器理解

    万次阅读 多人点赞 2018-02-26 09:54:35
    最近有用到modbus协议,就把之前原来收集的资料全都拿出来又复习了一遍。发现以前了解的也忘了差不多...具体如下: 0x01: 读线圈寄存器 0x02: 读离散输入寄存器 0x03: 读保持寄存器 0x04: 读输入寄存器 0x05: ...
  • 寄存器的“地址”概念

    千次阅读 2017-03-09 10:21:07
    寄存器地址就是内存地址  分为 逻辑地址:  机器语言指令仍用这种地址指定一个操作数的地址或一条指令的地址。这种寻址方式在Intel的分段结构中表现得尤为具体,它使得MS-DOS或Windows程序员把程序分为...
  • 如何理解寄存器映射

    千次阅读 2020-02-27 23:50:44
    存储器本身是没有地址的,给存储器分配地址的过程就是存储器映射。寄存器映射同理。寄存器就是给有特定功能的内存单元的别名。
  • STM32外设寄存器地址定义

    千次阅读 2016-08-18 10:54:02
    一直都是用STM32做项目中的主控芯片,在编程的时候,之前一直忽视了一个问题,那就是寄存器的位置是如何定义的,为什么用一个USART1->CR操作就能够给这个CR寄存器赋值?其实这是一个比较底层的问题,不懂这方面的...
  • 单片机寄存器

    万次阅读 2019-05-30 14:10:30
    单片机寄存器其实就相当于一个变量,只不过这个变量在固定的地址,有一个特殊的名称(当然也不强制)。 初学者对寄存器的操作比较困难的原因不是汇编语言或C语言使用的不熟,而是对寄存器的陌生。 单片机中存储器的...
  • 21个特殊功能寄存器(52系列是26个)不连续地分布在128个字节的SFR存储空间中,地址空间为80H-FFH,在这片SFR空间中,包含有128个位地址空间,地址也是80H-FFH,但只有83个有效位地址,可对11个特殊功能寄存器的某些位...
  • 在KEIL中如何查看寄存器的值与地址

    万次阅读 多人点赞 2019-04-08 22:46:35
    正确连接硬件,编译程序后,按下工具栏的调试按钮进入调试模式。...例如AHBIENR寄存器的值是0x0010 0084,将此十六进制的数据按照二进制展开,在数据手册中找到相应的寄存器,按位对照,并借助说明即可理...
  • 寄存器名称 寄存器地址 相对GPIOB基址的偏移 GPIOB_CRL 0x4001 0C00 0x00 GPIOB_CRH 0x4001 0C04 0x04 GPIOB_IDR 0x4001 0C08 0x08 GPIOB_ODR 0x4001 0C0C 0x0C GPIOB_BSRR 0x4001 0C10 0x10 GPIOB_BRR 0x4001 0C14...
  • CPU中的寄存器地址概念

    万次阅读 2016-03-17 10:18:12
    一般的CPU都是由以下部分组成:运算器、控制器和寄存器。 这些器件之间自然也要相互交换信息,所以他们也是有导线相连的,也就是总线了。但是这个总线是内部总线,而CPU和内存、显卡之类做信息交换的是外部总线。 ...
  • 特殊功能寄存器地址映象表(一)>  <特殊功能寄存器地址映象表(二)>  <特殊功能寄存器地址映象表(三)>  几个常用的SFR  1、ACC:累加器,常常用A表示...
  • 通用寄存器

    2021-07-28 06:43:31
    通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。除此之外,它们还各自具有一些特殊功能。汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确、合理地...
  • 前言 ´・ᴗ・` 微机系统的构成 外设 CPU结构 执行单元 BIU 寄存器 存储器组织结构 寻址方式 总结 ´◡`

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,303
精华内容 45,721
关键字:

寄存器地址怎么理解

友情链接: 互相关除噪音.zip