ESP32開發——關于ESP32TimerInterrupt庫的例程分析

最近在學習嵌入式開發的內容,正好有一個開發任務涉及到對于定時器中斷的使用,今天正好找到了這個相關的庫:ESP32TimerInterrupt

ESP32TimerInterrupt庫的下載鏈接(適用于Arduino IDE)

進入到這個地址后直接下載該庫的壓縮包,不用解壓,直接通過arduino IDE添加即可!
然后關于該庫的使用,GitHub中也給出了example來告訴大家如何使用。
下面開始例程的分析
  • 使用的開發IDE:arduino IDE
  • 使用的板子:ESP32S3
  • 例程:TimerInterruptTest.ino
首先要使用這個定時器中斷,要引入定時器中斷的庫,即包含這個庫的頭文件:
#include "ESP32TimerInterrupt.h"
然后定義中斷調用時,輸出電平的管腳:
#define PIN_D19       19        // Pin D19 mapped to pin GPIO9 of ESP32
#define PIN_D3        3        // Pin D3 mapped to pin GPIO3/RX0 of ESP32
然后編寫中斷處理函數:
bool IRAM_ATTR TimerHandler0(void * timerNo)
{static bool toggle0 = false;  // 定義狀態值為false//timer interrupt toggles pin PIN_D19digitalWrite(PIN_D19, toggle0); // 調用該中斷時,在ESP的GPIO9輸出toggle0的狀態值toggle0 = !toggle0; // 將狀態反轉return true;
}
關于該函數的解釋及參數說明

bool IRAM_ATTR TimerHandler0(void * timerNo) 是一個中斷服務例程(ISR)的聲明,它用于ESP32的硬件定時器中斷處理。下面是對該函數聲明的詳細解釋:

  • bool:函數的返回類型為布爾值,這意味著函數將返回 true 或 false。在中斷服務例程中返回 true 通常表示中斷被成功處理,而返回 false 可能表示中斷未被處理或處理中出現錯誤。
  • IRAM_ATTR:這是一個宏定義,用于指定該函數需要放置在指令RAM(Instruction RAM,IRAM)中。在ESP32中,將中斷服務例程放在IRAM中可以確保它們被快速執行,因為IRAM的訪問速度比普通RAM快。這是在處理高速中斷時推薦的做法。
  • TimerHandler0:這是ISR函數的名稱,它遵循了一定的命名約定,表明這是針對特定定時器(在這個例子中是 Timer 0)的中斷處理函數。
  • (void * timerNo):這是傳遞給ISR的參數,timerNo 是一個指向 void 類型的指針,通常用于傳遞與定時器相關的信息或上下文。參數的具體使用取決于中斷服務例程的設計和需求。
第二個中斷處理函數
bool IRAM_ATTR TimerHandler1(void * timerNo)
{static bool toggle1 = false;//timer interrupt toggles outputPindigitalWrite(PIN_D3, toggle1);toggle1 = !toggle1;return true;
}

注:解釋與參數說明同上,唯一的區別是,這里的中斷用的Timer 1,上面的中斷處理函數用的Timer 0。

