單芯片解決方案,開啟全新體驗(yàn)——W55MH32 高性能以太網(wǎng)單片機(jī)
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機(jī),它為用戶帶來前所未有的集成化體驗(yàn)。這顆芯片將強(qiáng)大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達(dá)216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨(dú)立的32KB以太網(wǎng)收發(fā)緩存,可供8個(gè)獨(dú)立硬件socket使用。如此配置,真正實(shí)現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32 提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復(fù)雜工控場景設(shè)計(jì)。它擁有66個(gè)GPIO、3個(gè)ADC、12通道DMA、17個(gè)定時(shí)器、2個(gè)I2C、5個(gè)串口、2個(gè)SPI接口(其中1個(gè)帶I2S接口復(fù)用)、1個(gè)CAN、1個(gè)USB2.0以及1個(gè)SDIO接口。如此豐富的外設(shè)資源,能夠輕松應(yīng)對工業(yè)控制中多樣化的連接需求,無論是與各類傳感器、執(zhí)行器的通信,還是對復(fù)雜工業(yè)協(xié)議的支持,都能游刃有余,成為復(fù)雜工控領(lǐng)域的理想選擇。 同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網(wǎng)關(guān)模組等場景,軟件使用方法一致。更多信息和資料請進(jìn)入http://www.w5500.com/網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32L這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實(shí)現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細(xì)信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價(jià)格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

第二十一章 TIM——通用定時(shí)器
1 定時(shí)器簡介
通用定時(shí)器是一個(gè)通過可編程預(yù)分頻器驅(qū)動的 16 位自動裝載計(jì)數(shù)器構(gòu)成。它適用于多種場合,包括測量輸入信號的脈沖長度(輸入捕獲)或者產(chǎn)生輸出波形(輸出比較和PWM)。使用定時(shí)器預(yù)分頻器和 RCC 時(shí)鐘控制器預(yù)分頻器,脈沖長度和波形周期可以在幾個(gè)微秒到幾個(gè)毫秒間調(diào)整。每個(gè)定時(shí)器都是完全獨(dú)立的,沒有互相共享任何資源。它們可以一起同步操作
2 通用定時(shí)器主要功能
主要功能
通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定時(shí)器功能包括:
- ?16 位向上、向下、向上/向下自動裝載計(jì)數(shù)器
- ?16 位可編程(可以實(shí)時(shí)修改)預(yù)分頻器,計(jì)數(shù)器時(shí)鐘頻率的分頻系數(shù)為 1~65536 之間的任意數(shù)值
-
?4 個(gè)獨(dú)立通道:
- ······輸入捕獲
- ······輸出比較
- ······PWM 生成(邊緣或中間對齊模式)
- ······單脈沖模式輸出
- ?使用外部信號控制定時(shí)器和定時(shí)器互連的同步電路
-
?如下事件發(fā)生時(shí)產(chǎn)生中斷/DMA:
- ······更新:計(jì)數(shù)器向上溢出/向下溢出,計(jì)數(shù)器初始化(通過軟件或者內(nèi)部/外部觸發(fā))
- ·······觸發(fā)事件(計(jì)數(shù)器啟動、停止、初始化或者由內(nèi)部/外部觸發(fā)計(jì)數(shù))
- ·······輸入捕獲
- ······輸出比較
- ?支持針對定位的增量(正交)編碼器和霍爾傳感器電路
- ?觸發(fā)輸入作為外部時(shí)鐘或者按周期的電流管理
通用定時(shí)器功能框圖如下:

3 通用定時(shí)器功能描述
3.1 時(shí)基單元
可編程通用定時(shí)器的主要部分是一個(gè)16位計(jì)數(shù)器和與其相關(guān)的自動裝載寄存器。這個(gè)計(jì)數(shù)器可 以向上計(jì)數(shù)、向下計(jì)數(shù)或者向上向下雙向計(jì)數(shù)。此計(jì)數(shù)器時(shí)鐘由預(yù)分頻器分頻得到。
計(jì)數(shù)器、自動裝載寄存器和預(yù)分頻器寄存器可以由軟件讀寫,在計(jì)數(shù)器運(yùn)行時(shí)仍可以讀寫。 時(shí)基單元包含:
- ?計(jì)數(shù)器寄存器(TIMx_CNT)
- ?預(yù)分頻器寄存器 (TIMx_PSC)
- ?自動裝載寄存器 (TIMx_ARR)
自動裝載寄存器是預(yù)先裝載的,寫或讀自動重裝載寄存器將訪問預(yù)裝載寄存器。 根據(jù)在
TIMx_CR1 寄存器中的自動裝載預(yù)裝載使能位(ARPE)的設(shè)置,預(yù)裝載寄存器的內(nèi)容被立即或在 每次的更新事件 UEV 時(shí)傳送到影子寄存器。當(dāng)計(jì)數(shù)器達(dá)到溢出條件(向下計(jì)數(shù)時(shí)的下溢條件)并當(dāng)TIMx_CR1 寄存器中的 UDIS 位等于'0'時(shí),產(chǎn)生更新事件。更新事件也可以由軟件產(chǎn)生。隨后會詳細(xì)描述每一種配置下更新事件的產(chǎn)生。
計(jì)數(shù)器由預(yù)分頻器的時(shí)鐘輸出 CK_CNT 驅(qū)動,僅當(dāng)設(shè)置了計(jì)數(shù)器 TIMx_CR1 寄存器中的計(jì)數(shù)器使能位(CEN)時(shí),CK_CNT 才有效。
注:真正的計(jì)數(shù)器使能信號 CNT_EN 是在 CEN 的一個(gè)時(shí)鐘周期后被設(shè)置。
預(yù)分頻器描述
預(yù)分頻器可以將計(jì)數(shù)器的時(shí)鐘頻率按 1 到 65536 之間的任意值分頻。它是基于一個(gè)(在 TIMx_PSC 寄存器中的)16 位寄存器控制的 16 位計(jì)數(shù)器。這個(gè)控制寄存器帶有緩沖器,它能夠在工作時(shí)被改變。新的預(yù)分頻器參數(shù)在下一次更新事件到來時(shí)被采用給出了在預(yù)分頻器運(yùn)行時(shí),更改計(jì)數(shù)器參數(shù)的例子。當(dāng)預(yù)分頻器的參數(shù)從 1 變到 2 時(shí),計(jì)數(shù)器的時(shí)序圖如下:

當(dāng)預(yù)分頻器的參數(shù)從 1 變到 4 時(shí),計(jì)數(shù)器的時(shí)序圖如下:

