原文:
http://blog.163.com/zhu_0571/blo ... 016201041933110758/
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
u32 tmppriority = 0x00, tmpreg = 0x00, tmpmask = 0x00;
u32 tmppre = 0, tmpsub = 0x0F;
/* Check the parameters */
assert(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
assert(IS_NVIC_IRQ_CHANNEL(NVIC_InitStruct->NVIC_IRQChannel));
assert(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
assert(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - (SCB->AIRC & (u32)0x700))>> 0x08;//算出来得到的就是占先优先级的位数占四位中的几位
tmppre = (0x4 - tmppriority);
//算出来得到的就是响应优先级的位数占四位中的几位
tmpsub = tmpsub >> tmppriority;
//然后将四位掩码通过抢占优先级位数得到响应优先级的掩码
tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
//把用户输入的优先级组别参数 结合 前面计算出来的响应优先级的位数 通过 移位放置到抢占优先级相应的bit上
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;//与上相应优先级掩码得到单纯的相应优先级
//然后 或上(|) 响应优先级得到了该中断通道8位的优先级数
//接下来的问题就是如何将这个优先级放置到相应的通道中断优先级寄存器中?
tmppriority = tmppriority << 0x04;
//首先将这个优先级数左移四位放置到相应通道优先级寄存器8位的高四位(优先级8位从左边算起的)
tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
//因为一个32位中包含4个八位,而同时又包括好几个32位,这样的话,需要有一个对准的问题,比如我现在
//是第六个通道,我就需要将其放置到第二个32位中的第二个八位(从左边数),具体算法是:
//首先将该通道在32位中的第几个八位算出来,所以同0x03相与,将通道序号按照模4(MOD)计算,结果其实就是通道数除以4得到的余数,
//然后再乘以8得到的便是该通道在32位中的第几位,有0*8=0,1*8=8,2*8=16,3*8=24,这四种情况
//总之该语句将该通道优先级寄存在其32位当中从第几位开始的8位找出来了放在tmppriority相应的地方中
tmpreg = NVIC->Priority[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)];
//接下来将通道数除以四(这里通道移位来运算除法的),得到的其实就是该通道在第几个32位优先级寄存器上,把这个32位寄存
//结果读出来放在tmpreg中!
tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
//该语句将该通道优先级寄存器在32位当中的第几位开始的八位加上了掩码,以便后面方便写入到该通道优先级寄存器的八位上
tmpreg &= ~tmpmask;
//将该通道在32位的优先级寄存器组上的8位清零,其他位也就是其它通道的响应优先级寄存器保证同一相与,不会改变
tmppriority &= tmpmask;
//该语句只保留该通道的响应优先级寄存器在32位上的八位,其他的通道响应优先级寄存器全部用0屏蔽,
tmpreg |= tmppriority;
//终于现在,tmpreg中该通道响应优先级寄存器的8位全部为0,其他通道响应优先级寄存器的8位(还有三组)全部为原来本身的数而没有改变
//tmppriority中该通道响应优先级寄存器的8位数据完好,其他通道响应优先级寄存器的8位(还有三组)全部为0
//两者相"或",该32位tmpreg便是已经包含了本次用户输入的通道中断响应优先级寄存器的8位信息
NVIC->Priority[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg;
//输入到包含该通道中断响应优先级寄存器的32位寄存器中,可以看出,本质上也是一个读--修改--写的过程
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->Enable[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
(u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->Disable[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
(u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}
}
阅读(6911) | 评论(0) | 转发(0) |