別問什么高級(jí)不高級(jí)了,輸出個(gè)波形而已,沒有啥難的。只是給出了一些細(xì)節(jié),比如你想輸出自己定制的一些波形,該怎么辦?
這里就是使用了TIM1
可以在各種情況下輸出中斷
在NVIC里面可以看到
里面包含的寄存器就是這幾個(gè)
可以按照72MHz來設(shè)置
STM32定時(shí)器之ARR,PSC倆兄弟,具體的可以看我以前的文章。
關(guān)于定時(shí)器的函數(shù),開啟定時(shí)器需要自己寫
TIM1是掛在APB2上面
在中斷的文件里面最后顯示up這個(gè)中斷
update
表面是UP,但其實(shí)要送下下個(gè)函數(shù)里面看看到底是誰的中斷
這個(gè)函數(shù)的具體作用是判斷中斷是否正常,然后判斷產(chǎn)生的是哪一類定時(shí)器中斷(溢出中斷/PWM中斷.....),然后進(jìn)入相應(yīng)的中斷回調(diào)函數(shù)
長(zhǎng)這樣
找到觸發(fā)的中斷,然后就是觸發(fā)回調(diào)函數(shù)
就是我搞黃了這個(gè)
弱定義的回調(diào),要在這里自己去寫邏輯
注意要打開定時(shí)器讓其工作,假如是中斷打開要開IT的函數(shù)
這個(gè)可以重載定時(shí)器的值
顯示的__HAL_TIM_SET_AUTORELOAD宏定義是一個(gè)常見的用于設(shè)置STM32時(shí)鐘自動(dòng)重載寄存器(ARR)的宏。它可以同時(shí)更新TIM_HandleTypeDef結(jié)構(gòu)體中的Init.Period字段。
這個(gè)宏用于動(dòng)態(tài)更改時(shí)鐘周期。如果想在中斷后更改時(shí)鐘周期為10ms,可以使用:
__HAL_TIM_SET_AUTORELOAD(&htim1, 100); // 設(shè)置下一個(gè)周期為10ms
修改的是定時(shí)器結(jié)構(gòu)體里面的數(shù)據(jù)
原理就是你知道1s數(shù)一下,你就知道數(shù)10下就到時(shí)間了,也就是10次中斷,知道了數(shù)10s后,做些什么。。當(dāng)定時(shí)器到達(dá)預(yù)設(shè)的周期,它將觸發(fā)一個(gè)中斷,然后你在中斷服務(wù)程序里面切換GPIO的狀態(tài)。
在運(yùn)行時(shí)改變定時(shí)器的ARR(Auto-Reload Register)值在STM32(以及其他許多微控制器)中是一種常見的做法,用于動(dòng)態(tài)地改變定時(shí)器周期或者波形的參數(shù)。 這樣做的幾個(gè)主要用途和意義如下: 動(dòng)態(tài)波形調(diào)整:可以在運(yùn)行時(shí)改變PWM或者其他類型波形的頻率或者占空比。 任務(wù)調(diào)度:如果使用定時(shí)器進(jìn)行某種形式的多任務(wù)調(diào)度或者時(shí)間切片,動(dòng)態(tài)地改變ARR值可以使你更靈活地控制任務(wù)的執(zhí)行。 事件觸發(fā):通過改變ARR值,可以在特定的時(shí)刻或者在某個(gè)事件發(fā)生后觸發(fā)定時(shí)器中斷。 精確計(jì)時(shí):在需要非常精確控制時(shí)間的應(yīng)用場(chǎng)合(例如,高精度測(cè)量或者通信協(xié)議),動(dòng)態(tài)地改變ARR值可以在運(yùn)行時(shí)微調(diào)定時(shí)器行為。 節(jié)能:在一些低功耗應(yīng)用中,可以通過動(dòng)態(tài)調(diào)整ARR值來改變微控制器的工作周期,以此來降低功耗。 模式切換:在復(fù)雜的系統(tǒng)中,你可能需要定時(shí)器在不同的操作模式之間切換。動(dòng)態(tài)地改變ARR值使得這種切換成為可能。 應(yīng)對(duì)不確定性:在某些場(chǎng)合,事先可能不知道定時(shí)器需要運(yùn)行多長(zhǎng)時(shí)間。動(dòng)態(tài)地設(shè)置ARR值允許程序在運(yùn)行時(shí)根據(jù)實(shí)際需要來配置定時(shí)器。 波形由多個(gè)高低電平組成,每個(gè)電平的持續(xù)時(shí)間都是通過ARR值來設(shè)置的。 這里主要是定時(shí)器周期的動(dòng)態(tài)改變。
對(duì)定時(shí)器周期公式的理解:
T=(arr+1)*(PSC+1)/Tck 其中TCK為時(shí)鐘頻率,PSC為時(shí)鐘預(yù)分頻系數(shù),arr為自動(dòng)重裝載值。
f=Tck/(psc+1)*(arr+1)
Tck/(psc+1)即為時(shí)鐘頻率,1/f為機(jī)器周期,乘以(arr+1)即可得出定時(shí)器周期。
也就是說這個(gè)周期,就是你定的時(shí)間,到了什么時(shí)間干什么事情的時(shí)間。設(shè)置好以后,下一次中斷是什么時(shí)候,是某某時(shí)間,也就是你中斷出場(chǎng)的時(shí)候。
if (htim->Instance == TIM1): 這個(gè)檢查用于確定哪個(gè)定時(shí)器觸發(fā)了這個(gè)回調(diào)。因?yàn)槟憧赡苡卸鄠€(gè)定時(shí)器在你的程序中,這個(gè)檢查確保只有TIM1的事件會(huì)執(zhí)行下面的代碼。
這個(gè)時(shí)候?qū)懸幌麓a,可以把要生成的東西設(shè)置一個(gè)全局的變量,一開始為0,開始運(yùn)行,比如你現(xiàn)在是高電平,接著你就要設(shè)置下次的觸發(fā)時(shí)間,此時(shí)是高電平,下次是什么時(shí)候?自己數(shù)吧
其實(shí)此時(shí)對(duì)于使用定時(shí)器生成波形來講,那就OK了,在while里面都沒有東西。
while (1) { if (some_condition) { // 執(zhí)行某些動(dòng)作 } }
檢查變量干什么事情
while (1) { // 低優(yōu)先級(jí)任務(wù) }
緊急的在回調(diào),剩下的就在這里了
一般我們都是生成方波為主,來看看方波的優(yōu)點(diǎn)。
簡(jiǎn)單性和易于生成
方波是最簡(jiǎn)單、最易于生成和分析的波形之一。只需要一個(gè)簡(jiǎn)單的數(shù)字邏輯電路即可生成方波。
時(shí)間域和頻率域的特性
方波包含了多個(gè)奇次諧波,這一點(diǎn)在頻譜分析和信號(hào)處理中可能是有用的。
適用于數(shù)字和邏輯應(yīng)用
方波是數(shù)字電子學(xué)和邏輯電路的基礎(chǔ),用于表示二進(jìn)制信息(0和1)。
高能量效率
由于方波在其周期內(nèi)只有兩個(gè)狀態(tài)(通常是高和低),因此它能更有效地傳輸能量。
易于檢測(cè)和觸發(fā)
方波的尖銳邊緣使得它很容易被用作觸發(fā)信號(hào),在定時(shí)和同步應(yīng)用中很有用。
易于調(diào)制和解調(diào)
方波通常更容易用于某些類型的數(shù)字調(diào)制方案,如頻率偏移鍵控(FSK)和相位偏移鍵控(PSK)。
適用于脈沖寬度調(diào)制(PWM)
方波是PWM(脈沖寬度調(diào)制)的基礎(chǔ),這是一種常用于控制電機(jī)、LED亮度和其他應(yīng)用的技術(shù)。
高信噪比
在某些應(yīng)用中,例如數(shù)字通信,方波由于其決定性的高和低狀態(tài)通常有更高的信噪比。
那我們就來把這個(gè)生成的代碼框架完善一下。
使用一個(gè)簡(jiǎn)單的狀態(tài)機(jī)邏輯,以及一個(gè)數(shù)組來保存波形的各個(gè)部分(高電平/低電平以及持續(xù)時(shí)間)。
可以考慮設(shè)計(jì)成這樣,我們感興趣是就是高低電平和相應(yīng)的時(shí)間長(zhǎng)度
使用 #define WAVEFORM_SEGMENTS (sizeof(custom_waveform) / sizeof(WaveformSegment)) 是一種方便的方式來計(jì)算波形分段數(shù)組的元素?cái)?shù)量。
在這種情況下,custom_waveform 應(yīng)該是一個(gè) WaveformSegment 類型的數(shù)組。這種方法的優(yōu)點(diǎn)是它在編譯時(shí)完成計(jì)算,不需要運(yùn)行時(shí)計(jì)算。
在這里,waveform_enabled 是一個(gè)標(biāo)志,用于確定是否應(yīng)該生成波形。這個(gè)標(biāo)志可能會(huì)在其他代碼段,比如一個(gè)按鍵中斷服務(wù)例程中被設(shè)置。 current_segment 是一個(gè)靜態(tài)局部變量,用于跟蹤當(dāng)前波形的哪一部分(或“段”)正在生成。每當(dāng)這個(gè)回調(diào)函數(shù)被觸發(fā)時(shí),它會(huì): 檢查 waveform_enabled 是否被設(shè)置以及是否使用了正確的定時(shí)器實(shí)例。 如果是,則進(jìn)一步檢查 current_segment 是否小于波形分段數(shù)組的長(zhǎng)度(由 WAVEFORM_SEGMENTS 定義)。 如果也是,則根據(jù) custom_waveform[current_segment] 的內(nèi)容設(shè)置GPIO的電平并更新定時(shí)器的自動(dòng)重載值。 這種方式是非常靈活和可擴(kuò)展的。可以很容易地更改 custom_waveform 數(shù)組來生成不同的波形,或者動(dòng)態(tài)地更改它來適應(yīng)不同的應(yīng)用場(chǎng)景。 由于使用了靜態(tài)局部變量 current_segment,這個(gè)函數(shù)在多線程環(huán)境下可能不是線程安全的。如果在其他地方也訪問或修改了這些變量,可能需要添加額外的同步機(jī)制。 此外,如果波形生成結(jié)束后需要執(zhí)行其他操作(如通知其他任務(wù)或更改硬件狀態(tài)),則可以在代碼的相應(yīng)部分添加這些操作。在這里,一旦波形生成結(jié)束,waveform_enabled 被設(shè)置為0,以停止波形的進(jìn)一步生成,直到下一次明確的觸發(fā)。
開啟輸出
然后這樣使用
對(duì)于一個(gè)大的程序框架來說,它還是不夠優(yōu)雅,讓我來繼續(xù)的注入能量、
首先寫一個(gè)頭文件
這段代碼定義了一些靜態(tài)變量,這些變量在整個(gè)C文件(或作用域)內(nèi)都是可用的,但不能在其他C文件中訪問。這些變量通常用于在不同的函數(shù)之間共享狀態(tài)或數(shù)據(jù)。 htim_instance: 用于存儲(chǔ)與波形生成相關(guān)聯(lián)的TIM_HandleTypeDef結(jié)構(gòu)的指針。 GPIOx_instance: 用于存儲(chǔ)與波形生成相關(guān)聯(lián)的GPIO端口的指針。 GPIO_Pin_instance: 用于存儲(chǔ)與波形生成相關(guān)聯(lián)的GPIO端口的引腳號(hào)。 current_pattern: 一個(gè)指向波形段(WaveformSegment)數(shù)組的指針,用于表示當(dāng)前的波形模式。 pattern_size: 用于存儲(chǔ)當(dāng)前波形模式(即current_pattern數(shù)組)的大小。 current_segment: 一個(gè)用于跟蹤當(dāng)前波形段的索引的變量。 waveform_enabled: 一個(gè)標(biāo)志,用于指示是否應(yīng)該生成波形。 這些變量主要用于在回調(diào)函數(shù)(如HAL_TIM_PeriodElapsedCallback)和可能的其他設(shè)置或控制函數(shù)之間共享狀態(tài)。
可以這樣使用,然后,在HAL_TIM_PeriodElapsedCallback中,你就可以使用這些變量來實(shí)現(xiàn)波形的生成,而不需要硬編碼或傳遞大量參數(shù)。
回調(diào)是最終的執(zhí)行家,跑不了的
別的一些函數(shù)
使用的時(shí)候就生成一個(gè)波形的參數(shù)包
然后開啟和關(guān)閉就好了
我后面會(huì)寫個(gè)庫,扔Github上面。
審核編輯:湯梓紅
-
單片機(jī)
+關(guān)注
關(guān)注
6039文章
44582瀏覽量
636479 -
寄存器
+關(guān)注
關(guān)注
31文章
5357瀏覽量
120681 -
STM32
+關(guān)注
關(guān)注
2270文章
10910瀏覽量
356598 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3251瀏覽量
115017 -
波形
+關(guān)注
關(guān)注
3文章
379瀏覽量
31596
原文標(biāo)題:使用STM32任意定時(shí)器生成動(dòng)態(tài)波形
文章出處:【微信號(hào):TT1827652464,微信公眾號(hào):云深之無跡】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論