3.2 計(jì)數(shù)器模式
向上計(jì)數(shù)模式
在向上計(jì)數(shù)模式中,計(jì)數(shù)器從 0 計(jì)數(shù)到自動加載值(TIMx_ARR 計(jì)數(shù)器的內(nèi)容),然后重新從 0 開始計(jì)數(shù)并且產(chǎn)生一個(gè)計(jì)數(shù)器溢出事件。
每次計(jì)數(shù)器溢出時(shí)可以產(chǎn)生更新事件,在 TIMx_EGR 寄存器中(通過軟件方式或者使用從模式控 制器)設(shè)置 UG 位也同樣可以產(chǎn)生一個(gè)更新事件。
設(shè)置 TIMx_CR1 寄存器中的 UDIS 位,可以禁止更新事件;這樣可以避免在向預(yù)裝載寄存器中寫 入新值時(shí)更新影子寄存器。在 UDIS 位被清'0'之前,將不產(chǎn)生更新事件。但是在應(yīng)該產(chǎn)生更新事 件時(shí),計(jì)數(shù)器仍會被清'0',同時(shí)預(yù)分頻器的計(jì)數(shù)也被請 0(但預(yù)分頻系數(shù)不變)。此外,如果設(shè)置 了TIMx_CR1 寄存器中的 URS 位(選擇更新請求),設(shè)置 UG 位將產(chǎn)生一個(gè)更新事件 UEV,但硬件 不設(shè)置 UIF 標(biāo)志(即不產(chǎn)生中斷或 DMA 請求);這是為了避免在捕獲模式下清除計(jì)數(shù)器時(shí),同時(shí)產(chǎn) 生更新和捕獲中斷。
當(dāng)發(fā)生一個(gè)更新事件時(shí),所有的寄存器都被更新,硬件同時(shí)(依據(jù) URS 位)設(shè)置更新標(biāo)志位(TIMx_SR 寄存器中的 UIF 位)。
預(yù)分頻器的緩沖區(qū)被置入預(yù)裝載寄存器的值(TIMx_PSC 寄存器的內(nèi)容)。
自動裝載影子寄存器被重新置入預(yù)裝載寄存器的值(TIMx_ARR)。
下圖給出一些例子,當(dāng) TIMx_ARR=0x36 時(shí)計(jì)數(shù)器在不同時(shí)鐘頻率下的動作。內(nèi)部時(shí)鐘分頻因子為 1時(shí),計(jì)數(shù)器時(shí)序圖:

內(nèi)部時(shí)鐘分頻因子為 2,計(jì)數(shù)器時(shí)序圖:

內(nèi)部時(shí)鐘分頻因子為4,計(jì)數(shù)器時(shí)序圖:

內(nèi)部時(shí)鐘分頻因子為N,計(jì)數(shù)器時(shí)序圖:

當(dāng) ARPE=0 時(shí)的更新事件(TIMx_ARR 沒有預(yù)裝入),計(jì)數(shù)器時(shí)序圖:

當(dāng) ARPE=1 時(shí)的更新事件(預(yù)裝入了 TIMx_ARR),計(jì)數(shù)器時(shí)序圖:

3.3 捕獲/比較通道
每一個(gè)捕獲/比較通道都是圍繞著一個(gè)捕獲/比較寄存器(包含影子寄存器),包括捕獲的輸入部分(數(shù)字濾波、多路復(fù)用和預(yù)分頻器),和輸出部分(比較器和輸出控制)。 下面幾張圖是一個(gè)捕獲/比較通道概覽。
輸入部分對相應(yīng)的 TIx 輸入信號采樣,并產(chǎn)生一個(gè)濾波后的信號 TIxF。然后,一個(gè)帶極性選擇的邊緣檢測器產(chǎn)生一個(gè)信號(TIxFPx),它可以作為從模式控制器的輸入觸發(fā)或者作為捕獲控制。該信號通過預(yù)分頻進(jìn)入捕獲寄存器(ICxPS):

輸出部分產(chǎn)生一個(gè)中間波形 OCxRef(高有效)作為基準(zhǔn),鏈的末端決定最終輸出信號的極性:

捕獲/比較通道 1 的主電路:

