概念理解:寄存器与地址

概念理解:寄存器与地址寄存器是 CPU 内部用来存放数据的一些小型存储区域 用来暂时存放参与运算的数据和运算结果

大家好,欢迎来到IT知识分享网。

本文章描写一些对STM32寄存器与地址的概念理解以及在嵌入式编程中register和volatile 变量的区别与示例说明。


一、STM32F103系列芯片的地址映射和寄存器映射原理

(一)什么是寄存器

(二)地址映射和寄存器映射原理

STM32F103系列芯片的地址映射和寄存器映射原理是将芯片内部的各种资源(如GPIO、UART、SPI等)映射到特定的地址空间和寄存器中,以便程序可以通过读写这些地址和寄存器来访问这些资源。

对于STM32F103系列芯片,每个资源(例如GPIOA)都有一个特定的地址(例如0x),以及一组与之相关的寄存器(例如GPIOA_CRL、GPIOA_CRH、GPIOA_IDR、GPIOA_ODR等)。这些寄存器用于对相应资源进行配置和控制,例如设置GPIOA的输出高/低电平等。

通过地址映射和寄存器映射,我们可以更加方便地访问和控制STM32F103芯片的各种资源,从而实现特定的功能和应用。具体而言,可以使用C语言等编程语言,通过访问特定的地址和寄存器来读写和控制资源,从而实现如LED闪烁、按键检测、串口通信等特定功能。

(三)怎样找到某个寄存器地址?

找到某个寄存器地址的方法主要是通过查阅相关的数据手册。

  1. 找到对应设备的硬件手册或数据手册,这些手册通常会提供寄存器的地址信息。
  2. 在手册中寻找与所需寄存器相关的章节或表格,这些章节或表格通常会以寄存器的名称或功能作为关键字进行标记。
  3. 在相关章节或表格中,可以查找寄存器的地址,通常会以十六进制或二进制的形式表示。
  4. 确定寄存器的地址后,可以在程序中使用该地址进行读写操作。

二、GPIO端口的初始化设置步骤

GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置GPIO口工作模式 ,推挽模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //设置GPIO口的引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO口的速度 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化完成 

三、对RAM中的各变量的修改操作,与对外部设备寄存器的操作有哪些相同与差别?

(1)相同点:

  1. 语法:在C语言中,无论是对内存变量还是对外部设备的操作,语法上都是相同的。都是通过使用指针或者直接访问变量的方式来进行读写操作。
  2. 访问方式:对内存变量和外部设备的访问都需要知道其地址。对内存变量的地址通常由编译器自动分配,而对外部设备的地址通常由硬件或系统提供。

(2) 不同点:

  1. 物理位置:内存变量存储在RAM中,而外部设备存储在硬件设备的寄存器中。RAM是处理器的临时存储区域,当电源关闭时,其内容会丢失。而寄存器的内容即使电源关闭也会保留。
  2. 访问速度:对内存变量的访问速度通常比对外部设备的访问速度快得多。内存访问通常在几个CPU时钟周期内完成,而外部设备的访问可能需要几百个或更多的CPU时钟周期。
  3. 并发性:多个线程或进程可以同时访问内存变量,但需要适当的同步机制来防止数据竞争。然而,对外部设备的访问通常是串行的,因为硬件设备通常不能同时处理多个请求。
  4. 安全性:对内存变量的访问如果存在越界或者非法访问,可能会导致程序崩溃或者数据破坏。而对外部设备的非法访问可能会损坏硬件设备或者导致系统不稳定。
  5. 映射方式:对外部设备的操作通常需要特定的硬件知识,并且需要知道设备寄存器和内存地址之间的映射关系。而对内存变量的操作则相对简单,只需知道变量的地址即可。

(3)为什么51单片机的LED点灯编程要比STM32的简单

51单片机的硬件结构相对简单,其内部资源较少,外部引脚也较少,因此控制LED的方式相对单一。而STM32具有更多的内部资源和外部引脚,可以进行更多复杂的操作,因此需要更复杂的编程

四、register和volatile变量修饰符作用

#include <stdio.h>  int main() { 
     register int i; // 使用register修饰i变量  i = 10; while(i--) { 
     printf("%d ", i); } printf("\n"); volatile int j; // 使用volatile修饰j变量  j = 10; while(j--) { 
     printf("%d ", j); j = j - 1; // 在循环中更改j的值,以展示volatile的作用  } printf("\n"); return 0; } 

在上面的代码中,定义了两个变量i和j,并分别使用register和volatile修饰符。对于i变量,我们使用register修饰符请求编译器将其存储在CPU内部寄存器中,以提高访问速度。在循环中,我们使用i–操作符来减少i的值,并打印每个值。对于j变量,我们使用volatile修饰符表示它可能被某些编译器未知的因素更改。在循环中,我们使用j–操作符减少j的值,并在每次循环中显式地更改j的值。这样做是为了展示volatile修饰符的作用,即告诉编译器不要对访问该变量的代码进行优化,以确保每次循环中都能获得正确的值。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126839.html

(0)
上一篇 2025-09-15 17:20
下一篇 2025-09-15 17:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信