GD32自學筆記:5.定時器中斷

? ? ? ? 定時器中斷功能主要是兩點:

????????1.怎么配置的定時器中斷時間間隔;

????????2.中斷里長什么樣

一、定時器中斷配置函數

? ? ? ? 直接在bsp_basic_timer.c里找到下面函數:

void basic_timer_config(uint16_t pre,uint16_t per)
{/* ò????ü?úμ?ê±??T = 1/f, ?¨ê±ê±??time = T * ?ü?úéè?¤·??μ?μ??pre,?ü?ú??pertime = (pre + 1) * (per + 1) / psc_clk*/timer_parameter_struct timere_initpara; 							// ?¨ò??¨ê±?÷?á11ì?/* ?a??ê±?ó */rcu_periph_clock_enable(BSP_TIMER_RCU); 							// ?a???¨ê±?÷ê±?ó/* CK_TIMERx = 4 x CK_APB1  = 4x50M = 200MHZ */rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4); // ?????¨ê±?÷ê±?ótimer_deinit(BSP_TIMER);														  // ?′???¨ê±?÷/* ?????¨ê±?÷2?êy */timere_initpara.prescaler = pre-1;                    //  ê±?ó?¤·??μ?μ 0-65535   psc_clk = CK_TIMER / pretimere_initpara.alignedmode = TIMER_COUNTER_EDGE;     // ±??μ????                  timere_initpara.counterdirection = TIMER_COUNTER_UP;  // ?òé???êy    timere_initpara.period = per-1;                       // ?ü?ú  /* ?úê?è?2???μ?ê±oòê1ó?  êy×???2¨?÷ê1ó?μ?2é?ù?μ?ê????μ?·??μ±èày */timere_initpara.clockdivision = TIMER_CKDIV_DIV1;     // ·??μòò×ó         /* ??óD?????¨ê±?÷2?óD ?????ax£??í???′x+1′???è??D?? */    timere_initpara.repetitioncounter = 0;							  // ???′??êy?÷ 0-255  timer_init(BSP_TIMER,&timere_initpara);								// 3?ê??ˉ?¨ê±?÷/* ?????D??ó??è?? */nvic_irq_enable(BSP_TIMER_IRQ,3,2); 									// éè???D??ó??è???a 3,2/* ê1?ü?D?? */timer_interrupt_enable(BSP_TIMER,TIMER_INT_UP);       // ê1?ü?üD?ê??t?D?? /* ê1?ü?¨ê±?÷ */timer_enable(BSP_TIMER);
}