捕獲/比較模塊由一個(gè)預(yù)裝載寄存器和一個(gè)影子寄存器組成。讀寫過程僅操作預(yù)裝載寄存器。
在捕獲模式下,捕獲發(fā)生在影子寄存器上,然后再復(fù)制到預(yù)裝載寄存器中。
在比較模式下,預(yù)裝載寄存器的內(nèi)容被復(fù)制到影子寄存器中,然后影子寄存器的內(nèi)容和計(jì)數(shù)器進(jìn)行比較。
3.4 輸入捕獲模式
根據(jù)輸入信號的特點(diǎn),配置輸入濾波器為所需的帶寬(即輸入為 TIx 時(shí),輸入濾波器控制位是TIMx_CCMRx 寄存器中的 ICxF 位)。假設(shè)輸入信號在最多 5 個(gè)內(nèi)部時(shí)鐘周期的時(shí)間內(nèi)抖動,我們須配置濾波器的帶寬長于 5 個(gè)時(shí)鐘周期。因此我們可以(以 fDTS 頻率)連續(xù)采樣 8 次,以確 認(rèn)在 TI1 上一次真實(shí)的邊沿變換,即在 TIMx_CCMR1 寄存器中寫入 IC1F=0011。
選擇 TI1 通道的有效轉(zhuǎn)換邊沿,在 TIMx_CCER 寄存器中寫入 CC1P=0(上升沿)。
配置輸入預(yù)分頻器。在本例中,我們希望捕獲發(fā)生在每一個(gè)有效的電平轉(zhuǎn)換時(shí)刻,因此預(yù) 分頻器被禁止(寫 TIMx_CCMR1 寄存器的 IC1PS=00)。
設(shè)置 TIMx_CCER 寄存器的 CC1E=1,允許捕獲計(jì)數(shù)器的值到捕獲寄存器中。
如果需要,通過設(shè)置TIMx_DIER寄存器中的CC1IE位允許相關(guān)中斷請求,通過設(shè)置 TIMx_DIER寄存器中的 CC1DE 位允許 DMA 請求。
當(dāng)發(fā)生一個(gè)輸入捕獲時(shí):
產(chǎn)生有效的電平轉(zhuǎn)換時(shí),計(jì)數(shù)器的值被傳送到 TIMx_CCR1 寄存器。
CC1IF 標(biāo)志被設(shè)置(中斷標(biāo)志)。當(dāng)發(fā)生至少 2 個(gè)連續(xù)的捕獲時(shí),而 CC1IF 未曾被清除, CC1OF也被置'1'。
如設(shè)置了 CC1IE 位,則會產(chǎn)生一個(gè)中斷。
如設(shè)置了 CC1DE 位,則還會產(chǎn)生一個(gè) DMA 請求。
為了處理捕獲溢出,建議在讀出捕獲溢出標(biāo)志之前讀取數(shù)據(jù),這是為了避免丟失在讀出捕獲溢 出標(biāo)志之后和讀取數(shù)據(jù)之前可能產(chǎn)生的捕獲溢出信息。
注: 設(shè)置 TIMx_EGR 寄存器中相應(yīng)的 CCxG 位,可以通過軟件產(chǎn)生輸入捕獲中斷和/或 DMA 請求
3.5 PWM 輸入模式(僅適用于 TIM9/12)
該模式是輸入捕獲模式的一個(gè)特例,除下列區(qū)別外,操作與輸入捕獲模式相同:
兩個(gè) ICx 信號被映射至同一個(gè) TIx 輸入。
這 2 個(gè) ICx 信號為邊沿有效,但是極性相反。
其中一個(gè) TIxFP 信號被作為觸發(fā)輸入信號,而從模式控制器被配置成復(fù)位模式。
例如,你需要測量輸入到 TI1 上的 PWM 信號的長度(TIMx_CCR1 寄存器)和占空比(TIMx_CCR2 寄存器),具體步驟如下(取決于 CK_INT 的頻率和預(yù)分頻器的值)
選擇 TIMx_CCR1 的有效輸入:置 TIMx_CCMR1 寄存器的 CC1S=01(選擇 TI1)。
選擇 TI1FP1 的有效極性(用來捕獲數(shù)據(jù)到 TIMx_CCR1 中和清除計(jì)數(shù)器):置 CC1P=0(上升沿有效)。
選擇 TIMx_CCR2 的有效輸入:置 TIMx_CCMR1 寄存器的 CC2S=10(選擇 TI1)。
選擇 TI1FP2 的有效極性(捕獲數(shù)據(jù)到 TIMx_CCR2):置 CC2P=1(下降沿有效)。
選擇有效的觸發(fā)輸入信號:置 TIMx_SMCR 寄存器中的 TS=101(選擇 TI1FP1)。
配置從模式控制器為復(fù)位模式:置 TIMx_SMCR 中的 SMS=100。
使能捕獲:置 TIMx_CCER 寄存器中 CC1E=1 且 CC2E=1。
PWM 輸入模式時(shí)序如下:
3.6 輸出比較模式
此項(xiàng)功能是用來控制一個(gè)輸出波形,或者指示一段給定的的時(shí)間已經(jīng)到時(shí)。 當(dāng)計(jì)數(shù)器與捕獲/比較寄存器的內(nèi)容相同時(shí),輸出比較功能做如下操作:
將輸出比較模式(TIMx_CCMRx 寄存器中的 OCxM 位)和輸出極性(TIMx_CCER 寄存器中的 CCxP
位)定義的值輸出到對應(yīng)的引腳上。在比較匹配時(shí),輸出引腳可以保持它的電平(OCxM=000)、
被設(shè)置成有效電平(OCxM=001)、被設(shè)置成無效電平(OCxM=010)或進(jìn)行翻 轉(zhuǎn)(OCxM=011)。
設(shè)置中斷狀態(tài)寄存器中的標(biāo)志位(TIMx_SR 寄存器中的 CCxIF 位)。
若設(shè)置了相應(yīng)的中斷屏蔽(TIMx_DIER 寄存器中的 CCxIE 位),則產(chǎn)生一個(gè)中斷。
若設(shè)置了相應(yīng)的使能位(TIMx_DIER 寄存器中的 CCxDE 位,TIMx_CR2 寄存器中的 CCDS 位 選擇 DMA 請求功能),則產(chǎn)生一個(gè) DMA 請求。
TIMx_CCMRx 中的 OCxPE 位選擇 TIMx_CCRx 寄存器是否需要使用預(yù)裝載寄存器。 在輸出比較模式下,更新事件 UEV 對 OCxREF 和 OCx 輸出沒有影響。
同步的精度可以達(dá)到計(jì)數(shù)器的一個(gè)計(jì)數(shù)周期。輸出比較模式(在單脈沖模式下)也能用來輸出一個(gè)單脈沖。輸出比較模式的配置步驟:
1. 選擇計(jì)數(shù)器時(shí)鐘(內(nèi)部,外部,預(yù)分頻器)
2. 將相應(yīng)的數(shù)據(jù)寫入 TIMx_ARR 和 TIMx_CCRx 寄存器中
3. 如果要產(chǎn)生一個(gè)中斷請求和/或一個(gè) DMA 請求,設(shè)置 CCxIE 位和/或 CCxDE 位。
4. 選擇輸出模式,例如當(dāng)計(jì)數(shù)器CNT與CCRx匹配時(shí)翻轉(zhuǎn) OCx的輸出引腳,CCRx預(yù)裝載未 用,開啟 OCx 輸出且高電平有效,則必須設(shè)置 OCxM='011' 、OCxPE='0' 、CCxP='0'和 CCxE='1'。
5. 設(shè)置 TIMx_CR1 寄存器的 CEN 位啟動計(jì)數(shù)器
TIMx_CCRx 寄存器能夠在任何時(shí)候通過軟件進(jìn)行更新以控制輸出波形,條件是未使用預(yù)裝載寄 存器(OCxPE='0',否則 TIMx_CCRx 影子寄存器只能在發(fā)生下一次更新事件時(shí)被更新)。下圖給出了一個(gè)例子。

