基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

时间:2021-05-27 12:22:36

上一次,我们完成了核心初始化之关闭看门狗了。下面就要关闭所有中断了。因为这个时候还在初始化整个硬件环境,应用程序还没有开始跑,所以是不希望有中断产生来打断CPU工作的。

中断是嵌入式系统中很重要的东西了。因为有了这个东西,可以使CPU解放出来,做更多的事。

学单片机的时候,对于按键,我们可以采用轮询检测,隔一段时间就去检测看看按键有没有按下,有按下的话就进行处理。没有的话就跳过。而使用外部中断后,就不必检测了,外部中断会自动检测,就不用CPU检测了。当外部中断有效后,外部中断模块就会产生一个中断源给CPU,CPU检测到这个中断源,再去执行对应的中断处理函数。比轮询法效率要高很多了。

至于S3C6410的中断的具体的一些应用,等后面开发用到的时候再分析,这里只是关心怎么把所有中断给关闭掉。

在CPSR寄存器中

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

后面有两位,第7位和第6位,就是I位和F位。

我们知道,在S3C6410中是有两种中断,一种普通中断,一种是快速中断。所以这关闭需要分开关闭。

I位:控制所有普通中断。相当于51单片机的EA位。要使用中断的话,这一位就必须要置0,注意,这里0是使能。我们这里是要关闭所有中断,所以这一位就要写1.

F位:控制快速中断。要使用快中断的话,这一位就必须要置0.也是注意,0才是使能。我们这里要关闭所有快中断,所以这一位要写1.

另外,我们还要把中断控制器的中断使能也给关掉。

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

上图是S3C6410的中断控制器。

这里主要是VIC1和VIC0两个中断控制器,这两个控制S3C6410的64个中断。

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

 截图就截取一部分。

 第一列是中断的标号。表示这是第几个中断号。

 第二列是中断源。表示这个中断的源是什么。

 第三列是描述。说明这个中断是做什么的。

 第四列是中断属于哪个中断控制器。VIC0就说明该中断属于VIC0中断控制器,VIC1就说明该中断属于VIC1中断控制器。所以要使用对应的中断的话,就要去找对应的中断控制器。


 在VICx的若干寄存器里面,有下面两个寄存器,用来无效中断源。

 基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

 寄存器中的每一位对应相应的中断源。往寄存器里面写1,就屏蔽了对应的中断。

 

这里,我们要屏蔽所有中断,所以就直接往这两个寄存器里面写入全1.

知道我们怎么做后,剩下写代码就比较容易了。

   基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

   因为要对寄存器操作,所以第一步先定义要操作寄存器的地址。这里要操作两个寄存器,所以先用define对操作的两个寄存器的地址先定义一下。

       使用ldr伪指令,将iVIC0INTCLEAR寄存器的地址给r0寄存器

       使用mvn指令,将对0取反的值给r1寄存器。这个时候r1的值就是全1。

   使用str指令,将r1的值写入到r0代表的地址中去。就相当于往寄存器iVIC0INTCLEAR里面写入全1了。

 

       下面在对第二个寄存器执行同样的操作。


       第三步就将CPSR的I位和F位进行置1.以关闭所有中断。

       使用mrs指令,将CPSR的值读取到r0寄存器中。

       使用orr指令,将r0的第6位和第7位进行置1,在赋值给r0

       使用msr指令,将r0的值写入到CPSR寄存器中。这样的话,CPSR的I位和F位就置1了。

       使用mov指令,返回。

       这样,就完成了核心初始化之关闭所有中断了。

 

对比STM32:

       基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

        在启动文件中,有调用SystemInit函数,对系统进行复位。这个函数是用C语言写的,也是库中提供的。这个函数的作用是对外设复位以及时钟初始化,配置向量中断表在什么位置。

         进入这个函数,我使用的是STM32X103ZET6,是属于高容量的stm32类型,所以这里只看和高容量有关的代码。

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

     代码,注释也很清楚了。

前面,是对时钟进行复位的。这里现在先不管,等到了时钟在分析。关心红色框框起来的部分。由于我使用的芯片没有定义#if判断的宏,所以就执行到空色框的部分。这里对RCC下的CIR寄存器进行配置。

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

查手册,这个寄存器都是和时钟中断有关的。就是将时钟的相关的中断清除以及关闭。

stm32通过调用这个函数,就关闭了中断和清除中断。但是这些中断都是对应时钟的。而没有对应外部中断以及一些外设的中断的。我认为的话,复位后,外部中断及外设的中断都是不使能的呢?为什么了,因为时钟没有开启。STM32比ARM11多了门控时钟这个东西。即每个外设都有对应的门控时钟,当要使用该外设的时候,要开启对应外设的时钟。复位的时候,外设时钟是默认关闭的。

这个就看外设时钟使能寄存器就可以了,外设的话,是挂在不同的总线上的,有的在AHB总线,有的在APB1,有的在APB2上,所以就有3个寄存器来配置各个总线对应的时钟使能。

      基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断


 这里,就以APB2外设时钟使能说明。

基于S3C6410的ARM11学习(六) 核心初始化之关闭所有中断


复位默认值是0x0,所以每一位都是0.从列表就可以看出,0就是对应功能的时钟关闭。比如位2为0,IO端口A时钟关闭。既然端口时钟都关闭了,那中断就不会有效果,因为中断信号都进不了CPU。

但是,这复位为什么要复位时钟的中断了,因为随后就要对时钟进行配置了。将时钟配置为72M。而不是内部时钟的8M。所以不关闭时钟的相关中断的话,配置的时候就会产生中断。

如上,就对STM32初始化的中断关闭就完成了。当然这一步不是我们写程序完成的,而是启动代码帮我们搞定的。