????????定時器中斷初始化流程:

  1. 啟用定時器時鐘

    • 代碼rcu_periph_clock_enable(BSP_TIMER_RCU);
    • 功能:開啟定時器模塊的時鐘(BSP_TIMER_RCU?定義了具體定時器外設,如 TIMER0)。
    • 說明:通過 RCU(Reset and Clock Unit)模塊為定時器提供時鐘信號。
  2. 配置定時器時鐘分頻

    • 代碼rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
    • 功能:設置定時器時鐘為 APB1 時鐘的 4 倍(4 × 50MHz = 200MHz)。
    • 說明:定時器時鐘頻率(CK_TIMER)決定計數速度,影響定時精度。
  3. 復位定時器

    • 代碼timer_deinit(BSP_TIMER);
    • 功能:將定時器寄存器復位到默認狀態,確保無殘留配置。
    • 說明:清除之前的配置,為新設置做準備。
  4. 配置定時器參數

    • 代碼
      timer_parameter_struct timere_initpara; timere_initpara.prescaler = pre-1; // 預分頻值 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?timere_initpara.alignedmode = TIMER_COUNTER_EDGE; // 邊沿對齊 timere_initpara.counterdirection = TIMER_COUNTER_UP; // 向上計數 timere_initpara.period = per-1; // 周期? ? ? ? ? ? ? ? ? ? timere_initpara.clockdivision = TIMER_CKDIV_DIV1; // 時鐘分頻因子 timere_initpara.repetitioncounter = 0; // 重復計數器? ? ? ? ? ? timer_init(BSP_TIMER, &timere_initpara);
    • 功能
      • 定義并初始化定時器參數結構體?timer_parameter_struct
      • 設置預分頻值 (pre-1),定時器計數頻率 = CK_TIMER / (pre)。
      • 配置為邊沿對齊模式(TIMER_COUNTER_EDGE)和向上計數(TIMER_COUNTER_UP)。
      • 設置周期值 (per-1),決定定時器溢出周期,定時時間 = (pre × per) / CK_TIMER。
      • 時鐘分頻因子為 1(TIMER_CKDIV_DIV1),不額外分頻。
      • 重復計數器為 0(repetitioncounter = 0),無重復計數,適用于基本定時器。
      • 調用?timer_init?初始化定時器寄存器。
    • 說明定時時間計算公式為?time = (pre × per) / CK_TIMER,例如,若?pre=20000,?per=10000, CK_TIMER=200MHz,則?time = (20000 × 10000) / 200,000,000 = 1秒
  5. 配置中斷優先級

    • 代碼nvic_irq_enable(BSP_TIMER_IRQ, 3, 2);
    • 功能:啟用定時器中斷(BSP_TIMER_IRQ),設置 NVIC 中斷優先級為搶占優先級 3,子優先級 2。
    • 說明:確保定時器中斷能夠被 CPU 響應,優先級決定中斷處理順序。
  6. 使能定時器更新中斷

    • 代碼timer_interrupt_enable(BSP_TIMER, TIMER_INT_UP);
    • 功能:啟用定時器更新事件中斷(TIMER_INT_UP),當計數器溢出時觸發中斷。
    • 說明:更新事件發生在計數器達到?per-1?并溢出時,觸發中斷處理程序。
  7. 啟動定時器

    • 代碼timer_enable(BSP_TIMER);
    • 功能:使能定時器,開始計數。
    • 說明:定時器按照配置的頻率和周期運行,定期觸發中斷。

二、中斷函數

? ? ? ? 同樣在bsp_basic_timer.c中的中斷函數如下:

