上一次,我们完成了核心初始化之关闭看门狗了。下面就要关闭所有中断了。因为这个时候还在初始化整个硬件环境,应用程序还没有开始跑,所以是不希望有中断产生来打断CPU工作的。
中断是嵌入式系统中很重要的东西了。因为有了这个东西,可以使CPU解放出来,做更多的事。
学单片机的时候,对于按键,我们可以采用轮询检测,隔一段时间就去检测看看按键有没有按下,有按下的话就进行处理。没有的话就跳过。而使用外部中断后,就不必检测了,外部中断会自动检测,就不用CPU检测了。当外部中断有效后,外部中断模块就会产生一个中断源给CPU,CPU检测到这个中断源,再去执行对应的中断处理函数。比轮询法效率要高很多了。
至于S3C6410的中断的具体的一些应用,等后面开发用到的时候再分析,这里只是关心怎么把所有中断给关闭掉。
在CPSR寄存器中
后面有两位,第7位和第6位,就是I位和F位。
我们知道,在S3C6410中是有两种中断,一种普通中断,一种是快速中断。所以这关闭需要分开关闭。
I位:控制所有普通中断。相当于51单片机的EA位。要使用中断的话,这一位就必须要置0,注意,这里0是使能。我们这里是要关闭所有中断,所以这一位就要写1.
F位:控制快速中断。要使用快中断的话,这一位就必须要置0.也是注意,0才是使能。我们这里要关闭所有快中断,所以这一位要写1.
另外,我们还要把中断控制器的中断使能也给关掉。
上图是S3C6410的中断控制器。
这里主要是VIC1和VIC0两个中断控制器,这两个控制S3C6410的64个中断。
截图就截取一部分。
第一列是中断的标号。表示这是第几个中断号。
第二列是中断源。表示这个中断的源是什么。
第三列是描述。说明这个中断是做什么的。
第四列是中断属于哪个中断控制器。VIC0就说明该中断属于VIC0中断控制器,VIC1就说明该中断属于VIC1中断控制器。所以要使用对应的中断的话,就要去找对应的中断控制器。
在VICx的若干寄存器里面,有下面两个寄存器,用来无效中断源。
寄存器中的每一位对应相应的中断源。往寄存器里面写1,就屏蔽了对应的中断。
这里,我们要屏蔽所有中断,所以就直接往这两个寄存器里面写入全1.
知道我们怎么做后,剩下写代码就比较容易了。
因为要对寄存器操作,所以第一步先定义要操作寄存器的地址。这里要操作两个寄存器,所以先用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:
在启动文件中,有调用SystemInit函数,对系统进行复位。这个函数是用C语言写的,也是库中提供的。这个函数的作用是对外设复位以及时钟初始化,配置向量中断表在什么位置。
进入这个函数,我使用的是STM32X103ZET6,是属于高容量的stm32类型,所以这里只看和高容量有关的代码。
代码,注释也很清楚了。
前面,是对时钟进行复位的。这里现在先不管,等到了时钟在分析。关心红色框框起来的部分。由于我使用的芯片没有定义#if判断的宏,所以就执行到空色框的部分。这里对RCC下的CIR寄存器进行配置。
查手册,这个寄存器都是和时钟中断有关的。就是将时钟的相关的中断清除以及关闭。
stm32通过调用这个函数,就关闭了中断和清除中断。但是这些中断都是对应时钟的。而没有对应外部中断以及一些外设的中断的。我认为的话,复位后,外部中断及外设的中断都是不使能的呢?为什么了,因为时钟没有开启。STM32比ARM11多了门控时钟这个东西。即每个外设都有对应的门控时钟,当要使用该外设的时候,要开启对应外设的时钟。复位的时候,外设时钟是默认关闭的。
这个就看外设时钟使能寄存器就可以了,外设的话,是挂在不同的总线上的,有的在AHB总线,有的在APB1,有的在APB2上,所以就有3个寄存器来配置各个总线对应的时钟使能。
这里,就以APB2外设时钟使能说明。
复位默认值是0x0,所以每一位都是0.从列表就可以看出,0就是对应功能的时钟关闭。比如位2为0,IO端口A时钟关闭。既然端口时钟都关闭了,那中断就不会有效果,因为中断信号都进不了CPU。
但是,这复位为什么要复位时钟的中断了,因为随后就要对时钟进行配置了。将时钟配置为72M。而不是内部时钟的8M。所以不关闭时钟的相关中断的话,配置的时候就会产生中断。
如上,就对STM32初始化的中断关闭就完成了。当然这一步不是我们写程序完成的,而是启动代码帮我们搞定的。