接下來定義中斷的持續時間(毫秒)和間隔時間(微秒)
#define TIMER0_INTERVAL_MS        1000  // 間隔時間單位是微秒
#define TIMER0_DURATION_MS        5000  // 持續時間單位是毫秒#define TIMER1_INTERVAL_MS        3000
#define TIMER1_DURATION_MS        15000
對兩個定時器進行初始化
// Init ESP32 timer 0 and 1
ESP32Timer ITimer0(0);
ESP32Timer ITimer1(1);
編寫配置函數
void setup()
{pinMode(PIN_D19, OUTPUT);pinMode(PIN_D3, OUTPUT);// 開啟串口Serial.begin(115200);// 如果串口連接建立或者板子運行超過5秒則退出循環while (!Serial && millis() < 5000);// 延遲500毫秒delay(500);// 利用串口打印信息Serial.print(F("\nStarting TimerInterruptTest on "));Serial.println(ARDUINO_BOARD);Serial.println(ESP32_TIMER_INTERRUPT_VERSION);Serial.print(F("CPU Frequency = "));Serial.print(F_CPU / 1000000);Serial.println(F(" MHz"));// Using ESP32  => 80 / 160 / 240MHz CPU clock ,// For 64-bit timer counter// For 16-bit timer prescaler up to 1024// Interval in microsecs// 下面定時器間隔設置為1000000微秒,即1秒if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0)){// 如果定時器中斷設置成功,則串口打印定時器設置成功的信息,并打印板子運行時間Serial.print(F("Starting  ITimer0 OK, millis() = "));Serial.println(millis());}else// 否則打印定時器無法設置Serial.println(F("Can't set ITimer0. Select another freq. or timer"));// Interval in microsecsif (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS * 1000, TimerHandler1)){Serial.print(F("Starting  ITimer1 OK, millis() = "));Serial.println(millis());}elseSerial.println(F("Can't set ITimer1. Select another freq. or timer"));Serial.flush();
}
編寫循環函數
void loop()
{static unsigned long lastTimer0 = 0;static unsigned long lastTimer1 = 0;static bool timer0Stopped = false;static bool timer1Stopped = false;if (millis() - lastTimer0 > TIMER0_DURATION_MS){// 如果板子距離上一次中斷觸發的時間大于定時器持續時間,則更新lastTimer0的值lastTimer0 = millis(); // 檢查定時器是否開啟,如果開啟就關掉,如果關掉就開啟if (timer0Stopped){Serial.print(F("Start ITimer0, millis() = "));Serial.println(millis());ITimer0.restartTimer(); // 重啟定時器Timer 0}else{Serial.print(F("Stop ITimer0, millis() = "));Serial.println(millis());ITimer0.stopTimer();  // 關閉定時器Timer 0}// 進行狀態轉換timer0Stopped = !timer0Stopped;}// 如果板子距離上一次中斷觸發的時間大于定時器持續時間,則更新lastTimer1的值if (millis() - lastTimer1 > TIMER1_DURATION_MS){lastTimer1 = millis();// 檢查定時器是否開啟,如果開啟就關掉,如果關掉就開啟if (timer1Stopped){Serial.print(F("Start ITimer1, millis() = "));Serial.println(millis());ITimer1.restartTimer(); // 重啟定時器Timer 1}else{Serial.print(F("Stop ITimer1, millis() = "));Serial.println(millis());ITimer1.stopTimer();  // 關閉定時器Timer 1}timer1Stopped = !timer1Stopped;}
}
完整代碼
#include "ESP32TimerInterrupt.h"// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
// Don't use PIN_D2 with ESP32_C3 (crash)
#define PIN_D19             19        // Pin D19 mapped to pin GPIO9 of ESP32
#define PIN_D3               3        // Pin D3 mapped to pin GPIO3/RX0 of ESP32// With core v2.0.0+, you can't use Serial.print/println in ISR or crash.
// and you can't use float calculation inside ISR
// Only OK in core v1.0.6-
bool IRAM_ATTR TimerHandler0(void * timerNo)
{static bool toggle0 = false;//timer interrupt toggles pin PIN_D19digitalWrite(PIN_D19, toggle0);toggle0 = !toggle0;return true;
}bool IRAM_ATTR TimerHandler1(void * timerNo)
{static bool toggle1 = false;//timer interrupt toggles outputPindigitalWrite(PIN_D3, toggle1);toggle1 = !toggle1;return true;
}#define TIMER0_INTERVAL_MS        1000
#define TIMER0_DURATION_MS        5000#define TIMER1_INTERVAL_MS        3000
#define TIMER1_DURATION_MS        15000// Init ESP32 timer 0 and 1
ESP32Timer ITimer0(0);
ESP32Timer ITimer1(1);void setup()
{pinMode(PIN_D19, OUTPUT);pinMode(PIN_D3, OUTPUT);Serial.begin(115200);while (!Serial && millis() < 5000);delay(500);Serial.print(F("\nStarting TimerInterruptTest on "));Serial.println(ARDUINO_BOARD);Serial.println(ESP32_TIMER_INTERRUPT_VERSION);Serial.print(F("CPU Frequency = "));Serial.print(F_CPU / 1000000);Serial.println(F(" MHz"));// Using ESP32  => 80 / 160 / 240MHz CPU clock ,// For 64-bit timer counter// For 16-bit timer prescaler up to 1024// Interval in microsecsif (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0)){Serial.print(F("Starting  ITimer0 OK, millis() = "));Serial.println(millis());}elseSerial.println(F("Can't set ITimer0. Select another freq. or timer"));// Interval in microsecsif (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS * 1000, TimerHandler1)){Serial.print(F("Starting  ITimer1 OK, millis() = "));Serial.println(millis());}elseSerial.println(F("Can't set ITimer1. Select another freq. or timer"));Serial.flush();
}void loop()
{static unsigned long lastTimer0 = 0;static unsigned long lastTimer1 = 0;static bool timer0Stopped         = false;static bool timer1Stopped         = false;if (millis() - lastTimer0 > TIMER0_DURATION_MS){lastTimer0 = millis();if (timer0Stopped){Serial.print(F("Start ITimer0, millis() = "));Serial.println(millis());ITimer0.restartTimer();}else{Serial.print(F("Stop ITimer0, millis() = "));Serial.println(millis());ITimer0.stopTimer();}timer0Stopped = !timer0Stopped;}if (millis() - lastTimer1 > TIMER1_DURATION_MS){lastTimer1 = millis();if (timer1Stopped){Serial.print(F("Start ITimer1, millis() = "));Serial.println(millis());ITimer1.restartTimer();}else{Serial.print(F("Stop ITimer1, millis() = "));Serial.println(millis());ITimer1.stopTimer();}timer1Stopped = !timer1Stopped;}
}
上面的完整代碼在arduino IDE中安裝好定時器中斷的庫后,即可編譯,燒錄進ESP32中即可運行!

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

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

相關文章

ubuntu使用記錄——如何使用wireshark網絡抓包工具進行檢測速騰激光雷達的ip和端口號

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言wireshark網絡抓包工具1.wireshark的安裝2.wireshark的使用3.更改雷達ip 總結 前言 Wireshark是一款備受贊譽的開源網絡協議分析軟件&#xff0c;其功能之強大…

簡述MyBatis中#{}引用和${}引用的區別

各位大佬光臨寒舍&#xff0c;希望各位能賞臉給個三連&#xff0c;謝謝各位大佬了&#xff01;&#xff01;&#xff01; 目錄 1.有無預編譯 優點 缺點 2.SQL執行的快慢 3.能否被SQL注入 4.參數輸入方式 5.總結 1.有無預編譯 #{}是有預編譯的而${}是沒有預編譯的&…

LiveGBS流媒體平臺GB/T28181用戶手冊-服務器概覽:通道信息、負載信息、CPU使用、存儲使用、帶寬使用(Mbps)、內存使用

LiveGBS用戶手冊-服務器概覽&#xff1a;通道信息、負載信息、CPU使用、存儲使用、帶寬使用&#xff08;Mbps&#xff09;、內存使用 1、服務器概覽1.1、通道信息1.2、負載信息1.2.1、信息說明1.2.2、會話列表 1.3、CPU使用1.4、存儲使用1.5、帶寬使用&#xff08;Mbps&#xf…

15:00面試,15:08出來,面試問的有點變態。。。。

&#x1f345; 視頻學習&#xff1a;文末有免費的配套視頻可觀看 &#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 從小廠出來&#xff0c;沒想到在另一家公司又寄了。 到這家公司開始上班&#xff0c;加班是每天…

C語言查漏補缺學習【精簡版】

1.scanf函數 scanf&#xff08;"%d %d"&#xff09;//1 2 scanf("price%d %d") //price1 2 // 意思就是scanf函數中&#xff0c;格式是什么&#xff0c;就要對應的輸入什么&#xff0c;不然讀取不到輸入的變量2.常量&#xff1a;const int AMOUNT 100; …

github下載代碼

clone代碼 git clone https://<your_token>github.com//.git 設置URL git remote set-url origin https://<your_token>github.com//.git 設置github本地ip https://juejin.cn/post/7350880189836918820?searchId202405191828091DB64DD476DF0AEC7442

掌握Edge瀏覽器的使用技巧

導言&#xff1a; Edge瀏覽器是微軟推出的一款現代化、高效的網絡瀏覽器。它不僅提供了基本的瀏覽功能&#xff0c;還具備了許多強大的特性和技巧&#xff0c;可以幫助用戶更好地利用瀏覽器進行工作和娛樂。本文將介紹一些Edge瀏覽器的使用技巧&#xff0c;幫助讀者更好地掌握這…

阿里云數據庫 SelectDB 版全面商業化,開啟現代化實時數據倉庫的全新篇章

2024 年 5 月 21 日&#xff0c;由阿里云聯合飛輪科技共同舉辦的「阿里云數據庫 SelectDB 版商業化產品發布會」于線上召開。阿里巴巴集團副總裁、阿里云數據庫產品事業部負責人李飛飛宣布&#xff0c;阿里云數據庫 SelectDB 版在中國站及國際站全面發布&#xff0c;正式開啟商…

集合-1 數組ArrayListLinkedList

一.數組 1.什么是數組&#xff1f; 數組是一種用連續的內存空間存儲相同類型數據的線性數據結構。 2.為什么數組下標是從0開始&#xff1f; &#xff08;1&#xff09;數組根據下標查找元素是基于尋址公式&#xff1a;元素地址數組首地址索引i*數組存儲數據類型的大小 &am…

ROS | 用C++和python實現運動控制功能

基礎知識&#xff1a; 用C實現&#xff1a; C代碼&#xff1a; 用python實現&#xff1a; Python代碼&#xff1a;

數據庫理論基本概念

數據庫理論基本概念 三級模式和兩級映像 外模式 > 用戶和數據庫系統的接口 -------- 外模式-概念模式映射 概念模式 > 數據的邏輯結構和特征的描述 -------- 概念模式-內模式映射 內模式 > 數據物理結構和存儲方式的描述三級…

避雷:搭建ai知識庫的6大注意事項

隨著人工智能技術的發展&#xff0c;ai知識庫成為眾多企業追求的一個重要部分&#xff0c;幫助企業提高運營次效率&#xff0c;越來越受到人們的關注。但是&#xff0c;在搭建ai知識庫的過程中&#xff0c;稍不留意&#xff0c;就會漏掉一些小細節&#xff0c;導致做出來的ai知…

【LeetCode】438.找到字符串中所有字母異位詞

找到字符串中所有字母異位詞 題目描述&#xff1a; 給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 異位詞 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示…

Scala學習筆記4: 數組

目錄 第四章1- 定長數組2- 變長數組3- 遍歷數組和數組緩存4- 數組轉換5- 常用算法6- 多維數組end 第四章 1- 定長數組 在Scala中, 定長數組可以使用 Array 類來創建; 定長數組在創建時需要指定數組的長度, 并且長度在整個數組生命周期中保持不變; 示例: // 定義一個定長數組…

GPT-4o 引領人機交互新風向的向量數據庫Milvus Cloud 成本

成本 AIGC 時代對于冷熱儲存的呼喚 成本一直是向量數據庫獲得更廣泛使用的最大阻礙之一,這個成本來自兩點: 儲存,絕大多數向量數據庫為了保證低延遲,需要把數據全量緩存到內存或者本地磁盤。在這個動輒百億量級的AI 時代,意味著幾十上百 TB 的資源消耗。 計算,數據需…

OpenFeign高級用法:緩存、QueryMap、MatrixVariable、CollectionFormat優雅地遠程調用

碼到三十五 &#xff1a; 個人主頁 微服務架構中&#xff0c;服務之間的通信變得尤為關鍵。OpenFeign&#xff0c;一個聲明式的Web服務客戶端&#xff0c;使得REST API的調用變得更加簡單和優雅。OpenFeign集成了Ribbon和Hystrix&#xff0c;具有負載均衡和容錯的能力&#xff…

線性回歸模型之套索回歸

概述 本案例是基于之前的嶺回歸的案例的。之前案例的完整代碼如下&#xff1a; import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import Ridge, LinearRegression from sklearn.datasets import make_regression from sklearn.model_selectio…

NegativePrompt:利用心理學通過負面情緒刺激增強大型語言模型

【摘要】大型語言模型 (LLM) 已成為各種應用不可或缺的一部分&#xff0c;從傳統的計算任務到高級人工智能 (AI) 應用。這種廣泛的應用促使社會科學等各個學科對 LLM 進行了廣泛的研究。值得注意的是&#xff0c;研究表明 LLM 具有情商&#xff0c;可以通過積極的情緒刺激進一步…

C++:深入理解多態

一、多態的概念 多態的概念&#xff1a;通俗來說&#xff0c;就是多種形態&#xff0c;具體點就是去完成某個行為&#xff0c;當不同的對象去完成時會產生出不同的狀態。 那究竟多態的實際價值體現在哪里呢&#xff1f;&#xff1f; 1、舉個例子比如說購買高鐵票這個行為&…