void BSP_TIMER_IRQHANDLER(void)
{/* ?aà?ê??¨ê±?÷?D?? */if(timer_interrupt_flag_get(BSP_TIMER,TIMER_INT_FLAG_UP) == SET){timer_interrupt_flag_clear(BSP_TIMER,TIMER_INT_FLAG_UP);  // ??3y?D??±ê???? /* ?′DD1|?ü */gpio_bit_toggle(PORT_LED2,PIN_LED2);                      // ·-×aledprintf("BSP_TIMER_IRQHANDLER!\r\n");          						// ′??ú′òó?BSP_TIMER_IRQHANDLER!}
}

? ? ? ? 定時器中斷函數在執行功能前主要進行了兩個操作:

  1. 檢查中斷標志

    • 代碼if(timer_interrupt_flag_get(BSP_TIMER, TIMER_INT_FLAG_UP) == SET)
    • 功能:檢查定時器?BSP_TIMER?的更新中斷標志位(TIMER_INT_FLAG_UP)是否置位(SET)。
    • 說明
      • 更新中斷標志在定時器計數器溢出時自動置位,表示一次定時周期完成。
      • 條件判斷確保只處理更新中斷,避免誤處理其他中斷類型。
      • BSP_TIMER?是預定義的定時器,此處對應的是TIMER5,由歷史會話中的?basic_timer_config?配置。

  1. 清除中斷標志

    • 代碼timer_interrupt_flag_clear(BSP_TIMER, TIMER_INT_FLAG_UP);
    • 功能:清除定時器的更新中斷標志位。
    • 說明
      • 清除標志位以確保下一次中斷能夠正確觸發。
      • 如果不清除,中斷可能持續觸發,導致程序異常或死鎖。
      • 這是中斷服務函數的標準操作,防止重復進入中斷。

三、如何調用

? ? ? ? 在main.c里面只需要配置一下?basic_timer_config函數就行,調用代碼如下:

basic_timer_config(20000,10000);  // ?¨ê±?÷3?ê??ˉ
  • 定時時間公式:time = (pre × per) / CK_TIMER
  • 代入參數
    pre = 20000 (實際預分頻系數 19999 + 1)
  • per = 10000 (實際周期 9999 + 1)
  • CK_TIMER = 200,000,000 Hz
  • time = (20000 × 10000) / 200,000,000 = 200,000,000 / 200,000,000 = 1 秒

? ? ? ? 運行后可以看到串口一直在輸出:

? ? ? ? 并且開發板上對應的LED2在閃爍

四、思考

為什么常常使用ADC時不直接放在?while(1)?主循環中使用?delay?控制采樣間隔?

? ? ? ? 不是不行,也可以,但是:

  1. 延時不精確,受主循環影響

    • 在主循環中使用?delay_ms(500)?等軟件延時函數時,延時基于 CPU 空閑循環(如空指令循環)實現,但實際時間會因編譯優化、系統時鐘偏差或中斷干擾而抖動(例如,串口中斷或 GPIO 操作可能打斷延時,導致采樣間隔不均勻)。
    • 問題:采樣間隔(如每 500ms 采樣一次)無法嚴格控制,可能導致數據采集不均勻,影響信號處理精度(如歷史會話中提到的 ADC 采樣)。
    • 示例:若主循環中插入其他任務(如 LED 控制),延時函數會阻塞整個 CPU,造成采樣時機漂移。
  2. 阻塞主循環,降低系統響應性

    • delay?是“忙等待”(busy-waiting),CPU 在延時期間完全閑置,無法處理其他任務(如用戶輸入、通信或外設事件)。
    • 問題:在多任務環境中(如實時控制系統),主循環被阻塞會導致系統響應遲鈍,甚至錯過關鍵事件。例如,定時器中斷每 1 秒觸發 LED 翻轉,若也需要ADC 采樣用?delay?阻塞 500ms,主循環就無法及時響應其他中斷。
    • 效率低:CPU 利用率低下,浪費資源,尤其在低功耗應用中不友好。
  3. 不適合實時性和周期性要求

    • ADC 采樣往往需要固定間隔(如傳感器數據采集),主循環的軟件延時無法保證硬件級精度,受溫度、電壓等因素影響。
    • 問題:在高速采樣場景(如音頻或電機控制),間隔抖動可能導致數據失真或系統不穩定。若 ADC 采樣直接用?delay,與定時器中斷(1 秒間隔)沖突,可能干擾整體流程。

為什么ADC采樣常放到定時器中斷中?

  1. 精確的硬件定時

    • 定時器使用硬件計數器(如?basic_timer_config(20000, 10000)?配置 1 秒間隔),基于系統時鐘(CK_TIMER = 200MHz)精確控制中斷觸發時機,間隔誤差極小(納秒級)。
    • 優勢:不受主循環影響,確保 ADC 采樣嚴格周期性(如每 500ms 觸發一次),提高數據一致性和精度。定時器可自動重載,無需軟件干預。
  2. 非阻塞執行,提高系統效率

    • 中斷服務函數(如?BSP_TIMER_IRQHANDLER)在定時器溢出時自動調用,執行 ADC 采樣后快速返回,主循環繼續運行其他任務。
    • 優勢:避免阻塞,支持多任務并行。例如,歷史會話中定時器中斷可用于 ADC 觸發采樣,同時主循環處理串口輸出或 LED 控制,CPU 利用率高。結合 DMA(直接內存訪問)可進一步自動化數據傳輸,減少 CPU 負擔。
  3. 增強實時性和可擴展性

    • 中斷優先級機制(如 NVIC 設置搶占優先級 3)確保 ADC 采樣及時響應,適用于實時系統(如工業控制)。
    • 優勢:易于調整間隔(修改?pre?和?per?參數),并支持多通道采樣(如定時器觸發 ADC 多通道)。1 秒中斷可擴展為 500ms ADC 采樣,結合?timer_interrupt_enable(BSP_TIMER, TIMER_INT_UP)?實現周期觸發。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95948.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95948.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95948.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Godot入門大全]目錄

