【STM32教程】一文搞懂ARM内核是如何控制外设寄存器的

1、ARM内核寄存器组(M3为例)

     Cortex‐M3 处理器拥有 R0‐R15 的寄存器组。其中 R13 作为堆栈指针 SP。SP 有两个,但在同一 时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。

【STM32教程】一文搞懂ARM内核是如何控制外设寄存器的_第1张图片

R0-R12:通用寄存器 

  通用寄存器,用于数据操作。比如我们常用的加减乘除。MOV R0,#1(给R0寄存器赋值1)

R13(SP): 两个堆栈指针:

  主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包 括中断服务例程) 

  进程堆栈指针(PSP):由用户的应用程序代码使用。

R15  (PC):程序计数寄存器

  PC寄存器指向我们当前运行程序的地址,修改PC寄存器的值能够改变程序的执行位置。

R14(LR):连接寄存器

   当我们的程序调用子程序时,PC寄存器的值被改变,执行完子程序,想要返回主程序执行,就需要将PC修改回,调用子程序之前的地址。这个地址就存储在LR当中。

注意:

    到这里我们应该知道了,程序的执行就是内核根据PC中的地址,找到程序执行位置,对内存中的程序进行读取,期间通过通用寄存器进行数据的存储运算。

2、内存映射(M3为例)

   内核可以直接读写R0、R2、PC这些寄存器,但是我们在单片机的程序设计中经常需要控制片上外设,像GPIO、USART、IIC等这些外设有自己独立的寄存器,该怎么去访问?这是今天的重点,搞懂了这个,我们对单片机的认知就会提升一大截档次。尤其是对单片机程序的编写会更上一层楼。

   前面的内容介绍过了,内核使用通用寄存器进行数据的运算,PC的读写控制程序执行的地址,返回地址用LR进行存储,外面的寄存器肯定是不能这样了。但是内核可以通过对内存的读写操作来读写内核外部的寄存器。下面我们先来看下M3内核的内存映射图。

【STM32教程】一文搞懂ARM内核是如何控制外设寄存器的_第2张图片

    如图这是M3内核的存储器映射图(推荐的厂商可以根据这个设计,也可以自己设计。当然基本上芯片厂商是根据这个设计的)。

   在内存映射中有程序的存储地址、 外围设备地址等。硬件结构上,片上外设的寄存器连在了外围设备这段地址上(0X40000000--0x5FFFFFFF)。

   这里我们再看个片上外设的寄存器,以GPIO的为例。

【STM32教程】一文搞懂ARM内核是如何控制外设寄存器的_第3张图片

   这个寄存器是控制GPIO端口模式的,我们可以看到偏移地址为0x00,这里还需要个基地址,基地址加上偏移地址就是我们寄存器的准确地址了。基地址我们可以理解为在上面的存储器映射表中,0X40000000开始接片上外设的寄存器,这个地址就可以理解为基地址,偏移地址就是在这个地址的基础上向上偏移了多少,接的我们需要使用的寄存器。当然实际中,这段 0X40000000开始的地址还会被细分,比如我们的GPIOA、GPIOB。但是追根到底是我们需要用到的每一个寄存器,都会在这上面找到一个具体的地址,这个地址就相当于内核对外的接口,一共排列了4G大小的长度,寄存器在某一个位置通过导线连接这样就能够和内核通信了。

  我们控制时,以上面的寄存器为例,内核对该寄存器的地址0和1位写11就可以控制PIN0引脚为模拟模式了。这里的可以看到32位一个分成了16组,每2位控制一个PIN引脚。

  再举个例子如果我们想将GPIOA的第0个引脚,即PA0配置为通用输出模式,那么我们就可以找到GPIOA的端口模式寄存器地址,然后直接给这个地址里的0和1位分别赋值1和0。

   本篇文章到这里就结束了,原理是这个原理,其他片上外设寄存器的读写也是这个道理,找到地址给对应位赋值,或者读取对应位就可以了。

   下篇文章,我们来使用C语言一步步写寄存器操作,来实现自己的程序函数库。

你可能感兴趣的:(STM32,stm32,单片机,嵌入式硬件)