輸出比較模式,翻轉(zhuǎn) OC1。
3.7 PWM 模式
脈沖寬度調(diào)制模式可以產(chǎn)生一個(gè)由 TIMx_ARR 寄存器確定頻率、由 TIMx_CCRx 寄存器確定占空比的信號。
在 TIMx_CCMRx 寄存器中的 OCxM 位寫入'110'(PWM 模式 1)或'111'(PWM 模式 2),能夠獨(dú)立地設(shè)置每個(gè) OCx 輸出通道產(chǎn)生一路 PWM。必須設(shè)置 TIMx_CCMRx 寄存器 OCxPE 位以使能相應(yīng)的預(yù) 裝載寄存器,最后還要設(shè)置 TIMx_CR1 寄存器的 ARPE 位,(在向上計(jì)數(shù)或中心對稱模式中)使能 自動重裝載的預(yù)裝載寄存器。
僅當(dāng)發(fā)生一個(gè)更新事件的時(shí)候,預(yù)裝載寄存器才能被傳送到影子寄存器,因此在計(jì)數(shù)器開始計(jì) 數(shù)之前,必須通過設(shè)置 TIMx_EGR 寄存器中的 UG 位來初始化所有的寄存器。OCx 的極性可以通過軟件在 TIMx_CCER 寄存器中的 CCxP 位設(shè)置,它可以設(shè)置為高電平有效或 低電平有效。TIMx_CCER寄存器中的CCxE位控制OCx輸出使能。詳見TIMx_CCERx寄存器的 描述。
在 PWM 模式(模式 1 或模式 2)下,TIMx_CNT 和 TIMx_CCRx 始終在進(jìn)行比較,(依據(jù)計(jì)數(shù)器的計(jì)數(shù)方向) 以確定是否符合 TIMx_CCRx ≤ TIMx_CNT 或者 TIMx_CNT ≤ TIMx_CCRx 。然而 為了與OCREF_CLR 的功能(在下一個(gè) PWM 周期之前, ETR 信號上的一個(gè)外部事件能夠清除 OCxREF) 一致,OCxREF 信號只能在下述條件下產(chǎn)生:
當(dāng)比較的結(jié)果改變
當(dāng)輸出比較模式(TIMx_CCMRx 寄存器中的 OCxM 位)從“凍結(jié)”(無比較,OCxM='000')切換到
某個(gè) PWM 模式(OCxM='110'或'111')。這樣在運(yùn)行中可以通過軟件強(qiáng)置 PWM 輸出。
根據(jù) TIMx_CR1寄存器中 CMS位的狀態(tài),定時(shí)器能夠產(chǎn)生邊沿對齊的 PWM信號或中央對齊的 PWM信號。
PWM 邊沿對齊模式
- 向上計(jì)數(shù)配置
當(dāng) TIMx_CR1 寄存器中的 DIR 位為低的時(shí)候執(zhí)行向上計(jì)數(shù)。
下面是一個(gè) PWM 模式 1 的例子。當(dāng) TIMx_CNT
如果比較值為 0,則 OCxREF 保持為'0' 。下圖為 TIMx_ARR=8 時(shí)邊沿對齊的 PWM 波形實(shí)例。邊沿對齊的 PWM 波形(ARR=8)如下:

- 向下計(jì)數(shù)的配置
當(dāng) TIMx_CR1 寄存器的 DIR 位為高時(shí)執(zhí)行向下計(jì)數(shù)。在 PWM 模式 1 ,當(dāng)TIMx_CNT>TIMx_CCRx 時(shí)參考信 號 OCxREF 為低,否 則為高。 如果TIMx_CCRx 中的比較值大于 TIMx_ARR 中的自動重裝載值,則 OCxREF 保持為'1'。該模式下不 能產(chǎn)生 0%的 PWM 波形。
PWM 中央對齊模式
當(dāng) TIMx_CR1 寄存器中的 CMS 位不為'00'時(shí),為中央對齊模式(所有其他的配置對 OCxREF/OCx 信號都有相同的作用)。根據(jù)不同的 CMS 位設(shè)置,比較標(biāo)志可以在計(jì)數(shù)器向上計(jì)數(shù)時(shí)被置'1'、在計(jì)數(shù)器向下計(jì)數(shù)時(shí)被置'1'、或在計(jì)數(shù)器向上和向下計(jì)數(shù)時(shí)被置'1' 。TIMx_CR1 寄存器中的計(jì)數(shù)方向位(DIR)由硬件更新,不要用軟件修改它。
下圖給出了一些中央對齊的 PWM 波形的例子
TIMx_ARR=8
PWM 模式 1
TIMx_CR1 寄存器中的 CMS=01,在中央對齊模式 1 時(shí),當(dāng)計(jì)數(shù)器向下計(jì)數(shù)時(shí)設(shè)置比較標(biāo)志。

