STM32_HAL庫提高中斷執行效率

目錄

  • 中斷流程分析
  • 我的解決辦法
  • 優缺點

大家都在說STM32 HAL 庫中斷效率低下。具體哪里不行?如何優化?
我手里的項目要用到多個定時器TIM6、TIM7、TIM9、TIM10、TIM11、TIM12、TIM13,在處理這些定時器中斷的時候,也發現了這個問題。
下面給出我的分析和解決辦法。

中斷流程分析

以TIM7 中斷流程分析,中斷條件滿足之后,單片機從中斷向量表中找中斷服務函數TIM7_IRQHandler,然后跳轉進去

; Vector Table Mapped to Address 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __VectorsEXPORT  __Vectors_EndEXPORT  __Vectors_Size__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault Handler
......                               DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                   DCD     TIM7_IRQHandler                   ; TIM7

TIM7_IRQHandler內容如下,從這里HAL庫開始接管

void TIM7_IRQHandler(void)
{/* USER CODE BEGIN TIM7_IRQn 0 *//* USER CODE END TIM7_IRQn 0 */HAL_TIM_IRQHandler(&htim7);/* USER CODE BEGIN TIM7_IRQn 1 *//* USER CODE END TIM7_IRQn 1 */
}

HAL_TIM_IRQHandler內容如下,為了方便閱讀做了刪減

	if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1)){/* Capture compare 1 event Process */}if ((itflag & (TIM_FLAG_CC2)) == (TIM_FLAG_CC2)){/* Capture compare 2 event Process */}if ((itflag & (TIM_FLAG_CC3)) == (TIM_FLAG_CC3)){/* Capture compare 3 event Process */}if ((itflag & (TIM_FLAG_CC4)) == (TIM_FLAG_CC4)){/* Capture compare 4 event Process */}if ((itflag & (TIM_FLAG_UPDATE)) == (TIM_FLAG_UPDATE)){/* TIM Update event Process *///我的定時器只用來做定時中斷,所以關注TIM_IT_UPDATE中斷if ((itsource & (TIM_IT_UPDATE)) == (TIM_IT_UPDATE)){//清除標志位__HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE);	#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)//如果啟用了回調函數注冊執行這里,實際上我們重寫下面一條語句的函數效果類似。htim->PeriodElapsedCallback(htim);#else//沒有啟用回調函數,執行這里。HAL_TIM_PeriodElapsedCallback是虛函數,用戶自行重寫HAL_TIM_PeriodElapsedCallback(htim);#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */}}if ((itflag & (TIM_FLAG_BREAK)) == (TIM_FLAG_BREAK)){/* TIM Break input event Process */}if ((itflag & (TIM_FLAG_TRIGGER)) == (TIM_FLAG_TRIGGER)){/* TIM Trigger detection event Process */}if ((itflag & (TIM_FLAG_COM)) == (TIM_FLAG_COM)){/* TIM commutation event Process */}

HAL_TIM_PeriodElapsedCallback的定義如下

/*** @brief  Period elapsed callback in non-blocking mode* @param  htim TIM handle* @retval None*/
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* Prevent unused argument(s) compilation warning */UNUSED(htim);/* NOTE : This function should not be modified, when the callback is needed,the HAL_TIM_PeriodElapsedCallback could be implemented in the user file*/
}

可以看出來,不同中斷公用一個最終的處理函數HAL_TIM_PeriodElapsedCallback,在該函數里用戶自己靠傳入的形參htim去區分是哪一個中斷觸發的。那么實際重寫HAL_TIM_PeriodElapsedCallback的時候,應該是如下結構

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim == htim6){} else if(htim == htim7){}else if(htim == htim9){}else if(htim == htim10){}......
}

這樣的處理方便倒是挺方便的,但是明顯的效率低下。主要體現如下兩部分:

  • 我不需要判斷那么多中斷事件,我對自己項目中定時器的作用非常清晰,不會用于做捕獲、從機等,也就不用判斷這些中斷事件。
  • 不同定時器公用一個回調函數,在回調函數內再區分,效率低下。原本不同的定時器就有不同的中斷服務函數的。
    在這里插入圖片描述

