一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

關(guān)于SYSTICK的COUNTFLAG標(biāo)志的小疑惑

茶話MCU ? 來源:茶話MCU ? 2023-03-26 14:48 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前不久在研究SYSTICK有關(guān)問題閱讀相關(guān)技術(shù)資料時,無意間產(chǎn)生了個小疑惑。

問題是這樣的,我們知道SYSTICK定時器是個24位向下計數(shù)器,每當(dāng)發(fā)生從1記到0時會讓一個名為COUNTFLAG的標(biāo)志位置1,如果此時SYSTICK的滴答中斷請求使能了的話,可以對CPU發(fā)起中斷請求。

543c497a-cba0-11ed-bfe3-dac502259ad0.png

根據(jù)我們平常STM32的開發(fā)經(jīng)驗,通常各種外設(shè)事件發(fā)起中斷請求時,往往有相應(yīng)的事件標(biāo)志跟中斷響應(yīng)關(guān)聯(lián),在中斷服務(wù)程序里并將相關(guān)事件標(biāo)志做清零操作,否則它會沒完沒了地發(fā)起中斷請求?;谶@點,我想這個COUNTFLAG標(biāo)志應(yīng)該也是跟SYSTICK中斷密切相關(guān),溢出時被置位,在SYSTICK中斷服務(wù)程序里將其清零。

可是,我們平常的SYSTICK的中斷服務(wù)程序里根本沒看到哪里有對COUNTFLAG標(biāo)志做清零。ARM Cortex內(nèi)核手冊針對COUNTFLAG標(biāo)志的描述中涉及它可以清零的地方有兩處:

5470fa08-cba0-11ed-bfe3-dac502259ad0.png

第一個地方是在SYSTICK控制寄存器【SYST_CSR】里有介紹,讀它可以清零。說實在的,這點我是通過咨詢ARM公司才理解到位的。第二個地方是在介紹SYSTCIK的當(dāng)前計數(shù)器寄存器時提到,即對當(dāng)前計數(shù)器寄存器進(jìn)行寫操作時也會將COUNTFLAG標(biāo)志清零。

問題是平常的SYSTICK的中斷服務(wù)程序里根本就沒有涉及到上面提到的可能對COUNTFLAG標(biāo)志清零的操作?。?!既沒有讀SYSTICK控制寄存器,也沒有對計數(shù)器做寫操作。那這個標(biāo)志啥時候被清零的呢?如果不清零的話,難道不會沒完沒了地申請中斷,可現(xiàn)在的實踐結(jié)果又不是這樣的!

后來,找同事咨詢、討論,有同事說他印象中計數(shù)器重裝時會將該標(biāo)志清零。如果說重裝可以清COUNTFLAG的話,這樣可以很好地解釋目前的結(jié)果。因為既然每次重裝可以清零,自然用不著到中斷服務(wù)程序里再做清零,那么在中斷服務(wù)程序里見不到對COUNTFLAG的清零操作也就再正常不過了。也因此一時以為找到了答案。可后來一想,還是有些不對勁的地方。至少有2點說不通。

第一、如果是重裝時清零,該標(biāo)志是溢出時被置1的,而溢出和重裝兩個動作可以看成同一時刻完成,即置位后馬上被清零。這樣的話,用戶永遠(yuǎn)沒有機(jī)會見到該標(biāo)志為1的時候。何時能被軟件用得上呢?定義這個標(biāo)志意義何在呢?

第二、關(guān)于這個標(biāo)志,在ARM 內(nèi)核手冊里還說了下面一句話:

54890b5c-cba0-11ed-bfe3-dac502259ad0.png

意思就是說用戶軟件可以通過查看COUNTFLAG標(biāo)志來確認(rèn)SYSTICK之前有發(fā)生過溢出。如果重裝可以清零的話,用戶軟件是不可能有機(jī)會讀到該標(biāo)志為1的時候。也就是說重裝清零結(jié)論跟這句話是矛盾的。

經(jīng)過與同事的來回討論,以及查找其它相關(guān)信息,后來認(rèn)為這個標(biāo)志可能跟中斷沒有必然關(guān)系。這個過程中我也意識到我提出這個標(biāo)志哪里清零的問題,可能是先入為主的慣性思維在作怪。具體點說,我們認(rèn)為這個COUNTFLAG標(biāo)志在發(fā)生溢出時置位沒問題,前面提到的兩種情形下會被清零也沒問題。但是,SYSTICK的滴答中斷不跟這個標(biāo)志位關(guān)聯(lián),它只與計數(shù)器發(fā)生從1計到0的事件有關(guān),即手冊中下面綠色方框框住的這句話。