使用中央對齊模式的提示:
進(jìn)入中央對齊模式時(shí),使用當(dāng)前的向上/向下計(jì)數(shù)配置;這就意味著計(jì)數(shù)器向上還是向下計(jì)數(shù)取決于 TIMx_CR1 寄存器中 DIR 位的當(dāng)前值。此外,軟件不能同時(shí)修改 DIR 和 CMS 位。
不推薦當(dāng)運(yùn)行在中央對齊模式時(shí)改寫計(jì)數(shù)器,因?yàn)檫@會產(chǎn)生不可預(yù)知的結(jié)果。特別地: 如果寫入計(jì)數(shù)器的值大于自動重加載的值(TIMx_CNT>TIMx_ARR),則方向不會被更新。 例如,如果計(jì)數(shù)器正在向上計(jì)數(shù),它就會繼續(xù)向上計(jì)數(shù)。如果將 0 或者 TIMx_ARR 的值寫入計(jì)數(shù)器,方向被更新,但不產(chǎn)生更新事件 UEV。
使用中央對齊模式最保險(xiǎn)的方法,就是在啟動計(jì)數(shù)器之前產(chǎn)生一個(gè)軟件更新(設(shè)置 TIMx_EGR 位中的 UG 位),不要在計(jì)數(shù)進(jìn)行過程中修改計(jì)數(shù)器的值。
4 PWM
4.1 代碼解析
1.頭文件包含和全局變量定義
#include ??stdlib.h???>
#include ??string.h???>
#include ??stdio.h???>
#include "delay.h"
#include "w55mh32.h"
USART_TypeDef *USART_TEST = USART1;
頭文件:引入了標(biāo)準(zhǔn)庫頭文件和自定義頭文件,delay.h可能用于延時(shí)功能,w55mh32.h可能包含硬件相關(guān)的定義。
全局變量:USART_TEST是一個(gè)指向USART_TypeDef類型的指針,被初始化為USART1,用于后續(xù)的串口操作。
2.函數(shù)聲明
void UART_Configuration(uint32_t bound);
void TIM_Configuration(void);
void RCC_ClkConfiguration(void);
聲明了三個(gè)函數(shù):
UART_Configuration():用于配置串口通信。
TIM_Configuration():用于配置定時(shí)器并輸出 PWM 信號。
RCC_ClkConfiguration():用于配置系統(tǒng)時(shí)鐘。
main()函數(shù)
RCC_ClocksTypeDef clocks;
int main(void)
{
RCC_ClkConfiguration();
delay_init();
UART_Configuration(115200);
RCC_GetClocksFreq(&clocks);
printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn",
(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);
printf("TIM Out Test.n");
TIM_Configuration();
while (1);
}
系統(tǒng)初始化:
調(diào)用RCC_ClkConfiguration()函數(shù)配置系統(tǒng)時(shí)鐘。
調(diào)用delay_init()函數(shù)初始化延時(shí)功能。
調(diào)用UART_Configuration()函數(shù)配置串口通信,波特率設(shè)置為 115200。
調(diào)用RCC_GetClocksFreq()函數(shù)獲取系統(tǒng)時(shí)鐘頻率信息。
信息輸出:
通過printf()函數(shù)輸出系統(tǒng)時(shí)鐘頻率信息,包括系統(tǒng)時(shí)鐘(SYSCLK)、高級高性能總線時(shí)鐘(HCLK)、低速外設(shè)總線時(shí)鐘(PCLK1)、高速外設(shè)總線時(shí)鐘(PCLK2)和 ADC 時(shí)鐘(ADCCLK)。
輸出提示信息 “TIM Out Test.”,表示開始定時(shí)器輸出測試。
定時(shí)器配置:
調(diào)用TIM_Configuration()函數(shù)配置定時(shí)器并輸出 PWM 信號。
主循環(huán):
while (1);是一個(gè)無限循環(huán),使程序停在這里,等待定時(shí)器輸出 PWM 信號。
4.RCC_ClkConfiguration()函數(shù)
void RCC_ClkConfiguration(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
RCC_PLLCmd(DISABLE);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
RCC_HSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
}
時(shí)鐘復(fù)位:
調(diào)用RCC_DeInit()函數(shù)將 RCC 寄存器復(fù)位為默認(rèn)值。
外部高速時(shí)鐘(HSE)配置:調(diào)用RCC_HSEConfig()函數(shù)使能外部高速時(shí)鐘(HSE)。
通過while循環(huán)等待 HSE 準(zhǔn)備好(RCC_FLAG_HSERDY標(biāo)志置位)。
鎖相環(huán)(PLL)配置:
調(diào)用RCC_PLLCmd()函數(shù)禁用 PLL。
調(diào)用RCC_PLLConfig()函數(shù)配置 PLL,將 HSE 作為 PLL 的輸入時(shí)鐘源,PLL 乘法因子設(shè)置為 9。
調(diào)用RCC_PLLCmd()函數(shù)使能 PLL。
通過while循環(huán)等待 PLL 準(zhǔn)備好(RCC_FLAG_PLLRDY標(biāo)志置位)。
系統(tǒng)時(shí)鐘配置:
調(diào)用RCC_SYSCLKConfig()函數(shù)將 PLL 輸出作為系統(tǒng)時(shí)鐘。
總線時(shí)鐘配置:
調(diào)用RCC_HCLKConfig()函數(shù)將系統(tǒng)時(shí)鐘(SYSCLK)直接作為高級高性能總線時(shí)鐘(HCLK)。
調(diào)用RCC_PCLK1Config()函數(shù)將 HCLK 分頻 2 作為低速外設(shè)總線時(shí)鐘(PCLK1)。
調(diào)用RCC_PCLK2Config()函數(shù)將 HCLK 直接作為高速外設(shè)總線時(shí)鐘(PCLK2)。
低速內(nèi)部時(shí)鐘(LSI)和高速內(nèi)部時(shí)鐘(HSI)配置:
調(diào)用RCC_LSICm()函數(shù)使能低速內(nèi)部時(shí)鐘(LSI),并等待 LSI 準(zhǔn)備好(RCC_FLAG_LSIRDY標(biāo)志置位)。
調(diào)用RCC_HSICmd()函數(shù)使能高速內(nèi)部時(shí)鐘(HSI),并等待 HSI 準(zhǔn)備好(RCC_FLAG_HSIRDY標(biāo)志置位)。
5 TIM_Configuration()函數(shù)
void TIM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Enable Timer 3 Clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //Enable GPIO peripherals and AFIO multiplexing function module clocks
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Timer TIM3 initialization
TIM_TimeBaseStructure.TIM_Period = 99;
TIM_TimeBaseStructure.TIM_Prescaler = clocks.PCLK1_Frequency / 1000000 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//Initialize TIM3 Channel2 PWM mode
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 99 / 2;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE); //Open the advanced timer
}
時(shí)鐘使能:
調(diào)用RCC_APB1PeriphClockCmd()函數(shù)使能定時(shí)器 3(TIM3)的時(shí)鐘。
調(diào)用RCC_APB2PeriphClockCmd()函數(shù)使能 GPIOA 和 AFIO(復(fù)用功能模塊)的時(shí)鐘。
GPIO 配置:
將GPIOA的Pin 7配置為復(fù)用推挽輸出模式,用于輸出 TIM3 的通道 2(TIM_CH2)的 PWM 信號。
配置 GPIO 的速度為 50MHz。
定時(shí)器基本參數(shù)配置:
定義TIM_TimeBaseInitTypeDef類型的結(jié)構(gòu)體TIM_TimeBaseStructure,用于配置定時(shí)器的基本參數(shù)。
TIM_Period設(shè)置為 99,表示定時(shí)器的自動重載值。
TIM_Prescaler根據(jù)PCLK1的頻率進(jìn)行設(shè)置,將定時(shí)器的時(shí)鐘頻率進(jìn)行分頻。
TIM_ClockDivision設(shè)置為TIM_CKD_DIV1,表示時(shí)鐘分頻因子為 1。
TIM_CounterMode設(shè)置為TIM_CounterMode_Up,表示定時(shí)器采用向上計(jì)數(shù)模式。
調(diào)用TIM_TimeBaseInit()函數(shù)根據(jù)上述參數(shù)初始化 TIM3。
定時(shí)器輸出比較(PWM)配置:
定義TIM_OCInitTypeDef類型的結(jié)構(gòu)體TIM_OCInitStructure,用于配置定時(shí)器的輸出比較(PWM)參數(shù)。
TIM_OCMode設(shè)置為TIM_OCMode_PWM2,表示采用 PWM 模式 2。
TIM_OutputState和TIM_OutputNState都設(shè)置為TIM_OutputState_Enable,表示使能輸出和互補(bǔ)輸出。
TIM_Pulse設(shè)置為99 / 2,表示 PWM 信號的脈沖寬度。
TIM_OCPolarity和TIM_OCNPolarity都設(shè)置為TIM_OCPolarity_Low,表示輸出極性為低。
TIM_OCIdleState設(shè)置為TIM_OCIdleState_Set,TIM_OCNIdleState設(shè)置為TIM_OCIdleState_Reset,表示空閑狀態(tài)下的輸出電平。
調(diào)用TIM_OC2Init()函數(shù)根據(jù)上述參數(shù)初始化 TIM3 的通道 2。
預(yù)裝載寄存器配置:
調(diào)用TIM_OC2PreloadConfig()函數(shù)使能 TIM3 通道 2 的預(yù)裝載寄存器。
調(diào)用TIM_ARRPreloadConfig()函數(shù)使能 TIM3 的自動重載寄存器的預(yù)裝載功能。
定時(shí)器使能:
調(diào)用TIM_Cmd()函數(shù)使能 TIM3。
調(diào)用TIM_CtrlPWMOutputs()函數(shù)使能高級定時(shí)器的 PWM 輸出。
6 UART_Configuration()函數(shù)
void UART_Configuration(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART_TEST, &USART_InitStructure);
USART_Cmd(USART_TEST, ENABLE);
}
時(shí)鐘使能:
調(diào)用RCC_APB2PeriphClockCmd()函數(shù)使能 USART1 和 GPIOA 的時(shí)鐘。
GPIO 配置:
將GPIOA的Pin 9配置為復(fù)用推挽輸出模式,用于 USART1 的發(fā)送功能。
將GPIOA的Pin 10配置為浮空輸入模式,用于 USART1 的接收功能。
配置 GPIO 的速度為 50MHz。
USART 配置:
定義USART_InitTypeDef類型的結(jié)構(gòu)體USART_InitStructure,用于配置 USART 的基本參數(shù)。
USART_BaudRate根據(jù)傳入的參數(shù)bound設(shè)置波特率。
USART_WordLength設(shè)置為USART_WordLength_8b,表示數(shù)據(jù)位為 8 位。
USART_StopBits設(shè)置為USART_StopBits_1,表示停止位為 1 位。
USART_Parity設(shè)置為USART_Parity_No,表示無校驗(yàn)位。
USART_HardwareFlowControl設(shè)置為USART_HardwareFlowControl_None,表示無硬件流控制。
USART_Mode設(shè)置為USART_Mode_Rx | USART_Mode_Tx,表示支持收發(fā)模式。
調(diào)用USART_Init()函數(shù)根據(jù)上述參數(shù)初始化 USART1。
調(diào)用USART_Cmd()函數(shù)使能 USART1。
7. SER_PutChar()和fputc()函數(shù)
int SER_PutChar(int ch)
{
while (!USART_GetFlagStatus(USART_TEST, USART_FLAG_TC));
USART_SendData(USART_TEST, (uint8_t)ch);
return ch;
}
int fputc(int c, FILE *f)
{
if (c == 'n')
{
SER_PutChar('r');
}
return (SER_PutChar(c));
}
SER_PutChar()函數(shù)用于將一個(gè)字符發(fā)送到串口,通過USART_GetFlagStatus()函數(shù)檢查串口發(fā)送完成標(biāo)志,等待發(fā)送完成后,調(diào)用USART_SendData()函數(shù)發(fā)送字符。
fputc()函數(shù)重定向了printf()函數(shù)的輸出,將字符通過串口發(fā)送出去,當(dāng)遇到換行符n時(shí),先調(diào)用SER_PutChar('r')函數(shù)發(fā)送回車符r。
4.2下載驗(yàn)證