我的解決辦法

在TIM7_IRQHandler里寫應用,然后直接返回

void TIM7_IRQHandler(void)
{/* USER CODE BEGIN TIM7_IRQn 0 */if(TIMER_Group.callback[1])				TIMER_Group.callback[1]();return;/* USER CODE END TIM7_IRQn 0 */HAL_TIM_IRQHandler(&htim7);/* USER CODE BEGIN TIM7_IRQn 1 *//* USER CODE END TIM7_IRQn 1 */
}

callback指向的函數內容如下

static void hwtimer2_callback(void)
{/* some app*/__HAL_TIM_CLEAR_FLAG(htim7, TIM_IT_UPDATE);//手動清除標志位
}

優缺點

優點:解決了中斷效率低下的問題
缺點1:return后面HAL_TIM_IRQHandler(&htim7);任然參與編譯,可能占用更多的Flash空間
缺點2:因為HAL_TIM_IRQHandler(&htim7);代碼不可到達,會報

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

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

相關文章

RabbitMQ惰性隊列的工作原理、消息持久化機制、同步刷盤的概念、延遲插件的使用方法

惰性隊列工作原理 惰性隊列通過盡可能多地將消息存儲到磁盤上來減少內存的使用。與傳統隊列相比,惰性隊列不會主動將消息加載到內存中,而是盡量讓消息停留在磁盤上,從而降低內存占用。盡管如此,它并不保證所有操作都是同步寫入磁…

Spark Core(二)

Spark-Core編程(二) RDD轉換算子 RDD 根據數據處理方式的不同將算子整體上分為 Value 類型、雙 Value 類型和 Key-Value 類型 Value類型 1)map 將處理的數據逐條進行映射轉換,這里的轉換可以是類型的轉換,也可以是…

C#打開文件及目錄腳本