54b1a2a6-cba0-11ed-bfe3-dac502259ad0.png

說實在的,這句話我老早就看到了,只是覺得溢出做為中斷觸發(fā)條件沒錯,但一門心思老糾結(jié)著哪個地方對COUNTFLAG清零了。

如果說COUNTFLAG只是個溢出事件標(biāo)志,滴答中斷不跟它關(guān)聯(lián)也是可以理解和接受的。首先,根據(jù)ARM手冊描述來理解這個結(jié)論沒有問題,沒有說不通的地方,然后,實現(xiàn)邏輯上也沒啥問題,反正溢出一次就申請一次中斷。

聊到這里,很多STM32用戶【包括本人在內(nèi)】可能會覺得有點別扭或不習(xí)慣,這點我們下面繼續(xù)聊。我就我們針對COUNTFLAG標(biāo)志跟SYSTICK中斷的關(guān)系的理解,說得直白點就是SYSTICK中斷跟COUNTFLAG有無關(guān)系、服務(wù)程序里要不要清零再次找ARM公司做了確認(rèn),他們完全認(rèn)同我們的理解。即COUNTFLAG只是個溢出事件標(biāo)志,SYSTICK中斷不跟它關(guān)聯(lián),只與計數(shù)器溢出事件本身關(guān)聯(lián),并不關(guān)心COUNTFLAG的值是0還是1。到此,關(guān)于COUNTFLAG要不要在服務(wù)程序里清零的疑惑算是塵埃落定。

但是------

用過STM32外設(shè)事件申請中斷的人應(yīng)該很清晰地知道,要想各個外設(shè)事件中斷申請能得到響應(yīng)的話,除了NVIC端接受響應(yīng)、外設(shè)端允許申請中斷外,還得有相應(yīng)的事件發(fā)生【包括軟件方式】以及對應(yīng)的事件標(biāo)志被置位【或者說應(yīng)該有效】,中斷服務(wù)程序跟相應(yīng)事件標(biāo)志直接相關(guān),即發(fā)生中斷響應(yīng)時中斷事件標(biāo)志必須有效,并需在中斷服務(wù)程序里對標(biāo)志清零,否則會沒完沒了地申請中斷、響應(yīng)中斷。顯然,這個過程跟前面SYSTICK中斷有點不一樣。SYSTICK中斷雖然設(shè)置了溢出事件標(biāo)志,但其中斷并沒有跟該標(biāo)志關(guān)聯(lián)起來。事實上這樣運行起來也沒有任何問題,那么ST設(shè)計的外設(shè)申請中斷怎么非要跟標(biāo)志位關(guān)聯(lián)在一起呢?我們平常做STM32開發(fā)時,有時因為疏忽或原理不夠清晰,沒及時清零中斷請求標(biāo)志讓CPU沒完沒了地進(jìn)中斷而陷入異常。

why?

整體上,STM32微控制器是由ARM處理器和ST外設(shè)集成而來,ARM 處理器又包括內(nèi)核、核外設(shè)【以示區(qū)別于ST公司設(shè)計的外設(shè)】。其中SYSTICK、FPU、MPU、NVIC等均屬于核外設(shè)。也就是說,SYSTICK是ARM的外設(shè),不是ST設(shè)計的。既然這樣,難道只是設(shè)計思路上的差異?但是,SYSTICK中斷可以不跟事件標(biāo)志關(guān)聯(lián)起來,可以行得通,為什么ST不也這樣設(shè)計呢?

一起來看看,嘗試找找原因。

原因在于SYSTICK外設(shè)就一個溢出事件可以申請中斷,在NVIC那邊獨立對應(yīng)一個中斷請求號【IRQ#],所以CPU在響應(yīng)SYSTICK中斷時根本無需關(guān)注那個溢出標(biāo)志,有那個溢出事件就夠了,因為除了這個溢出事件沒別的事件來申請TICK中斷。

【下圖是來自STM32G4參考手冊里有關(guān)中斷矢量表的部分截圖】

54fdd7f2-cba0-11ed-bfe3-dac502259ad0.png

而ST的外設(shè)申請中斷時就沒有SYSTICK那么好的福分了。往往是一個外設(shè)的多個事件共用1個中斷請求。比方以上面STM32G4系列ADC3的中斷來看,因為它只有1個中斷申請?zhí)?,在CPU看來就一個中斷入口,即所有ADC3相關(guān)事件觸發(fā)的中斷共用一個中斷服務(wù)程序入口,但可以申請中斷的事件可多了,見下圖【我后面把能觸發(fā)同一中斷請求的事件稱之為兄弟事件】:

