STM32-M0中斷優先級介紹


  先解釋中斷優先級,后面講代碼的實現。

  差異:M0的中斷優先級相比於M4,沒有用到分組,且只用到了2個bit位(即0~3)來設置,數值越小,優先級越高;同等優先級,根據終端號的大小來決定誰先執行。

  根據下面這張編程手冊里的圖來說明:

 

  從上往下看,共32個IRQ中斷,每個中斷優先級占8個位,一個寄存器存4個中斷的優先級,所以M0的IRQ中斷最多只有32個;表27中高亮部分,說的是只用高兩位來表示優先級的值,低六位填0,沒有用到。

  還有一個要提到的是word-accessible,就是寄存器只能按字操作。

  M0的中斷優先級就講完了,還是很簡單的,那我們講一下代碼的實現:

 

 1 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
 2 {
 3   uint32_t tmppriority = 0x00;
 4   
 5   /* Check the parameters */
 6   assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
 7   assert_param(IS_NVIC_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPriority));  
 8     
 9   if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
10   {
11     /* Compute the Corresponding IRQ Priority --------------------------------*/    
12     tmppriority = NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02];
13     tmppriority &= (uint32_t)(~(((uint32_t)0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)));
14     tmppriority |= (uint32_t)((((uint32_t)NVIC_InitStruct->NVIC_IRQChannelPriority << 6) & 0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8));    
15     
16     NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02] = tmppriority;
17     
18     /* Enable the Selected IRQ Channels --------------------------------------*/
19     NVIC->ISER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
20   }
21   else
22   {
23     /* Disable the Selected IRQ Channels -------------------------------------*/
24     NVIC->ICER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
25   }
26 }

  這段代碼是官方庫的代碼,我說下思路:

    1、要設置優先級,要先找到該中斷的優先級寄存器在哪個寄存器里,將中斷號除以4,得到對應寄存器,讀該寄存器的值給變量tmppriority ,代碼如下:

      tmppriority = NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02];

    2、再判斷該終端號的優先級值在對應寄存器的哪個位置,並清零該8位,共四個位置為:0~7、8~15、16~23、24~31,代碼如下,NVIC_InitStruct->NVIC_IRQChannel & 0x03表示對4求余的結果;

      tmppriority &= (uint32_t)(~(((uint32_t)0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)));

    3、接着給該8位寫入要設置的優先級的值,由於優先級只占了8位的高兩位,所以NVIC_InitStruct->NVIC_IRQChannelPriority << 6寫高兩位,再左移到在該寄存器中對應的位置,和讀到寄存器的值tmppriority 與運算,就完成了對該寄存器的對應位寫優先級值得操作,記住,這是一個32位的數;

      tmppriority |= (uint32_t)((((uint32_t)NVIC_InitStruct->NVIC_IRQChannelPriority << 6) & 0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)); 

    4、把這個32位的數寫入該寄存器中;  

      NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02] = tmppriority;

    廢話:((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8))這個語句是用來獲得在寄存器中的偏移值得,用這個偏移值就能把8位數進行左移。

完!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM