找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2535|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

STM32 NVIC編程模板

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:319895 發(fā)表于 2019-12-28 14:50 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
今天和大家聊聊什么是NVIC,NVIC全名也叫做嵌套向量控制器,看名字也就知道了它和中斷密不可分。它是ARM公司設(shè)計(jì)的內(nèi)核管理設(shè)備,因此各個(gè)廠商在使用的時(shí)候往往都各不相同,但是原理都差不多,我們今天討論的就是ST公司是在怎么使用的,這里大家最好看看M3/M4權(quán)威指南第7章,239頁。這里我就不說中斷的基本概念了,直接進(jìn)入主題。為什么要使用中斷?CPU的運(yùn)行有中斷和查詢,但是查詢的時(shí)候CPU一直工作,這樣一直占用CPU,而中斷來的時(shí)候,CPU檢查到了中斷標(biāo)志,就會(huì)立刻知道要有事情去處理。那么它就會(huì)去處理緊急的事情。這里就涉及到了優(yōu)先級(jí)的3種情況。

1)搶占優(yōu)先級(jí):看名字就知道它特別霸道,會(huì)從CPU手中去搶占資源,也就是高搶占優(yōu)先級(jí)會(huì)干擾低搶占優(yōu)先級(jí),也就是中斷嵌套。
2)響應(yīng)優(yōu)先級(jí):高響應(yīng)優(yōu)先級(jí)有優(yōu)先處理(同時(shí)到來),但是如果高響應(yīng)優(yōu)先級(jí)后來的話,那么對(duì)不起,你也要排隊(duì),等這個(gè)事情處理完,響應(yīng)優(yōu)先級(jí)沒有中斷嵌套。
3)自然優(yōu)先級(jí):有沒有響應(yīng)優(yōu)先級(jí),我們?cè)跀?shù)據(jù)手冊(cè)看到的中斷(除了內(nèi)核設(shè)備)都是自然優(yōu)先級(jí),我們可以通多NVIC來設(shè)置優(yōu)先級(jí)級(jí)別。

二:中斷的來源:1:外設(shè)比如定時(shí)器,串口等;2:中斷請(qǐng)求;3:系統(tǒng)滴答定時(shí)器;4:系統(tǒng)異常;5:軟件中斷?偣惨255個(gè)中斷來源,15個(gè)是系統(tǒng)異常,240個(gè)是外部中斷。

三:ARM公司設(shè)計(jì)NVIC:
some of the registers are saved onto the stack automatically                                                這段話表明了在處理中斷的時(shí)候,外了恢復(fù)中斷程序,ARM                                                                                                                                                  公司把一些寄存器保存到堆棧中,在返回的時(shí)候自動(dòng)恢復(fù),
when an exception is accepted, and are also automatically restored in an exception
return sequence. This mechanism allows the exception handlers to be written as
normal C functions without any additional software overhead.


Set up the priority level of the required interrupt (this step is optional)
• Enable the interrupt generation control in the peripheral that triggers the interrupt
• Enable the interrupt in the NVIC
這段話告訴我們:當(dāng)要使用中斷的時(shí)候,第一步:使用外部中斷的使能(就好比開時(shí)鐘一樣);第二步:設(shè)置中斷的優(yōu)先級(jí)級(jí)別;第3步:啟用NVIC的中斷。

四:優(yōu)先級(jí)級(jí)別有優(yōu)先級(jí)級(jí)別寄存器來控制,ARM公司一共有8位確定優(yōu)先級(jí)級(jí)別;但是ST公司只使用了4位;我們看看ST公司是在怎么確定優(yōu)先級(jí)級(jí)別的。
      看下面4個(gè)函數(shù)就知道了在CM4.h文件的1485頁。
1)void NVIC_EnableIRQ(IRQn_Type IRQn)   函數(shù)功能:NVIC中斷使能,函數(shù)參數(shù):IRQn_Type IRQn,中斷名:指明了是哪一個(gè)中斷


2)void NVIC_SetPriority (IRQn_Type IRQn,uint32_t priority) 1568頁:函數(shù)功能:設(shè)定優(yōu)先級(jí)級(jí)別,函數(shù)參數(shù):IRQn_Type IRQn,中斷名:指明了是哪一個(gè)中斷
uint32_t priority:中斷優(yōu)先級(jí)級(jí)別。
3)void NVIC_SetPriorityGrouping(uint32_tPriorityGroup)函數(shù)功能:設(shè)定優(yōu)先級(jí)分組(一個(gè)工程內(nèi)就只能用一次分組,如果多次分組,之前的分組就會(huì)無效)函數(shù)參數(shù):uint32_tPriorityGroup優(yōu)先級(jí)分組值 ===========(7-組編號(hào))


4)uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
{
  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */    //表示ST公司只用了4位
  uint32_t PreemptPriorityBits;                          //搶占優(yōu)先級(jí)位數(shù)
  uint32_t SubPriorityBits;                                  //響應(yīng)優(yōu)先級(jí)位數(shù)
  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;

return (
           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
         );






}
NVIC_PRIO_BITS:恒等于4

我們來分析這個(gè)函數(shù):函數(shù)功能:得到優(yōu)先級(jí)級(jí)別;函數(shù)參數(shù):uint32_t PriorityGroup;優(yōu)先級(jí)分組值;uint32_t PreemptPriority:搶占優(yōu)先級(jí)

uint32_t SubPriority:響應(yīng)優(yōu)先級(jí);
uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);  上面我們說過PriorityGroup=7-組邊號(hào),當(dāng)組邊號(hào)是0,PriorityGroupTmp=7;帶進(jìn)這一句話

PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;結(jié)果PreemptPriorityBits =0;表示搶占優(yōu)先級(jí)位數(shù)是0,響應(yīng)優(yōu)先級(jí)位數(shù)是4;返回的值是0和15.然后依次分析1,2 ,3,4。組。得到優(yōu)先級(jí)級(jí)別。


下面我們把這4個(gè)函數(shù)封裝成一個(gè)函數(shù)得到:


void My_NVIC_Init(IRQn_Type IRQn,u32 PG,u32 PP,u32 SP)
{

u32 priority;

NVIC_SetPriorityGrouping(PG);      //設(shè)定優(yōu)先級(jí)分組

priority=NVIC_EncodePriority (PG,PP,SP);  //得到優(yōu)先級(jí)級(jí)別
  
  NVIC_SetPriority (IRQn, priority);          //設(shè)定優(yōu)先級(jí)級(jí)別

NVIC_EnableIRQ (IRQn);                          /NVIC中斷使能。

}
接下來我會(huì)通過外部中斷實(shí)驗(yàn)來告訴你們?nèi)绾问褂眠@個(gè)NVIC函數(shù)。

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:170498 發(fā)表于 2020-1-15 20:41 | 只看該作者
不錯(cuò)不錯(cuò),看明白了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表