55265970-cba0-11ed-bfe3-dac502259ad0.png

再以SPI3和LPTIM1的中斷為例,它倆也各只有一個中斷請求號,同樣可以申請中斷的事件也不少,分別見下面兩幅圖。

55387524-cba0-11ed-bfe3-dac502259ad0.png

554f0adc-cba0-11ed-bfe3-dac502259ad0.png

顯然,ST設(shè)計的外設(shè)不能照搬SYSTICK的玩法。如果中斷服務(wù)程序不跟觸發(fā)事件標(biāo)志關(guān)聯(lián)起來,進(jìn)了中斷就不知該基于哪個事件來運行程序;基于某個事件運行了中斷服務(wù)程序若不對它清零【包括讀清零、寫清零等】,等兄弟事件觸發(fā)再進(jìn)來時如何分得清哪是過時事件、哪是新觸發(fā)的即時事件?

或許有人會說,為什么不給每個ST外設(shè)事件都安排一個中斷請求號呢?這要考慮到必要性和中斷請求號的有限性。不難理解必要性并不強(qiáng),目前ST的設(shè)計其實沒有啥不合理的地方。另外,內(nèi)核開放的中斷請求號數(shù)目是也有限的,視不同內(nèi)核而定。

今天的話題就聊到這里,該問題屬于好奇型的,即使不知道問題原因,一般也不會影響到我們平常的STM32開發(fā)。探究下也就是滿足下好奇心,讓內(nèi)心偶爾掀起一陣漣漪,給生活增添一抹色彩。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11080

    瀏覽量

    217155
  • STM32
    +關(guān)注

    關(guān)注

    2293

    文章

    11032

    瀏覽量

    365150
  • 計數(shù)器
    +關(guān)注

    關(guān)注

    32

    文章

    2291

    瀏覽量

    96438
  • 中斷
    +關(guān)注

    關(guān)注

    5

    文章

    905

    瀏覽量

    42816
  • Systick
    +關(guān)注

    關(guān)注

    0

    文章

    63

    瀏覽量

    13602

原文標(biāo)題:關(guān)于SYSTICK的COUNTFLAG標(biāo)志的小疑惑