如果想查看PWM輸出的占空比,可以在循環(huán)里加這段代碼:
uint16_t pwm_value = TIM_GetCapture2(TIM3);
float duty_cycle = (float)pwm_value / 99 * 100;
printf("PWM Duty Cycle: %.2f%%n", duty_cycle);
delay_ms(1000);
這樣可以打印出PWM的占空比:

5 更新中斷
5.1 代碼解析
1. main()函數(shù):初始化與啟動
int main(void) {
delay_init(); // 延時(shí)初始化(sysTick)
UART_Configuration(115200); // 串口配置(115200波特率)
TIM_Configuration(); // 定時(shí)器TIM3配置
// 打印系統(tǒng)時(shí)鐘
printf("SYSCLK: %3.1fMhz...n", (float)clocks.SYSCLK_Frequency / 1000000);
while (1); // 主循環(huán)(空,依賴中斷)
}
2. UART_Configuration():串口初始化
void UART_Configuration(uint32_t bound) {
// 使能USART1、GPIOA時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置TX(PA9):復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置RX(PA10):浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 串口參數(shù):115200波特率,8位數(shù)據(jù),1位停止位
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE); // 使能串口
}
3. TIM_Configuration():定時(shí)器 TIM3 配置
void TIM_Configuration(void) {
// 使能TIM3時(shí)鐘(APB1總線)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// 定時(shí)器參數(shù):
TIM_TimeBaseStructure.TIM_Period = 9999; // 自動重載值(0~9999,共10000個(gè)周期)
// 預(yù)分頻器:PCLK1頻率/1MHz - 1(例如PCLK1=36MHz → 36-1=35)
TIM_TimeBaseStructure.TIM_Prescaler = (clocks.PCLK1_Frequency / 1000000) - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化定時(shí)器
// 使能更新中斷
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// 中斷配置(NVIC):
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // TIM3中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 搶占優(yōu)先級0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子優(yōu)先級3
NVIC_Init(&NVIC_InitStructure); // 使能中斷
TIM_Cmd(TIM3, ENABLE); // 啟動定時(shí)器
}
4. 中斷處理函數(shù):TIM3_IRQHandler()
void TIM3_IRQHandler(void) {
if (TIM_GetITStatus(TIM3, TIM_IT_Update)) { // 檢查更新中斷標(biāo)志
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除中斷標(biāo)志
printf("%sn", __FUNCTION__); // 打印函數(shù)名("TIM3_IRQHandler")
}
}
該代碼演示了 W55MH32 定時(shí)器的基本用法:配置 TIM3 的更新中斷,周期性觸發(fā)并通過串口輸出信息。核心流程:定時(shí)器初始化(預(yù)分頻器、周期)→ 啟用中斷 → 中斷處理(打印信息)。適用于需要周期性任務(wù)的場景(如定時(shí)采樣、心跳信號)。
5.2 下載驗(yàn)證

