首页 > 其他分享 >STM32/ARM-M系列 如何用C语言指针操作寄存器 上篇

STM32/ARM-M系列 如何用C语言指针操作寄存器 上篇

时间:2024-08-23 18:24:53浏览次数:13  
标签:C语言 STM32 地址 寄存器 操作 CCR ARM 外设 指针

1、操作外设实际上就是操作寄存器

使用STM32进行编程,我们一般是用官方提供的库函数(HAL库)来操作各种外设。本质上,每个外设都有自己的一组外设寄存器,操作外设就是操作各种外设寄存器。HAL库的各个库函数就是对他们的寄存器操作的高度抽象后的封装。打开stm32f10x的数据手册的地址映射表,实际上图中的外设区就是里边就是映射的每个外设的各个寄存器的地址。

在STM32中,每个外设所拥有的一组寄存器的地址是连续的(注意,这点十分重要,下边会讲),外设的起始地址称为基地址,后续的每个寄存器都可以用这个基地址+偏移地址的方式来描述。

STM32,顾名思义,是32位的系统,每个寄存器都是32位的。因此,每个寄存器可以操作的东西其实是很多的,基本上每个位都可以操作一个东西。也正因此,对寄存器的操作,其实就是位操作,位操作在嵌入式底层开发中是十分重要的

注:此图来自stm32f10x的数据手册。

2、C语言指针操作寄存器

我们知道,汇编语言是直接操作硬件的语言,也就是直接操作寄存器。那么,如何用C语言操作寄存器呢?实际上,C语言操作寄存器是通过指针的方式。具体的方法是,找到想要操作的寄存器的地址,将寄存器的地址强制转换为指针(volatile unsigned long *),然后再用#define给它定义个别名,就可以把这个寄存器的别名当作指针进行操作了

例如,操作Cortex-M3内核的寄存器NVIC_CCR,查阅相关手册知道其地址为0xE000ED14,那么就可以用以下所示的方法操作该寄存器:

#define NVIC_CCR ((volatile unsigned long *)(0xE000ED14))
*NVIC_CCR = *NVIC_CCR | 0x200; //设置STKALIGN位

其中,unsigned long表示无符号长整型,在stm32中(32位系统),也就是4字节的无符号整型数。volatile是c语言关键字,用于防止对编译器对其进行优化。volatile unsigned long在stm32的库函数中有时候会被替换为__IO uint32_t,__IO和uint32_t分别是volatile和unsigned long的宏定义。

(volatile unsigned long *)(0xE000ED14)表示指向地址0xE000ED14的指针。许多初学者看到这个语句可能会有点疑惑,不太理解为什么可以这么做。实际上,比如定义个指针int* ptr,ptr就表示这个指针所指向内存的首地址,而0xE000ED14本身就是个地址,所以并没有什么不妥。或者说,本质上,指针就是地址,这也是c语言可以用指针操作寄存器的本质原因

随后我们再用#define定义哥别名NVIC_CCR来表示这个指针,于是,我们就可以使用*NVIC_CCR直接操作这个寄存器了。

标签:C语言,STM32,地址,寄存器,操作,CCR,ARM,外设,指针
From: https://blog.csdn.net/hccgso1212/article/details/141354932

相关文章

  • C语言数组介绍(详解)
    数组目录数组概念一维数组⼀维数组的创建和初始化一维数组的基本创建一维数组的初始化数组的类型一维数组的使用数组下标数组元素的打印数组的输入一维数组内存中的储存如何用sizefo计算数组元素个数二维数组二维数字的概念二维数组的创建二维数组的初始化二维数组的......
  • 【OpenHarmony】openharmony移植到RK3568------获取源码编译OpenHarmony源码
    一、源码获取源码获取有好几种方式,在这里直接在镜像网站下载源码,点击下面连接下载全量版本的OpenHarmony4.1https://repo.huaweicloud.com/openharmony/os/4.1-Release/code-v4.1-Release.tar.gz将源码放到自己建立的目录下解压,我放入的是这个目录/home/wzz/work/0H4.1......
  • 【HarmonyOS NEXT星河版开发实战】天气查询APP
    目录前言界面效果展示首页添加和删除 界面构建讲解1.获取所需数据 2.在编译器中准备数据 3.index页面代码讲解 3.1导入模块: 3.2 定义组件:3.3 定义状态变量:3.4  定义Tabs控制器:3.5 定义按钮样式: 3.6 页面显示时触发的方法: 3.7 获取数据的方......
  • Ubuntu安装arm交叉编译环境
    本地机是x86架构,目标机是arm64架构。CPU架构描述x86_64 /x86/amd6464位AMD/英特尔CPU的别称AArch64 /arm64/ARMv8/ARMv964位ARMCPU的别称i38632位AMD/英特尔CPUAArch32 /arm/ARMv1 到 ARMv732位ARMCPU的别称......
  • C语言中的数据类型
    在C语言中,主要的数据类型有以下几类:一、基本数据类型整型:int:通常占据4个字节,具体大小取决于编译器和系统架构。用于表示整数。short:一般为2个字节,短整型。long:通常为4个字节或更多,长整型。longlong:至少8个字节,更长的整数类型。浮点型:float:单精度浮点数,......
  • C语言的优势与标准
    目录C语言概述1.1C语言的起源1.2使用C语言的理由1.3C语言标准1.3.1K&RC1.3.2ANSIC/C89标准1.3.3C99标准C语言概述        欢迎大家来到c语言的世界,c语言是一种强大的专业化的编程语言。1.1C语言的起源        贝尔实验室的DennisRitchi......
  • C语言实验报告(软件)
    华中科技大学C语言课程实验报告@目录华中科技大学C语言课程实验报告实验1表达式和标准输入与输出实验1.1实验目的1.2实验内容1源程序改错解答:2程序设计(1)解答:(2)解答:(3)解答:1.3实验小结实验2流程控制实验2.1实验目的2.2实验内容及要求1.......
  • STM32学习记录-05 -1-TIM定时中断
    1TIM简介TIM(Timer)定时器定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断(如在STM32中主频为72MHz,计72个数即1MHz也就是1us,计72000个数即1KHz也就是1ms)16位计数器、预分频器(对计数器的时钟进行分频)、自动重装寄存器(计数的目标值,计多少个时钟申请中断)的时基单......
  • STM32学习记录-05 -2-TIM输出比较
    1输出比较简介OC(OutputCompare)输出比较输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形每个高级定时器和通用定时器都拥有4个输出比较通道高级定时器的前3个通道额外拥有死区生成和互补输出的功能2......
  • C语言-数组名与&数组名的细节注意
    这篇博客将通过整型数组、字符数组、字符串放在数组中、以及二维数组的数组名与&数组名和各类特殊情况的题目讲解来使得我们对于指针与数组名具有更加深刻的了解。注意:sizeof(数组名)-数组名表示整个数组的-计算的是整个数组的大小&数组名-数组名表示整个数组,取出的是整......