赞
踩
在学习51单片机的时候,配置串口中断服务函数,只需要查看串口中断的中断号,然后在编写中断服务函数的时候,在函数名后面加上中断号。而在stm32中,中断的数量较多,对于中断的管理也会稍微复杂一点,而且中断服务函数名字不能自己随便乱取,已经有定义过,要通过查询找到你所使用的中断服务函数所需要用到的名字。
CM3内核可以支持256个中断,其中包含有16个内核中断和240个外部中断。但是stm32只用到了其中的84个中断(16个内核中断和68个可屏蔽中断)。
管理这么多的中断,stm32使用了几个寄存器来使他们有序的执行:
ISER[8]:(Interrupt Set-Enable Registers),中断使能寄存器组,有ISER[0]~ISER[7]8个32位寄存器组成,每一位控制一个中断,总共可控制256个中断,而使用stm32,只用到了ISER[0~2],ISER[0]的 bit0~31 分别对应中断 0~31;ISER[1]的 bit0~32 对应中断 32~63;ISER[2]的 bit0~3 对应中断 64~67。
ICER[8]:(Interrupt Clear-Enable Registers),中断除能寄存器组。与上一个寄存器相反,不做赘述。
ISPR[8]:(Interrupt Set-Pending Registers),中断挂起控制寄存器组。这个寄存器的作用是当有一个更高优先级的中断出现时,将低优先级正在执行的中断先挂起,让给高优先级的先。
IABR[8]:(Interrupt Active Bit Registers),中断激活标志位寄存器组。这是一个只读的寄存器,通过这个寄存器我们可以读出哪个中断在执行(对应的位为1则表示该中断正在执行)
由上表,由寄存器AIRCR来设定所用到的4位bit中到底分配几个bit来表示抢占优先级,像上面那样,AIRCR为0时,4位bit全部用来表示响应优先级。
从上面的知识可以看出,在串口中断中,像中断的使能由串口的状态来决定,比如像接收完毕时产生中断,而挂起和解挂则由系统根据优先级来设置,那么我们需要做的就是去配置中断的中断分组(就是上面表格说到的内容),以及优先级,然后编写产生中断后要做的事(即中断服务函数)
- //设置 NVIC 分组
- //NVIC_Group:NVIC 分组 0~4 总共 5 组
- void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
- {
- u32 temp,temp1;
- temp1=(~NVIC_Group)&0x07;//取后三位
- temp1<<=8;
- temp=SCB->AIRCR; //读取先前的设置
- temp&=0X0000F8FF; //清空先前分组
- temp|=0X05FA0000; //写入钥匙
- temp|=temp1;
- SCB->AIRCR=temp; //设置分组
- }
上面一段代码时配置分组的,在配置AIRCR时,需要先向AIRCR输入秘钥,为了保持AIRCR原先的值,先将AIRCR原先的值保留下来,然后向AIRCR输入秘钥,之后再把保留下来的值赋值回去。
- //设置 NVIC
- //NVIC_PreemptionPriority:抢占优先级
- //NVIC_SubPriority :响应优先级
- //NVIC_Channel :中断编号
- //NVIC_Group :中断分组 0~4
- //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
- //组划分:
- //组 0:0 位抢占优先级,4 位响应优先级
- //组 1:1 位抢占优先级,3 位响应优先级
- //组 2:2 位抢占优先级,2 位响应优先级
- //组 3:3 位抢占优先级,1 位响应优先级
- //组 4:4 位抢占优先级,0 位响应优先级
- //NVIC_SubPriority 和 NVIC_PreemptionPriority 的原则是,数值越小,越优先
- void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,
- u8 NVIC_Group)
- {
- u32 temp;
- MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
- temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
- temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
- temp&=0xf; //取低四位
- NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);
- //使能中断位(要清除的话,相反操作就 OK)
- NVIC->IP[NVIC_Channel]|=temp<<4; //设置响应优先级和抢断优先级
- }

上面一段代码则是用来设置优先级(抢占优先级和响应优先级)。上面的分组分好后,我们便知道IP寄存器中有4位bit用几位来表示抢占优先级,之后就该开始设置优先级的值了,比如我们分为组 1:1 位抢占优先级,3 位响应优先级,我们赋值1010,则表示抢占优先级为1,响应优先级为2.
到这里,中断就配置完了,接下来就要自己写中断服务函数了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。