1 免責聲明 資源分享免責聲明: 本平臺/本人所分享的各類資源(包括但不限于文字、圖片、音頻、視頻、文檔等),均來源于公開網絡環境中的可分享內容或已獲授權的傳播素材。 本平臺/本人僅出于信息交流、資源共享之目的進行傳播&…

使用 StringRedisTemplate 實現 ZSet 滾動查詢(處理相同分數場景)

1. 為什么需要改進當 ZSet 中存在相同分數 (score) 的元素時,單純使用分數作為偏移會導致數據漏查或重復。例如:多條記錄具有相同時間戳(作為分數)分頁查詢時可能跳過相同分數的元素或重復查詢相同分數的元素改進方案:…

【Android】安裝2025版AndroidStudio開發工具開發老安卓舊版App

為了開發老舊的安卓App,這里記錄一下2025版AndroidStudio的安裝過程,如果卸載以后,可以按照此文章的步驟順利重新安裝繼續使用。 文章目錄安裝包Android SDK新建項目新建頁面構建項目Gradle下載失敗構建失敗構建完成編譯失敗安裝失敗關于APP在…

Python跳過可迭代對象前部元素完全指南:從基礎到高并發系統實戰

引言:跳過前部元素的核心價值在數據處理和系統開發中,跳過可迭代對象的前部元素是常見且關鍵的操作。根據2024年數據處理報告:92%的數據清洗需要跳過文件頭部85%的日志分析需要忽略初始記錄78%的網絡協議處理需跳過頭部信息65%的機器學習訓練…

ConcurrentHashMap擴容機制

ConcurrentHashMap的擴容為了提高效率,是多線程并發的每個線程控制一部分范圍節點的擴容(根據cpu與數組長度確定控制多大范圍)有兩個核心參數sizeCtl:標記擴容狀態 負數時代表正在擴容,存儲量參與擴容的線程數,正數代表出發擴容的…

Spring Cloud Gateway 進行集群化部署

如果將 Gateway 單獨部署為一個服務而不做任何高可用處理,它確實會成為一個單點故障(SPOF, Single Point of Failure)。如果這個唯一的 Gateway 實例因為服務器宕機、應用崩潰、部署更新或其他任何原因而不可用,那么整個系統的所有…

計算機網絡:以太網中的數據傳輸