6 TIM_CalibrationLsi
6.1 代碼解析
1. 全局變量
uint8_t TIM5_CAPTURE_STA = 0; // 輸入捕獲狀態(tài)(位7:完成標(biāo)志,位6:上升沿標(biāo)志,位0-5:溢出次數(shù))
uint16_t TIM5_CAPTURE_VAL; // 捕獲值(TIM5計(jì)數(shù)器值)
2. main()函數(shù):初始化與主循環(huán)
int main(void) {
RCC_ClkConfiguration(); // 系統(tǒng)時(shí)鐘配置(HSE→PLL→72MHz)
delay_init(); // 延時(shí)初始化(SysTick)
UART_Configuration(115200); // 串口配置(115200波特率)
TIM_Configuration(); // TIM5輸入捕獲配置(LSI測量)
// 主循環(huán):處理捕獲結(jié)果
while (1) {
if (TIM5_CAPTURE_STA & 0x80) { // 捕獲完成標(biāo)志
// 計(jì)算總時(shí)間:溢出次數(shù)×65536 + 捕獲值
temp = (TIM5_CAPTURE_STA & 0x3F) * 65536 + TIM5_CAPTURE_VAL;
printf("LSI周期: %d μsnLSI頻率: %f Hzn", temp, 1000000.0 / temp);
TIM5_CAPTURE_STA = 0; // 重置狀態(tài),準(zhǔn)備下次捕獲
}
}
}
3. TIM_Configuration():定時(shí)器輸入捕獲配置
void TIM_Configuration(void) {
// 使能TIM5和AFIO時(shí)鐘(用于引腳重映射)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 重映射:LSI → TIM5_CH4(無需外部引腳)
GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);
// 時(shí)基配置:
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 最大計(jì)數(shù)值(65535)
// 預(yù)分頻器:PCLK1×2 / 1MHz - 1(TIMx時(shí)鐘=PCLK1×2)
TIM_TimeBaseStructure.TIM_Prescaler = (clocks.PCLK1_Frequency * 2 / 1000000) - 1;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
// 輸入捕獲配置(通道4,上升沿捕獲):
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕獲
TIM_ICInit(TIM5, &TIM_ICInitStructure);
// 中斷配置:更新(溢出)+ 捕獲中斷
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM5, TIM_IT_Update | TIM_IT_CC4, ENABLE);
TIM_Cmd(TIM5, ENABLE); // 啟動定時(shí)器
}
4. 中斷處理函數(shù):TIM5_IRQHandler()
void TIM5_IRQHandler(void) {
if (! (TIM5_CAPTURE_STA & 0x80)) { // 未完成捕獲
// 處理更新中斷(定時(shí)器溢出)
if (TIM_GetITStatus(TIM5, TIM_IT_Update)) {
if (TIM5_CAPTURE_STA & 0x40) { // 已捕獲上升沿,溢出計(jì)數(shù)
if ((TIM5_CAPTURE_STA & 0x3F) == 0x3F) { // 溢出32次(超時(shí))
TIM5_CAPTURE_STA |= 0x80; // 標(biāo)記失敗
} else {
TIM5_CAPTURE_STA++; // 溢出次數(shù)+1
}
}
}
// 處理捕獲中斷(CH4上升沿)
if (TIM_GetITStatus(TIM5, TIM_IT_CC4)) {
if (TIM5_CAPTURE_STA & 0x40) { // 已捕獲上升沿,現(xiàn)在捕獲下降沿(假設(shè)LSI是方波)
TIM5_CAPTURE_VAL = TIM_GetCapture4(TIM5); // 讀取捕獲值
TIM5_CAPTURE_STA |= 0x80; // 標(biāo)記完成
} else { // 首次捕獲上升沿
TIM5_CAPTURE_STA = 0x40; // 標(biāo)記已捕獲上升沿
TIM_SetCounter(TIM5, 0); // 計(jì)數(shù)器清零
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC4 | TIM_IT_Update); // 清除中斷標(biāo)志
}
5. 系統(tǒng)時(shí)鐘配置:RCC_ClkConfiguration()
void RCC_ClkConfiguration(void) {
// 初始化系統(tǒng)時(shí)鐘:HSE(8MHz) → PLL×9 → SYSCLK=72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// 總線分頻:
RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK=72MHz
RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1=36MHz(TIM5屬于APB1)
RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2=72MHz
RCC_LSICmd(ENABLE); // 啟用LSI(內(nèi)部低速時(shí)鐘,~32kHz)
}
此代碼是 W55MH32 定時(shí)器高級應(yīng)用的典型示例,展示了如何利用硬件特性測量內(nèi)部信號,適用于嵌入式系統(tǒng)調(diào)試和時(shí)鐘校準(zhǔn)場景。
6.2 下載驗(yàn)證

7 TIM_InputCapture
7.1 代碼解析
1. 全局變量
uint8_t TIM3_CAPTURE_STA = 0; // 輸入捕獲狀態(tài)(位7:完成,位6:上升沿標(biāo)志,位0-5:溢出次數(shù))
uint16_t TIM3_CAPTURE_VAL; // 捕獲值(TIM3計(jì)數(shù)器值)
2. main()函數(shù):初始化與主循環(huán)
int main(void) {
RCC_ClkConfiguration(); // 系統(tǒng)時(shí)鐘配置(72MHz)
UART_Configuration(115200); // 串口初始化
TIM_Configuration(); // TIM3輸入捕獲配置
while (1) {
if (TIM3_CAPTURE_STA & 0x80) { // 捕獲完成
// 計(jì)算總時(shí)間:溢出次數(shù)×65536 + 捕獲值(單位:μs)
temp = (TIM3_CAPTURE_STA & 0x3F) * 65536 + TIM3_CAPTURE_VAL;
printf("HIGH:%d usrn", temp); // 打印高電平時(shí)間
TIM3_CAPTURE_STA = 0; // 重置狀態(tài),準(zhǔn)備下次捕獲
}
}
}
3. TIM_Configuration():定時(shí)器輸入捕獲配置
void TIM_Configuration(void) {
// 使能TIM3、GPIOA、AFIO時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
// 配置GPIOA7為輸入(TIM3_CH2)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉輸入(根據(jù)信號調(diào)整)
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 時(shí)基配置:
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 最大計(jì)數(shù)值(65535)
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 預(yù)分頻器(72MHz/72=1MHz → 計(jì)數(shù)周期1μs)
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 輸入捕獲配置(通道2,上升沿捕獲):
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕獲
TIM_ICInit(TIM3, &TIM_ICInitStructure);
// 中斷配置:更新(溢出)+ 捕獲中斷
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM3, TIM_IT_Update | TIM_IT_CC2, ENABLE);
TIM_Cmd(TIM3, ENABLE); // 啟動定時(shí)器
}
4. 中斷處理函數(shù):TIM3_IRQHandler()
void TIM3_IRQHandler(void) {
if (! (TIM3_CAPTURE_STA & 0x80)) { // 未完成捕獲
// 處理溢出中斷
if (TIM_GetITStatus(TIM3, TIM_IT_Update)) {
if (TIM3_CAPTURE_STA & 0x40) { // 已捕獲上升沿,統(tǒng)計(jì)溢出
if (TIM3_CAPTURE_STA & 0x3F == 0x3F) { // 溢出32次(超時(shí))
TIM3_CAPTURE_STA |= 0x80; // 標(biāo)記失敗
} else {
TIM3_CAPTURE_STA++; // 溢出次數(shù)+1
}
}
}
// 處理捕獲中斷(CH2上升沿/下降沿)
if (TIM_GetITStatus(TIM3, TIM_IT_CC2)) {
if (TIM3_CAPTURE_STA & 0x40) { // 捕獲下降沿(高電平結(jié)束)
TIM3_CAPTURE_VAL = TIM_GetCapture2(TIM3); // 讀取捕獲值
TIM3_CAPTURE_STA |= 0x80; // 標(biāo)記完成
TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Rising); // 切回上升沿捕獲
} else { // 捕獲上升沿(高電平開始)
TIM3_CAPTURE_STA = 0x40; // 標(biāo)記上升沿
TIM_SetCounter(TIM3, 0); // 計(jì)數(shù)器清零
TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Falling); // 切換為下降沿捕獲
}
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2 | TIM_IT_Update); // 清除中斷標(biāo)志
}
5. 系統(tǒng)時(shí)鐘配置
void RCC_ClkConfiguration(void) {
// HSE(8MHz) → PLL×9 → SYSCLK=72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// 總線分頻:HCLK=72MHz, PCLK1=36MHz, PCLK2=72MHz
}
此代碼是 W55MH32 定時(shí)器輸入捕獲的典型應(yīng)用,展示了如何通過硬件中斷高效測量外部信號,適用于需要高精度時(shí)間測量的嵌入式系統(tǒng)。
7.2 下載驗(yàn)證