如果每天開始工作前都要做一些準備工作,比如打開文件或文件夾,我們可以使用代碼一鍵完成。 using System.Diagnostics; using System.IO;namespace OpenFile {internal class Program{static void Main(string[] args){Console.WriteLine("Hello, …

Python生成exe

其中的 -w 參數是 PyInstaller 用于窗口模式(Windowed mode),它會關閉命令行窗口的輸出,這通常用于 圖形界面程序(GUI),比如使用 PyQt6, Tkinter, PySide6 等。 所以: 如果你在沒有…

【大模型微調】如何解決llamaFactory微調效果與vllm部署效果不一致如何解決

以下個人沒整理太全 一、生成式語言模型的對話模板介紹 使用Qwen/Qwen1.5-0.5B-Chat訓練 對話模板不一樣。回答的內容就會不一樣。 我們可以看到例如qwen模型的tokenizer_config.json文件,就可以看到對話模板,一般同系列的模型,模板基本都…

Linux網絡編程——詳解網絡層IP協議、網段劃分、路由

目錄 一、前言 二、IP協議的認識 1、什么是IP協議? 2、IP協議報頭 三、網段劃分 1、初步認識IP與路由 2、IP地址 I、DHCP動態主機配置協議 3、IP地址的劃分 I、CIDR設計 II、子網數目的計算 III、子網掩碼的確定 四、特殊的IP地址 五、IP地址的數量限…

ansible+docker+docker-compose快速部署4節點高可用minio集群

目錄 github項目地址 示例服務器列表 安裝前 修改變量文件group_vars/all.yml 修改ansible主機清單 修改setup.sh安裝腳本 用法演示 安裝后驗證 github項目地址 https://github.com/sulibao/ansible_minio_cluster.git 示例服務器列表 安裝前 修改變量文件group_var…

MySql主從相關概念

想象一下,你的業務飛速增長,用戶請求如潮水般涌來,突然數據庫主庫宕機,數據丟失,服務癱瘓——這簡直是開發者的噩夢!MySQL主從復制就像一張安全網,通過主庫寫、從庫讀的協作模式,不僅…

機械臂只有位置信息是否可以進行手眼標定?

平常我在做手眼標定時,一般都是通過OpenCV的cv::calibrateHandEye函數進行求解,需要輸入多組不同的機械臂位姿。今天遇到了一款舵機機器人,只能獲取位置,得不到姿態信息,想著那就把姿態都設為0,結果求不出來…

華為數字芯片機考2025合集2已校正

單選 1. 題目內容 關于亞穩態的描述錯誤的是( )。 1. 解題步驟 1.1 理解亞穩態(Metastability)的核心特性 亞穩態是指觸發器無法在指定時間內穩定輸出有效邏輯電平(0或1)的狀態,其關鍵特點…

T-Box車載系統介紹及其應用

定義 T-Box汽車系統,全稱為Telematics - BOX,也常簡稱為車載T - BOX,是汽車智能系統及車聯網系統中的核心組成部分,是安裝在車輛上的一種高科技遠程信息處理器。 工作原理 T-Box的核心功能主要通過MPU和MCU實現。MPU負責應用程序功…

[redis進階一]redis的持久化(1)RDB篇章

目錄 一 認識持久化 (1)先看總結圖 (2)什么是持久化? (3)redis是怎么進行持久化的呢 (4)簡單分析一下RDB持久化和AOF持久化的不同 二 RDB持久化 (1)RDB的觸發機制 (2)RDB的bgsave執行流程 (3)RDB文件的處理 (4)RDB的優缺點 (5)RDB效果演示板書 三 溫習Linux文件…

uniapp日常總結--uniapp頁面跳轉方式

uniapp日常總結--uniapp頁面跳轉方式_uniapp 跳轉-CSDN博客

《汽車電器與電子技術》實驗報告

SRS系統結構原理與故障檢測診斷 車輛上為什么要配安全氣囊?——解析汽車被動安全的關鍵防線 一、安全氣囊的核心作用:應對高速碰撞的“救命緩沖墊” 車輛在高速碰撞時(如正面碰撞、側面碰撞),人體會因慣性以極高速度…

ffmpeg編解碼器相關函數

文章目錄 🎯 你需要理解的核心結構體:📦 常用函數及使用順序(以解碼為例)1?? avcodec_find_decoder() / avcodec_find_encoder()2?? avcodec_alloc_context3()3?? avcodec_parameters_to_context()4?? avcodec…

尚硅谷2019版Java網絡編程筆記

第14章 網絡編程 網絡編程概述 什么是網絡編程? 網絡編程是通過網絡協議實現計算機之間的數據交換。Java提供了強大的網絡編程支持,隱藏了底層細節,開發者可以輕松實現網絡通信。 網絡編程的核心問題 如何定位網絡上的主機:通…

解決【遠程主機可能不符合 glibc 和 libstdc++ Vs code 服務器的先決條件】

可能是因為vscode不支持遠程操作系統的版本,要么升級操作系統要么回退vscode版本 vscode回退1.97版本下載地址: 1.97版本VSCODE

forms+windows添加激活水印

formswindows添加激活水印 多語言水印文本,根據系統語言自動切換。水印顯示在每個屏幕的右下角,位置動態調整。半透明灰色文字,微軟雅黑字體。窗口無邊框、置頂、透明背景,不干擾用戶操作。支持多顯示器。高DPI適配。 效果圖&am…

LeetCode --- 444 周賽

題目列表 3507. 移除最小數對使數組有序 I 3508. 設計路由器 3509. 最大化交錯和為 K 的子序列乘積 3510. 移除最小數對使數組有序 II 一、移除最小數對使數組有序 I & II 由于數組是給定的,所以本題的操作步驟是固定的,我們只要能快速模擬操作的過…

限流、降級、熔斷、隔離?

在微服務架構中,服務限流、降級、熔斷和隔離是保障系統高可用性的核心手段,但它們解決的問題和應用場景不同。以下是它們的區別、解決方案和實際案例的詳細說明: 一、服務限流(Rate Limiting) 定義:通過限…