以太網中,數據的傳輸依賴于一系列標準化的技術規范,核心包括幀結構封裝、介質訪問控制機制和物理層編碼技術,具體如下: 1. 以“幀(Frame)”為基本傳輸單元 以太網在數據鏈路層將網絡層的數據包(…

元器件--USB TypC接口

USB TypC接口下圖這些都是USB接口A口與B口的區別USB A口和B口最初由USB-IF在1996年引入。根據當時的USB協議,A口主要用于主設備(如電腦),而B口則用于從設備(如打印機和攝像頭)。隨著USB-C接口的日益普及&am…

多線程之HardCodedTarget(type=OssFileClient, name=file, url=http://file)異常

多線程之HardCodedTarget(typeOssFileClient, namefile, urlhttp://file)異常 摘要: 文檔描述了多線程環境下調用Feign客戶端OssFileClient時出現的HardCodedTarget異常。異常發生在異步保存文件到ES時,Feign調用未返回預期結果而直接打印了客戶端對象。…

計算機視覺(十二):人工智能、機器學習與深度學習

人工智能 (AI):宏大的目標 人工智能是最廣泛、最宏大的概念,它的目標是讓機器能夠模仿人類的智能行為,例如: 推理:像下棋程序一樣,通過邏輯來做決策。規劃:為實現一個目標而制定步驟&#xff0c…

容器元素的滾動條回到頂部

關閉再打開后,容器元素的滾動條回到頂部解決方法:1、通過打開開發者工具(F12),找到滾動條所屬元素為 el-textarea__inner,其父類 class"el-textarea content"2、代碼,通過元素的方法 …

分布式專題——2 深入理解Redis線程模型

1 Redis 簡介 1.1 Redis 是什么? Redis 全稱 Remote Dictionary Server(遠程字典服務),是一個開源的高性能 Key-Value 數據庫; 官網:Redis - The Real-time Data Platform; 引用官網上的?個…

simd學習

如何查看cpu是否支持simd?# 檢查特定指令集 grep -o avx2 /proc/cpuinfo | head -1 # 檢查AVX2 grep -o sse4 /proc/cpuinfo | head -1 # 檢查SSE4 grep -o avx512 /proc/cpuinfo | head -1 # 檢查AVX512gcc編譯選項,增加支持simd-mavx2 -D__AVX2__SS…

LabVIEW汽車發動機振動測試

以某型號四缸汽油發動機為測試對象,借助 LabVIEW 平臺與高精度數據采集硬件,開展發動機全工況振動測試。通過實時采集缸體、曲軸箱關鍵部位振動信號,分析振動特征與故障關聯,驗證發動機運行穩定性,為后期優化設計提供數…

android 四大組件—Service

啟動服務startService//啟動服務,通過類名 Intent intent new Intent(this, WiFiAutoLinkService.class); startService(intent); //通過字符串啟動 Intent intent new Intent(); intent.setAction("com.launcher.app"); intent.setPackage("com.l…

https + 域名 + 客戶端證書訪問模式

項目使用金融云部署,對外暴露IP訪問,因安全合規要求必須使用域名訪問,但公司又不提供域名。故,改為 https 域名 客戶端證書雙向認證 訪問模式,大大提升安全性。 1. 密鑰文件類型 .key、.csr、.cer(或 .cr…

ICPC 2023 Nanjing R L 題 Elevator

[ProblemDiscription]\color{blue}{\texttt{[Problem Discription]}}[Problem Discription] 來源:洛谷。侵權則刪。 [Analysis]\color{blue}{\texttt{[Analysis]}}[Analysis] 貪心。優先運送樓層高的貨物,在能裝下的情況下盡量多裝。 因為運送貨物的代價…

81-dify案例分享-零代碼用 Dify 使用夢 AI 3.0 多模態模型,免費生成影視級視頻

1.前言 即夢AI作為字節跳動旗下的AI繪畫與視頻生成平臺,近年來不斷推出新的模型和功能,以提升用戶體驗和創作能力。 即夢AI 3.0是即夢AI的最新版本,于2025年4月發布,標志著其在中文生圖模型上的重大升級。該版本不僅在中文生圖能…

SQL 進階指南:視圖的創建與使用(視圖語法 / 作用 / 權限控制)

在 SQL 操作中,你是否遇到過 “頻繁查詢多表關聯的固定結果”“不想讓他人看到表中的敏感字段” 這類問題?比如 “每周都要查‘技術部員工的姓名、職位、薪資’”,每次都寫多表關聯語句很麻煩;又比如 “給實習生開放數據查詢權限&…

【全部更新完畢】2025數學建模國賽C題思路代碼文章高教社杯全國大學生數學建模-NIPT 的時點選擇與胎兒的異常判定

B題全部更新完畢 包含完整的文章全部問題的代碼、結果、圖表 完整內容請看文末最后的推廣群NIPT 的時點選擇與胎兒的異常判定 摘要 在問題一中,我們以無創產前檢測(NIPT)數據為研究對象,圍繞“胎兒 Y 染色體濃度”(記為 (V)) 隨孕…