8 TIM_Tim9
8.1 代碼解析
1. 頭文件與全局變量
#include "w55mh32.h" // STM32硬件抽象層(寄存器定義)
USART_TypeDef *USART_TEST = USART1; // 串口外設(shè)指針(USART1)
2. main()函數(shù):初始化與啟動
int main(void) {
delay_init(); // 延時(shí)初始化(sysTick)
UART_Configuration(115200); // 串口配置(115200波特率)
TIM_Configuration(); // 定時(shí)器TIM9配置
// 打印系統(tǒng)時(shí)鐘
printf("SYSCLK: %3.1fMhz...n", (float)clocks.SYSCLK_Frequency / 1000000);
while (1); // 主循環(huán)(空,依賴中斷)
}
3. UART_Configuration():串口初始化
void UART_Configuration(uint32_t bound) {
// 使能USART1、GPIOA時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置TX(PA9):復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置RX(PA10):浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 串口參數(shù):115200波特率,8位數(shù)據(jù),1位停止位
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE); // 使能串口
}
4. TIM_Configuration():定時(shí)器 TIM9 配置
void TIM_Configuration(void) {
// 使能TIM9時(shí)鐘(APB2總線)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
// 定時(shí)器參數(shù):
TIM_TimeBaseStructure.TIM_Period = 9999; // 自動重載值(0~9999,共10000個(gè)周期)
// 預(yù)分頻器:PCLK2頻率/10000 - 1(例如PCLK2=72MHz → 72000000/10000 - 1=7199)
TIM_TimeBaseStructure.TIM_Prescaler = (clocks.PCLK2_Frequency / 10000) - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM9, &TIM_TimeBaseStructure); // 初始化定時(shí)器
// 使能更新中斷
TIM_ITConfig(TIM9, TIM_IT_Update, ENABLE);
// 中斷配置(NVIC):
NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn; // TIM9中斷通道(與TIM1共享中斷向量)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 搶占優(yōu)先級0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子優(yōu)先級3
NVIC_Init(&NVIC_InitStructure); // 使能中斷
TIM_Cmd(TIM9, ENABLE); // 啟動定時(shí)器
}
5. 中斷處理函數(shù):TIM1_BRK_TIM9_IRQHandler()
void TIM1_BRK_TIM9_IRQHandler(void) {
if (TIM_GetITStatus(TIM9, TIM_IT_Update)) { // 檢查更新中斷標(biāo)志
TIM_ClearITPendingBit(TIM9, TIM_IT_Update); // 清除中斷標(biāo)志
printf("%sn", __FUNCTION__); // 打印函數(shù)名("TIM1_BRK_TIM9_IRQHandler")
}
}
6. printf()重定向:串口輸出
int fputc(int c, FILE *f) {
if (c == 'n') SER_PutChar('r'); // 換行時(shí)添加回車
SER_PutChar(c); // 通過串口發(fā)送字符
return c;
}
該代碼演示了 W55MH32 定時(shí)器 TIM9 的基本用法:配置更新中斷,周期性觸發(fā)并通過串口輸出信息。核心流程:定時(shí)器初始化(預(yù)分頻器、周期)→ 啟用中斷 → 中斷處理(打印信息)。適用于需要周期性任務(wù)的場景(如定時(shí)采樣、心跳信號)。
8.2 下載驗(yàn)證

WIZnet 是一家無晶圓廠半導(dǎo)體公司,成立于 1998 年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨(dú)特的專利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營銷。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
-
單片機(jī)
+關(guān)注
關(guān)注
6078文章
45541瀏覽量
672507 -
以太網(wǎng)
+關(guān)注
關(guān)注
41文章
6097瀏覽量
181347 -
計(jì)數(shù)器
+關(guān)注
關(guān)注
32文章
2319瀏覽量
98421 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3369瀏覽量
124245
發(fā)布評論請先 登錄
第二十章 TIM——基本定時(shí)器
明德?lián)P視頻分享點(diǎn)撥FPGA課程--第二十一章 ?矩陣鍵盤工程
【每日一練】RT-Thread Nano-ESP82266 WIFI-2 代碼測試(第二十一節(jié)學(xué)習(xí)視頻)
第二十一講 組合邏輯電路中的競爭冒險(xiǎn)
模擬電路網(wǎng)絡(luò)課件 第二十一節(jié):場效應(yīng)管與BJT放大電路的比較
第二十一屆中國西部國際投資貿(mào)易洽談會開幕 全方位展示工業(yè)4.0以來最新科技成果
獲雙項(xiàng)榮譽(yù):中科智云受邀出席第二十一屆中國科學(xué)家論壇
第二十一屆電感變壓器產(chǎn)業(yè)峰會正式啟動!
圖撲軟件亮相第二十一屆中國·海峽創(chuàng)新項(xiàng)目成果交易會
閃耀灣區(qū),諾安智能獲評第二十一屆“深圳知名品牌(灣區(qū)知名品牌)”稱號
2024第二十一屆(上海)國際物聯(lián)網(wǎng)展覽會4月24日-26日開幕
云知聲亮相第二十一屆中國-東盟博覽會
魏德米勒亮相第二十一屆工業(yè)自動化與標(biāo)準(zhǔn)化研討會
龍芯中科亮相第二十一屆工業(yè)自動化與標(biāo)準(zhǔn)化研討會
【展會直擊】2025年第二十一屆中國國際消防設(shè)備技術(shù)交流展覽會展會現(xiàn)場
第二十一章 TIM——通用定時(shí)器
評論