文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    使用RTOS還能調(diào)用LL_mDelay延時函數(shù)嗎?

    如題,未學(xué)習(xí)研究過RTOS,不太清楚調(diào)用滴答定時器的情況,是不是不能判斷到SysTick_CTRL_COUNTFLAG_Msk標(biāo)志? void LL_mDelay(uint32_t Delay
    發(fā)表于 03-14 07:08

    求助,關(guān)于systick_ctrl寄存器設(shè)置與COUNTFLAG標(biāo)志位使用關(guān)系的疑問求解

    ,bit0位為011,也就是8分頻,開中斷,開始計數(shù),那么我在主函數(shù)里面使用的采用判斷標(biāo)志COUNTFLAG=1寫的那個while函數(shù)就進(jìn)不去里面那個等于1這個判斷函數(shù),就是我圖中的if函數(shù),如果把ctrl寄存器設(shè)置成為0x01也就是8分頻,不開中斷,開始計數(shù),那就能進(jìn)
    發(fā)表于 04-29 06:00

    求助關(guān)于SysTick程序的疑惑求解

    關(guān)于SysTick 程序的疑惑
    發(fā)表于 05-16 08:04

    【STM32F411 Nucleo試用體驗】+systick定時器

    (0:使用HCLK/8 作為Systick時鐘;1:使用HCLK作為Systick時鐘) 第3位:COUNTFLAG,Systick計數(shù)比較標(biāo)志
    發(fā)表于 06-01 18:11

    Systick相關(guān)寄存器和庫函數(shù)的疑惑

    當(dāng)前值寄存器中CURRENT的描述:寫它則使之清零,同時還會清除在SysTick控制及狀態(tài)寄存器中的COUNTFLAG標(biāo)志。那COUNTFALG是在被讀取為1后自動清零還是在CURRENT被清零后
    發(fā)表于 08-28 10:53

    請問下面A處的SysTick->VAL =0x00; 是否可以不要?

    請教SysTick的幾個問題。1.下面A處的SysTick->VAL =0x00;是否可以不要的?不是啟動倒數(shù)后,VAL的值就變了的嗎?至于寫VAL時會清COUNTFLAG標(biāo)志,但這個
    發(fā)表于 10-23 03:21

    配置SYSTICK

    SysTick_Handler中也無需對中斷標(biāo)志進(jìn)行清零(參考exit外部中斷服務(wù)函數(shù))2.要注意的是關(guān)于systick其實有兩個關(guān)鍵函數(shù),SyST
    發(fā)表于 08-17 06:22

    SysTick計數(shù)器有哪些應(yīng)用呢

    后, 每經(jīng)過1個系統(tǒng)時鐘周期,計數(shù)值就減1。計數(shù)到0時,SysTick計數(shù)器自動重裝初值并繼續(xù)計數(shù),同時內(nèi)部的 COUNTFLAG 標(biāo)志會置位,觸發(fā)中斷(如果中斷使能)。在 STM32 的應(yīng)用中,使用 Cortex-M3 內(nèi)核的
    發(fā)表于 12-07 09:37

    Systick寄存器的相關(guān)資料下載

    使能(是否啟用)TICKINT用來設(shè)置當(dāng)計時到0的時候是否要進(jìn)入中斷如果為0就RELOAD初值不斷循環(huán)如果為1就進(jìn)入中斷當(dāng)然,不中斷也可以通過標(biāo)志位來判斷第16位的COUNTFLAG就相當(dāng)于51中的標(biāo)志位當(dāng)數(shù)到0的時候,這一位會
    發(fā)表于 01-05 07:08

    SysTick寄存器介紹

    設(shè)置系統(tǒng)時鐘SYSCLK 等于72M。當(dāng)重裝載數(shù)值寄存器的值遞減到0 的時候,系統(tǒng)定時器就產(chǎn)生一次中斷,以此循環(huán)往復(fù)。SysTick 寄存器介紹SysTick—系統(tǒng)定時器有4 個寄存器。1、CTRL SysTick 控制及狀態(tài)寄
    發(fā)表于 01-21 11:37

    SysTick系統(tǒng)定時器相關(guān)資料下載

    的24次方。遞減計數(shù)器在時鐘的驅(qū)動下,從重裝載寄存器的初值開始往下遞減計數(shù)到0,到0后產(chǎn)生中斷,同時置位COUNTFLAG標(biāo)志位(在STK_CTRL寄存器),然后重裝載寄存器重新開始遞減計數(shù),如此循環(huán)。STK_CTRL寄存器SysTic
    發(fā)表于 02-18 06:51

    使用RTOS還能調(diào)用LL_mDelay這個延時函數(shù)嗎?

    如題,未學(xué)習(xí)研究過RTOS,不太清楚調(diào)用滴答定時器的情況,是不是不能判斷到SysTick_CTRL_COUNTFLAG_Msk標(biāo)志? void LL_mDelay(uint32_t Delay
    發(fā)表于 08-08 06:36

    STM32—關(guān)于SYSTICK系統(tǒng)時鐘的詳解及學(xué)習(xí)筆記

    SysTick_Handler中也無需對中斷標(biāo)志進(jìn)行清零(參考exit外部中斷服務(wù)函數(shù))2.要注意的是關(guān)于systick其實有兩個關(guān)鍵函數(shù),SyST
    發(fā)表于 11-30 15:51 ?15次下載
    STM32—<b class='flag-5'>關(guān)于</b><b class='flag-5'>SYSTICK</b>系統(tǒng)時鐘的詳解及學(xué)習(xí)筆記

    SysTick——系統(tǒng)定時器

    的24次方。遞減計數(shù)器在時鐘的驅(qū)動下,從重裝載寄存器的初值開始往下遞減計數(shù)到0,到0后產(chǎn)生中斷,同時置位COUNTFLAG標(biāo)志位(在STK_CTRL寄存器),然后重裝載寄存器重新開始遞減計數(shù),如此循環(huán)。STK_CTRL寄存器SysTic
    發(fā)表于 12-23 19:57 ?1次下載
    <b class='flag-5'>SysTick</b>——系統(tǒng)定時器

    一個有關(guān)SYSTICK好奇的問題

    前不久在研究SYSTICK有關(guān)問題閱讀相關(guān)技術(shù)資料時,無意間產(chǎn)生了個小疑惑。 問題是這樣的,我們知道SYSTICK定時器是個24位向下計數(shù)器,每當(dāng)發(fā)生從1記到0時會讓一個名為COUNTFLAG
    的頭像 發(fā)表于 06-21 15:48 ?1042次閱讀