女人荫蒂被添全过程13种图片,亚洲+欧美+在线,欧洲精品无码一区二区三区 ,在厨房拨开内裤进入毛片

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

第二十一章 TIM——通用定時器

W55MH32 ? 來源:W55MH32 ? 作者:W55MH32 ? 2025-06-20 13:57 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機

W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。

在封裝規格上,W55MH32 提供了兩種選擇:QFN100和QFN68。

W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業控制中多樣化的連接需求,無論是與各類傳感器、執行器的通信,還是對復雜工業協議的支持,都能游刃有余,成為復雜工控領域的理想選擇。 同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網關模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。

此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網絡通信安全再添保障。

為助力開發者快速上手與深入開發,基于W55MH32L這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。

若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

wKgZPGgbOfaANhwzACodXd3sVzg463.png

第二十一章 TIM——通用定時器

1 定時器簡介

通用定時器是一個通過可編程預分頻器驅動的 16 位自動裝載計數器構成。它適用于多種場合,包括測量輸入信號的脈沖長度(輸入捕獲)或者產生輸出波形(輸出比較和PWM)。使用定時器預分頻器和 RCC 時鐘控制器預分頻器,脈沖長度和波形周期可以在幾個微秒到幾個毫秒間調整。每個定時器都是完全獨立的,沒有互相共享任何資源。它們可以一起同步操作

2 通用定時器主要功能

主要功能

通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定時器功能包括:

  • ?16 位向上、向下、向上/向下自動裝載計數器
  • ?16 位可編程(可以實時修改)預分頻器,計數器時鐘頻率的分頻系數為 1~65536 之間的任意數值
  • ?4 個獨立通道:
    • ······輸入捕獲
    • ······輸出比較
    • ······PWM 生成(邊緣或中間對齊模式)
    • ······單脈沖模式輸出
  • ?使用外部信號控制定時器和定時器互連的同步電路
  • ?如下事件發生時產生中斷/DMA:
    • ······更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
    • ·······觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
    • ·······輸入捕獲
    • ······輸出比較
  • ?支持針對定位的增量(正交)編碼器和霍爾傳感器電路
  • ?觸發輸入作為外部時鐘或者按周期的電流管理

通用定時器功能框圖如下:

wKgZPGgwPCaAa0opAAT_Tn50a4U050.png

3 通用定時器功能描述

3.1 時基單元

可編程通用定時器的主要部分是一個16位計數器和與其相關的自動裝載寄存器。這個計數器可 以向上計數、向下計數或者向上向下雙向計數。此計數器時鐘由預分頻器分頻得到。

計數器、自動裝載寄存器和預分頻器寄存器可以由軟件讀寫,在計數器運行時仍可以讀寫。 時基單元包含:

  • ?計數器寄存器(TIMx_CNT)
  • ?預分頻器寄存器 (TIMx_PSC)
  • ?自動裝載寄存器 (TIMx_ARR)

自動裝載寄存器是預先裝載的,寫或讀自動重裝載寄存器將訪問預裝載寄存器。 根據在

TIMx_CR1 寄存器中的自動裝載預裝載使能位(ARPE)的設置,預裝載寄存器的內容被立即或在 每次的更新事件 UEV 時傳送到影子寄存器。當計數器達到溢出條件(向下計數時的下溢條件)并當TIMx_CR1 寄存器中的 UDIS 位等于'0'時,產生更新事件。更新事件也可以由軟件產生。隨后會詳細描述每一種配置下更新事件的產生。

計數器由預分頻器的時鐘輸出 CK_CNT 驅動,僅當設置了計數器 TIMx_CR1 寄存器中的計數器使能位(CEN)時,CK_CNT 才有效。

注:真正的計數器使能信號 CNT_EN 是在 CEN 的一個時鐘周期后被設置。

預分頻器描述

預分頻器可以將計數器的時鐘頻率按 1 到 65536 之間的任意值分頻。它是基于一個(在 TIMx_PSC 寄存器中的)16 位寄存器控制的 16 位計數器。這個控制寄存器帶有緩沖器,它能夠在工作時被改變。新的預分頻器參數在下一次更新事件到來時被采用給出了在預分頻器運行時,更改計數器參數的例子。當預分頻器的參數從 1 變到 2 時,計數器的時序圖如下:

wKgZO2gwPCWAKPwvAAEG4kQa5fk240.png

當預分頻器的參數從 1 變到 4 時,計數器的時序圖如下:

wKgZO2gwPCSAW72wAACMOq8Qgls140.png

3.2 計數器模式

向上計數模式

在向上計數模式中,計數器從 0 計數到自動加載值(TIMx_ARR 計數器的內容),然后重新從 0 開始計數并且產生一個計數器溢出事件。

每次計數器溢出時可以產生更新事件,在 TIMx_EGR 寄存器中(通過軟件方式或者使用從模式控 制器)設置 UG 位也同樣可以產生一個更新事件。

設置 TIMx_CR1 寄存器中的 UDIS 位,可以禁止更新事件;這樣可以避免在向預裝載寄存器中寫 入新值時更新影子寄存器。在 UDIS 位被清'0'之前,將不產生更新事件。但是在應該產生更新事 件時,計數器仍會被清'0',同時預分頻器的計數也被請 0(但預分頻系數不變)。此外,如果設置 了TIMx_CR1 寄存器中的 URS 位(選擇更新請求),設置 UG 位將產生一個更新事件 UEV,但硬件 不設置 UIF 標志(即不產生中斷或 DMA 請求);這是為了避免在捕獲模式下清除計數器時,同時產 生更新和捕獲中斷。

當發生一個更新事件時,所有的寄存器都被更新,硬件同時(依據 URS 位)設置更新標志位(TIMx_SR 寄存器中的 UIF 位)。

預分頻器的緩沖區被置入預裝載寄存器的值(TIMx_PSC 寄存器的內容)。

自動裝載影子寄存器被重新置入預裝載寄存器的值(TIMx_ARR)。

下圖給出一些例子,當 TIMx_ARR=0x36 時計數器在不同時鐘頻率下的動作。內部時鐘分頻因子為 1時,計數器時序圖:

wKgZPGgwPCSAHWlSAAC85xwy83Q518.png

內部時鐘分頻因子為 2,計數器時序圖:

wKgZPGgwPCSAdY6nAACuVr6XyfE872.png

內部時鐘分頻因子為4,計數器時序圖:

wKgZO2gwPCSAR_BXAACXfse9JB4958.png

內部時鐘分頻因子為N,計數器時序圖:

wKgZO2gwPCSAceUeAACMOq8Qgls239.png

當 ARPE=0 時的更新事件(TIMx_ARR 沒有預裝入),計數器時序圖:

wKgZO2gwPCWAc56MAAD1hC4nwEE677.png

當 ARPE=1 時的更新事件(預裝入了 TIMx_ARR),計數器時序圖:

wKgZPGgwPCWAaH8oAAEXDOVYmes459.png

3.3 捕獲/比較通道

每一個捕獲/比較通道都是圍繞著一個捕獲/比較寄存器(包含影子寄存器),包括捕獲的輸入部分(數字濾波、多路復用和預分頻器),和輸出部分(比較器和輸出控制)。 下面幾張圖是一個捕獲/比較通道概覽。

輸入部分對相應的 TIx 輸入信號采樣,并產生一個濾波后的信號 TIxF。然后,一個帶極性選擇的邊緣檢測器產生一個信號(TIxFPx),它可以作為從模式控制器的輸入觸發或者作為捕獲控制。該信號通過預分頻進入捕獲寄存器(ICxPS):

wKgZPGgwPCWABlu8AAD2Sa9rtkI445.png

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

wKgZO2gwPCaAc2-UAAGO4NWA5DE462.png

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

wKgZPGgwPCWAcHV3AADFO3BLFNA013.png

捕獲/比較模塊由一個預裝載寄存器和一個影子寄存器組成。讀寫過程僅操作預裝載寄存器。

在捕獲模式下,捕獲發生在影子寄存器上,然后再復制到預裝載寄存器中。

在比較模式下,預裝載寄存器的內容被復制到影子寄存器中,然后影子寄存器的內容和計數器進行比較。

3.4 輸入捕獲模式

根據輸入信號的特點,配置輸入濾波器為所需的帶寬(即輸入為 TIx 時,輸入濾波器控制位是TIMx_CCMRx 寄存器中的 ICxF 位)。假設輸入信號在最多 5 個內部時鐘周期的時間內抖動,我們須配置濾波器的帶寬長于 5 個時鐘周期。因此我們可以(以 fDTS 頻率)連續采樣 8 次,以確 認在 TI1 上一次真實的邊沿變換,即在 TIMx_CCMR1 寄存器中寫入 IC1F=0011。

選擇 TI1 通道的有效轉換邊沿,在 TIMx_CCER 寄存器中寫入 CC1P=0(上升沿)。

配置輸入預分頻器。在本例中,我們希望捕獲發生在每一個有效的電平轉換時刻,因此預 分頻器被禁止(寫 TIMx_CCMR1 寄存器的 IC1PS=00)。

設置 TIMx_CCER 寄存器的 CC1E=1,允許捕獲計數器的值到捕獲寄存器中。

如果需要,通過設置TIMx_DIER寄存器中的CC1IE位允許相關中斷請求,通過設置 TIMx_DIER寄存器中的 CC1DE 位允許 DMA 請求。

當發生一個輸入捕獲時:

產生有效的電平轉換時,計數器的值被傳送到 TIMx_CCR1 寄存器。

CC1IF 標志被設置(中斷標志)。當發生至少 2 個連續的捕獲時,而 CC1IF 未曾被清除, CC1OF也被置'1'。

如設置了 CC1IE 位,則會產生一個中斷。

如設置了 CC1DE 位,則還會產生一個 DMA 請求。

為了處理捕獲溢出,建議在讀出捕獲溢出標志之前讀取數據,這是為了避免丟失在讀出捕獲溢 出標志之后和讀取數據之前可能產生的捕獲溢出信息。

注: 設置 TIMx_EGR 寄存器中相應的 CCxG 位,可以通過軟件產生輸入捕獲中斷和/或 DMA 請求

3.5 PWM 輸入模式(僅適用于 TIM9/12)

該模式是輸入捕獲模式的一個特例,除下列區別外,操作與輸入捕獲模式相同:

兩個 ICx 信號被映射至同一個 TIx 輸入。

這 2 個 ICx 信號為邊沿有效,但是極性相反。

其中一個 TIxFP 信號被作為觸發輸入信號,而從模式控制器被配置成復位模式。

例如,你需要測量輸入到 TI1 上的 PWM 信號的長度(TIMx_CCR1 寄存器)和占空比(TIMx_CCR2 寄存器),具體步驟如下(取決于 CK_INT 的頻率和預分頻器的值)

選擇 TIMx_CCR1 的有效輸入:置 TIMx_CCMR1 寄存器的 CC1S=01(選擇 TI1)。

選擇 TI1FP1 的有效極性(用來捕獲數據到 TIMx_CCR1 中和清除計數器):置 CC1P=0(上升沿有效)。

選擇 TIMx_CCR2 的有效輸入:置 TIMx_CCMR1 寄存器的 CC2S=10(選擇 TI1)。

選擇 TI1FP2 的有效極性(捕獲數據到 TIMx_CCR2):置 CC2P=1(下降沿有效)。

選擇有效的觸發輸入信號:置 TIMx_SMCR 寄存器中的 TS=101(選擇 TI1FP1)。

配置從模式控制器為復位模式:置 TIMx_SMCR 中的 SMS=100。

使能捕獲:置 TIMx_CCER 寄存器中 CC1E=1 且 CC2E=1。

PWM 輸入模式時序如下:

3.6 輸出比較模式

此項功能是用來控制一個輸出波形,或者指示一段給定的的時間已經到時。 當計數器與捕獲/比較寄存器的內容相同時,輸出比較功能做如下操作:

將輸出比較模式(TIMx_CCMRx 寄存器中的 OCxM 位)和輸出極性(TIMx_CCER 寄存器中的 CCxP

位)定義的值輸出到對應的引腳上。在比較匹配時,輸出引腳可以保持它的電平(OCxM=000)、

被設置成有效電平(OCxM=001)、被設置成無效電平(OCxM=010)或進行翻 轉(OCxM=011)。

設置中斷狀態寄存器中的標志位(TIMx_SR 寄存器中的 CCxIF 位)。

若設置了相應的中斷屏蔽(TIMx_DIER 寄存器中的 CCxIE 位),則產生一個中斷。

若設置了相應的使能位(TIMx_DIER 寄存器中的 CCxDE 位,TIMx_CR2 寄存器中的 CCDS 位 選擇 DMA 請求功能),則產生一個 DMA 請求。

TIMx_CCMRx 中的 OCxPE 位選擇 TIMx_CCRx 寄存器是否需要使用預裝載寄存器。 在輸出比較模式下,更新事件 UEV 對 OCxREF 和 OCx 輸出沒有影響。

同步的精度可以達到計數器的一個計數周期。輸出比較模式(在單脈沖模式下)也能用來輸出一個單脈沖。輸出比較模式的配置步驟:

1. 選擇計數器時鐘(內部,外部,預分頻器)

2. 將相應的數據寫入 TIMx_ARR 和 TIMx_CCRx 寄存器中

3. 如果要產生一個中斷請求和/或一個 DMA 請求,設置 CCxIE 位和/或 CCxDE 位。

4. 選擇輸出模式,例如當計數器CNT與CCRx匹配時翻轉 OCx的輸出引腳,CCRx預裝載未 用,開啟 OCx 輸出且高電平有效,則必須設置 OCxM='011' 、OCxPE='0' 、CCxP='0'和 CCxE='1'。

5. 設置 TIMx_CR1 寄存器的 CEN 位啟動計數器

TIMx_CCRx 寄存器能夠在任何時候通過軟件進行更新以控制輸出波形,條件是未使用預裝載寄 存器(OCxPE='0',否則 TIMx_CCRx 影子寄存器只能在發生下一次更新事件時被更新)。下圖給出了一個例子。

wKgZO2gwPCWAXVOPAADfcm6DNNc555.png

輸出比較模式,翻轉 OC1。

3.7 PWM 模式

脈沖寬度調制模式可以產生一個由 TIMx_ARR 寄存器確定頻率、由 TIMx_CCRx 寄存器確定占空比的信號。

在 TIMx_CCMRx 寄存器中的 OCxM 位寫入'110'(PWM 模式 1)或'111'(PWM 模式 2),能夠獨立地設置每個 OCx 輸出通道產生一路 PWM。必須設置 TIMx_CCMRx 寄存器 OCxPE 位以使能相應的預 裝載寄存器,最后還要設置 TIMx_CR1 寄存器的 ARPE 位,(在向上計數或中心對稱模式中)使能 自動重裝載的預裝載寄存器。

僅當發生一個更新事件的時候,預裝載寄存器才能被傳送到影子寄存器,因此在計數器開始計 數之前,必須通過設置 TIMx_EGR 寄存器中的 UG 位來初始化所有的寄存器。OCx 的極性可以通過軟件在 TIMx_CCER 寄存器中的 CCxP 位設置,它可以設置為高電平有效或 低電平有效。TIMx_CCER寄存器中的CCxE位控制OCx輸出使能。詳見TIMx_CCERx寄存器的 描述。

在 PWM 模式(模式 1 或模式 2)下,TIMx_CNT 和 TIMx_CCRx 始終在進行比較,(依據計數器的計數方向) 以確定是否符合 TIMx_CCRx ≤ TIMx_CNT 或者 TIMx_CNT ≤ TIMx_CCRx 。然而 為了與OCREF_CLR 的功能(在下一個 PWM 周期之前, ETR 信號上的一個外部事件能夠清除 OCxREF) 一致,OCxREF 信號只能在下述條件下產生:

當比較的結果改變

當輸出比較模式(TIMx_CCMRx 寄存器中的 OCxM 位)從“凍結”(無比較,OCxM='000')切換到

某個 PWM 模式(OCxM='110'或'111')。這樣在運行中可以通過軟件強置 PWM 輸出。

根據 TIMx_CR1寄存器中 CMS位的狀態,定時器能夠產生邊沿對齊的 PWM信號或中央對齊的 PWM信號。

PWM 邊沿對齊模式

  • 向上計數配置

當 TIMx_CR1 寄存器中的 DIR 位為低的時候執行向上計數。

下面是一個 PWM 模式 1 的例子。當 TIMx_CNT

如果比較值為 0,則 OCxREF 保持為'0' 。下圖為 TIMx_ARR=8 時邊沿對齊的 PWM 波形實例。邊沿對齊的 PWM 波形(ARR=8)如下:

wKgZO2gwPCWAItbxAACnLmnSlZk325.png
  • 向下計數的配置

當 TIMx_CR1 寄存器的 DIR 位為高時執行向下計數。在 PWM 模式 1 ,當TIMx_CNT>TIMx_CCRx 時參考信 號 OCxREF 為低,否 則為高。 如果TIMx_CCRx 中的比較值大于 TIMx_ARR 中的自動重裝載值,則 OCxREF 保持為'1'。該模式下不 能產生 0%的 PWM 波形。

PWM 中央對齊模式

當 TIMx_CR1 寄存器中的 CMS 位不為'00'時,為中央對齊模式(所有其他的配置對 OCxREF/OCx 信號都有相同的作用)。根據不同的 CMS 位設置,比較標志可以在計數器向上計數時被置'1'、在計數器向下計數時被置'1'、或在計數器向上和向下計數時被置'1' 。TIMx_CR1 寄存器中的計數方向位(DIR)由硬件更新,不要用軟件修改它。

下圖給出了一些中央對齊的 PWM 波形的例子

TIMx_ARR=8

PWM 模式 1

TIMx_CR1 寄存器中的 CMS=01,在中央對齊模式 1 時,當計數器向下計數時設置比較標志。

wKgZPGgwPCaARJiwAAF6jCEfH6Q797.png

使用中央對齊模式的提示:

進入中央對齊模式時,使用當前的向上/向下計數配置;這就意味著計數器向上還是向下計數取決于 TIMx_CR1 寄存器中 DIR 位的當前值。此外,軟件不能同時修改 DIR 和 CMS 位。

不推薦當運行在中央對齊模式時改寫計數器,因為這會產生不可預知的結果。特別地: 如果寫入計數器的值大于自動重加載的值(TIMx_CNT>TIMx_ARR),則方向不會被更新。 例如,如果計數器正在向上計數,它就會繼續向上計數。如果將 0 或者 TIMx_ARR 的值寫入計數器,方向被更新,但不產生更新事件 UEV。

使用中央對齊模式最保險的方法,就是在啟動計數器之前產生一個軟件更新(設置 TIMx_EGR 位中的 UG 位),不要在計數進行過程中修改計數器的值。

4 PWM

4.1 代碼解析

1.頭文件包含和全局變量定義

 
#include 
#include 
#include 
#include "delay.h"
#include "w55mh32.h"

USART_TypeDef *USART_TEST = USART1;
 

頭文件:引入了標準庫頭文件和自定義頭文件,delay.h可能用于延時功能,w55mh32.h可能包含硬件相關的定義。

全局變量:USART_TEST是一個指向USART_TypeDef類型的指針,被初始化為USART1,用于后續的串口操作。

2.函數聲明

 
void              UART_Configuration(uint32_t bound);
void              TIM_Configuration(void);
void              RCC_ClkConfiguration(void);

聲明了三個函數:

UART_Configuration():用于配置串口通信。

TIM_Configuration():用于配置定時器并輸出 PWM 信號。

RCC_ClkConfiguration():用于配置系統時鐘。

main()函數

 
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);
}

系統初始化:

調用RCC_ClkConfiguration()函數配置系統時鐘。

調用delay_init()函數初始化延時功能。

調用UART_Configuration()函數配置串口通信,波特率設置為 115200。

調用RCC_GetClocksFreq()函數獲取系統時鐘頻率信息。

信息輸出:

通過printf()函數輸出系統時鐘頻率信息,包括系統時鐘(SYSCLK)、高級高性能總線時鐘(HCLK)、低速外設總線時鐘(PCLK1)、高速外設總線時鐘(PCLK2)和 ADC 時鐘(ADCCLK)。

輸出提示信息 “TIM Out Test.”,表示開始定時器輸出測試。

定時器配置:

調用TIM_Configuration()函數配置定時器并輸出 PWM 信號。

主循環:

while (1);是一個無限循環,使程序停在這里,等待定時器輸出 PWM 信號。

4.RCC_ClkConfiguration()函數

 
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);
}

 

時鐘復位:

調用RCC_DeInit()函數將 RCC 寄存器復位為默認值。

外部高速時鐘(HSE)配置:調用RCC_HSEConfig()函數使能外部高速時鐘(HSE)。

通過while循環等待 HSE 準備好(RCC_FLAG_HSERDY標志置位)。

鎖相環(PLL)配置:

調用RCC_PLLCmd()函數禁用 PLL。

調用RCC_PLLConfig()函數配置 PLL,將 HSE 作為 PLL 的輸入時鐘源,PLL 乘法因子設置為 9。

調用RCC_PLLCmd()函數使能 PLL。

通過while循環等待 PLL 準備好(RCC_FLAG_PLLRDY標志置位)。

系統時鐘配置:

調用RCC_SYSCLKConfig()函數將 PLL 輸出作為系統時鐘。

總線時鐘配置:

調用RCC_HCLKConfig()函數將系統時鐘(SYSCLK)直接作為高級高性能總線時鐘(HCLK)。

調用RCC_PCLK1Config()函數將 HCLK 分頻 2 作為低速外設總線時鐘(PCLK1)。

調用RCC_PCLK2Config()函數將 HCLK 直接作為高速外設總線時鐘(PCLK2)。

低速內部時鐘(LSI)和高速內部時鐘(HSI)配置:

調用RCC_LSICm()函數使能低速內部時鐘(LSI),并等待 LSI 準備好(RCC_FLAG_LSIRDY標志置位)。

調用RCC_HSICmd()函數使能高速內部時鐘(HSI),并等待 HSI 準備好(RCC_FLAG_HSIRDY標志置位)。

5 TIM_Configuration()函數

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
}


 

時鐘使能:

調用RCC_APB1PeriphClockCmd()函數使能定時器 3(TIM3)的時鐘。

調用RCC_APB2PeriphClockCmd()函數使能 GPIOA 和 AFIO(復用功能模塊)的時鐘。

GPIO 配置:

將GPIOA的Pin 7配置為復用推挽輸出模式,用于輸出 TIM3 的通道 2(TIM_CH2)的 PWM 信號。

配置 GPIO 的速度為 50MHz。

定時器基本參數配置:

定義TIM_TimeBaseInitTypeDef類型的結構體TIM_TimeBaseStructure,用于配置定時器的基本參數。

TIM_Period設置為 99,表示定時器的自動重載值。

TIM_Prescaler根據PCLK1的頻率進行設置,將定時器的時鐘頻率進行分頻。

TIM_ClockDivision設置為TIM_CKD_DIV1,表示時鐘分頻因子為 1。

TIM_CounterMode設置為TIM_CounterMode_Up,表示定時器采用向上計數模式。

調用TIM_TimeBaseInit()函數根據上述參數初始化 TIM3。

定時器輸出比較(PWM)配置:

定義TIM_OCInitTypeDef類型的結構體TIM_OCInitStructure,用于配置定時器的輸出比較(PWM)參數。

TIM_OCMode設置為TIM_OCMode_PWM2,表示采用 PWM 模式 2。

TIM_OutputState和TIM_OutputNState都設置為TIM_OutputState_Enable,表示使能輸出和互補輸出。

TIM_Pulse設置為99 / 2,表示 PWM 信號的脈沖寬度。

TIM_OCPolarity和TIM_OCNPolarity都設置為TIM_OCPolarity_Low,表示輸出極性為低。

TIM_OCIdleState設置為TIM_OCIdleState_Set,TIM_OCNIdleState設置為TIM_OCIdleState_Reset,表示空閑狀態下的輸出電平。

調用TIM_OC2Init()函數根據上述參數初始化 TIM3 的通道 2。

預裝載寄存器配置:

調用TIM_OC2PreloadConfig()函數使能 TIM3 通道 2 的預裝載寄存器。

調用TIM_ARRPreloadConfig()函數使能 TIM3 的自動重載寄存器的預裝載功能。

定時器使能:

調用TIM_Cmd()函數使能 TIM3。

調用TIM_CtrlPWMOutputs()函數使能高級定時器的 PWM 輸出。

6 UART_Configuration()函數

 
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);
}

 

時鐘使能:

調用RCC_APB2PeriphClockCmd()函數使能 USART1 和 GPIOA 的時鐘。

GPIO 配置:

將GPIOA的Pin 9配置為復用推挽輸出模式,用于 USART1 的發送功能。

將GPIOA的Pin 10配置為浮空輸入模式,用于 USART1 的接收功能。

配置 GPIO 的速度為 50MHz。

USART 配置:

定義USART_InitTypeDef類型的結構體USART_InitStructure,用于配置 USART 的基本參數。

USART_BaudRate根據傳入的參數bound設置波特率。

USART_WordLength設置為USART_WordLength_8b,表示數據位為 8 位。

USART_StopBits設置為USART_StopBits_1,表示停止位為 1 位。

USART_Parity設置為USART_Parity_No,表示無校驗位。

USART_HardwareFlowControl設置為USART_HardwareFlowControl_None,表示無硬件流控制。

USART_Mode設置為USART_Mode_Rx | USART_Mode_Tx,表示支持收發模式。

調用USART_Init()函數根據上述參數初始化 USART1。

調用USART_Cmd()函數使能 USART1。

7. SER_PutChar()和fputc()函數

 
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()函數用于將一個字符發送到串口,通過USART_GetFlagStatus()函數檢查串口發送完成標志,等待發送完成后,調用USART_SendData()函數發送字符。

fputc()函數重定向了printf()函數的輸出,將字符通過串口發送出去,當遇到換行符n時,先調用SER_PutChar('r')函數發送回車符r。

4.2下載驗證

wKgZPGgwPCWAA25eAACq14ujYbE992.png

如果想查看PWM輸出的占空比,可以在循環里加這段代碼:

 
 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的占空比:

wKgZPGgwPCWAA25eAACq14ujYbE992.png

5 更新中斷

5.1 代碼解析

1. main()函數:初始化與啟動

 
int main(void) {
    delay_init();          // 延時初始化(sysTick)
    UART_Configuration(115200);  // 串口配置(115200波特率)
    TIM_Configuration();   // 定時器TIM3配置

    // 打印系統時鐘
    printf("SYSCLK: %3.1fMhz...n", (float)clocks.SYSCLK_Frequency / 1000000);

    while (1);  // 主循環(空,依賴中斷)
}

 

2. UART_Configuration():串口初始化

 
void UART_Configuration(uint32_t bound) {
    // 使能USART1、GPIOA時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    // 配置TX(PA9):復用推挽輸出
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置RX(PA10):浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 串口參數:115200波特率,8位數據,1位停止位
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);  // 使能串口
}
 

3. TIM_Configuration():定時器 TIM3 配置

 
void TIM_Configuration(void) {
    // 使能TIM3時鐘(APB1總線)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // 定時器參數:
    TIM_TimeBaseStructure.TIM_Period = 9999;  // 自動重載值(0~9999,共10000個周期)
    // 預分頻器:PCLK1頻率/1MHz - 1(例如PCLK1=36MHz → 36-1=35)
    TIM_TimeBaseStructure.TIM_Prescaler = (clocks.PCLK1_Frequency / 1000000) - 1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 向上計數模式

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  // 初始化定時器

    // 使能更新中斷
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

    // 中斷配置(NVIC):
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  // TIM3中斷通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  // 搶占優先級0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  // 子優先級3
    NVIC_Init(&NVIC_InitStructure);  // 使能中斷

    TIM_Cmd(TIM3, ENABLE);  // 啟動定時器
}
 

4. 中斷處理函數:TIM3_IRQHandler()

 
void TIM3_IRQHandler(void) {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update)) {  // 檢查更新中斷標志
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  // 清除中斷標志
        printf("%sn", __FUNCTION__);  // 打印函數名("TIM3_IRQHandler")
    }
}
 

該代碼演示了 W55MH32 定時器的基本用法:配置 TIM3 的更新中斷,周期性觸發并通過串口輸出信息。核心流程:定時器初始化(預分頻器、周期)→ 啟用中斷 → 中斷處理(打印信息)。適用于需要周期性任務的場景(如定時采樣、心跳信號)。

5.2 下載驗證

wKgZO2gwPCWAMSVQAACq14ujYbE929.png

6 TIM_CalibrationLsi

6.1 代碼解析

1. 全局變量

 
uint8_t  TIM5_CAPTURE_STA = 0; // 輸入捕獲狀態(位7:完成標志,位6:上升沿標志,位0-5:溢出次數)
uint16_t TIM5_CAPTURE_VAL;     // 捕獲值(TIM5計數器值)

2. main()函數:初始化與主循環

 
int main(void) {
    RCC_ClkConfiguration();       // 系統時鐘配置(HSE→PLL→72MHz)
    delay_init();                  // 延時初始化(SysTick)
    UART_Configuration(115200);    // 串口配置(115200波特率)
    TIM_Configuration();          // TIM5輸入捕獲配置(LSI測量)

    // 主循環:處理捕獲結果
    while (1) {
        if (TIM5_CAPTURE_STA & 0x80) { // 捕獲完成標志
            // 計算總時間:溢出次數×65536 + 捕獲值
            temp = (TIM5_CAPTURE_STA & 0x3F) * 65536 + TIM5_CAPTURE_VAL;
            printf("LSI周期: %d μsnLSI頻率: %f Hzn", temp, 1000000.0 / temp);
            TIM5_CAPTURE_STA = 0; // 重置狀態,準備下次捕獲
        }
    }
}

 

3. TIM_Configuration():定時器輸入捕獲配置

 
void TIM_Configuration(void) {
    // 使能TIM5和AFIO時鐘(用于引腳重映射)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    // 重映射:LSI → TIM5_CH4(無需外部引腳)
    GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);

    // 時基配置:
    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;                  // 最大計數值(65535)
    // 預分頻器:PCLK1×2 / 1MHz - 1(TIMx時鐘=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);  // 啟動定時器
}

4. 中斷處理函數:TIM5_IRQHandler()

 
void TIM5_IRQHandler(void) {
    if (! (TIM5_CAPTURE_STA & 0x80)) { // 未完成捕獲
        // 處理更新中斷(定時器溢出)
        if (TIM_GetITStatus(TIM5, TIM_IT_Update)) {
            if (TIM5_CAPTURE_STA & 0x40) { // 已捕獲上升沿,溢出計數
                if ((TIM5_CAPTURE_STA & 0x3F) == 0x3F) { // 溢出32次(超時)
                    TIM5_CAPTURE_STA |= 0x80; // 標記失敗
                } else {
                    TIM5_CAPTURE_STA++; // 溢出次數+1
                }
            }
        }

        // 處理捕獲中斷(CH4上升沿)
        if (TIM_GetITStatus(TIM5, TIM_IT_CC4)) {
            if (TIM5_CAPTURE_STA & 0x40) { // 已捕獲上升沿,現在捕獲下降沿(假設LSI是方波)
                TIM5_CAPTURE_VAL = TIM_GetCapture4(TIM5); // 讀取捕獲值
                TIM5_CAPTURE_STA |= 0x80; // 標記完成
            } else { // 首次捕獲上升沿
                TIM5_CAPTURE_STA = 0x40; // 標記已捕獲上升沿
                TIM_SetCounter(TIM5, 0); // 計數器清零
            }
        }
    }
    TIM_ClearITPendingBit(TIM5, TIM_IT_CC4 | TIM_IT_Update); // 清除中斷標志
}

 

5. 系統時鐘配置:RCC_ClkConfiguration()

 
void RCC_ClkConfiguration(void) {
    // 初始化系統時鐘: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(內部低速時鐘,~32kHz)
}

 

此代碼是 W55MH32 定時器高級應用的典型示例,展示了如何利用硬件特性測量內部信號,適用于嵌入式系統調試和時鐘校準場景。

6.2 下載驗證

wKgZPGgwPCWACfVaAADwt9nyGwE077.png

7 TIM_InputCapture

7.1 代碼解析

1. 全局變量

 
uint8_t  TIM3_CAPTURE_STA = 0; // 輸入捕獲狀態(位7:完成,位6:上升沿標志,位0-5:溢出次數)
uint16_t TIM3_CAPTURE_VAL;     // 捕獲值(TIM3計數器值)

2. main()函數:初始化與主循環

 
int main(void) {
    RCC_ClkConfiguration();       // 系統時鐘配置(72MHz)
    UART_Configuration(115200);    // 串口初始化
    TIM_Configuration();          // TIM3輸入捕獲配置

    while (1) {
        if (TIM3_CAPTURE_STA & 0x80) { // 捕獲完成
            // 計算總時間:溢出次數×65536 + 捕獲值(單位:μs)
            temp = (TIM3_CAPTURE_STA & 0x3F) * 65536 + TIM3_CAPTURE_VAL;
            printf("HIGH:%d usrn", temp); // 打印高電平時間
            TIM3_CAPTURE_STA = 0; // 重置狀態,準備下次捕獲
        }
    }
}

 

3. TIM_Configuration():定時器輸入捕獲配置

 
void TIM_Configuration(void) {
    // 使能TIM3、GPIOA、AFIO時鐘
    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; // 下拉輸入(根據信號調整)
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 時基配置:
    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;      // 最大計數值(65535)
    TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;   // 預分頻器(72MHz/72=1MHz → 計數周期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); // 啟動定時器
}

 

4. 中斷處理函數:TIM3_IRQHandler()

 
void TIM3_IRQHandler(void) {
    if (! (TIM3_CAPTURE_STA & 0x80)) { // 未完成捕獲
        // 處理溢出中斷
        if (TIM_GetITStatus(TIM3, TIM_IT_Update)) {
            if (TIM3_CAPTURE_STA & 0x40) { // 已捕獲上升沿,統計溢出
                if (TIM3_CAPTURE_STA & 0x3F == 0x3F) { // 溢出32次(超時)
                    TIM3_CAPTURE_STA |= 0x80; // 標記失敗
                } else {
                    TIM3_CAPTURE_STA++; // 溢出次數+1
                }
            }
        }

        // 處理捕獲中斷(CH2上升沿/下降沿)
        if (TIM_GetITStatus(TIM3, TIM_IT_CC2)) {
            if (TIM3_CAPTURE_STA & 0x40) { // 捕獲下降沿(高電平結束)
                TIM3_CAPTURE_VAL = TIM_GetCapture2(TIM3); // 讀取捕獲值
                TIM3_CAPTURE_STA |= 0x80; // 標記完成
                TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Rising); // 切回上升沿捕獲
            } else { // 捕獲上升沿(高電平開始)
                TIM3_CAPTURE_STA = 0x40; // 標記上升沿
                TIM_SetCounter(TIM3, 0); // 計數器清零
                TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Falling); // 切換為下降沿捕獲
            }
        }
    }
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2 | TIM_IT_Update); // 清除中斷標志
}

 

5. 系統時鐘配置

 
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 定時器輸入捕獲的典型應用,展示了如何通過硬件中斷高效測量外部信號,適用于需要高精度時間測量的嵌入式系統。

7.2 下載驗證

wKgZPGgwPCWAb3e0AACPQXfa6mE614.png

8 TIM_Tim9

8.1 代碼解析

1. 頭文件與全局變量

 
#include "w55mh32.h"  // STM32硬件抽象層(寄存器定義)
USART_TypeDef *USART_TEST = USART1;  // 串口外設指針(USART1)

 

2. main()函數:初始化與啟動

 
int main(void) {
    delay_init();          // 延時初始化(sysTick)
    UART_Configuration(115200);  // 串口配置(115200波特率)
    TIM_Configuration();   // 定時器TIM9配置

    // 打印系統時鐘
    printf("SYSCLK: %3.1fMhz...n", (float)clocks.SYSCLK_Frequency / 1000000);

    while (1);  // 主循環(空,依賴中斷)
}

 

3. UART_Configuration():串口初始化

 
void UART_Configuration(uint32_t bound) {
    // 使能USART1、GPIOA時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    // 配置TX(PA9):復用推挽輸出
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置RX(PA10):浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 串口參數:115200波特率,8位數據,1位停止位
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);  // 使能串口
}

 

4. TIM_Configuration():定時器 TIM9 配置

 
void TIM_Configuration(void) {
    // 使能TIM9時鐘(APB2總線)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);

    // 定時器參數:
    TIM_TimeBaseStructure.TIM_Period = 9999;  // 自動重載值(0~9999,共10000個周期)
    // 預分頻器: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;  // 向上計數模式

    TIM_TimeBaseInit(TIM9, &TIM_TimeBaseStructure);  // 初始化定時器

    // 使能更新中斷
    TIM_ITConfig(TIM9, TIM_IT_Update, ENABLE);

    // 中斷配置(NVIC):
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn;  // TIM9中斷通道(與TIM1共享中斷向量)
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  // 搶占優先級0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  // 子優先級3
    NVIC_Init(&NVIC_InitStructure);  // 使能中斷

    TIM_Cmd(TIM9, ENABLE);  // 啟動定時器
}

 

5. 中斷處理函數:TIM1_BRK_TIM9_IRQHandler()

 
void TIM1_BRK_TIM9_IRQHandler(void) {
    if (TIM_GetITStatus(TIM9, TIM_IT_Update)) {  // 檢查更新中斷標志
        TIM_ClearITPendingBit(TIM9, TIM_IT_Update);  // 清除中斷標志
        printf("%sn", __FUNCTION__);  // 打印函數名("TIM1_BRK_TIM9_IRQHandler")
    }
}

 

6. printf()重定向:串口輸出

 
int fputc(int c, FILE *f) {
    if (c == 'n') SER_PutChar('r');  // 換行時添加回車
    SER_PutChar(c);  // 通過串口發送字符
    return c;
}

 

該代碼演示了 W55MH32 定時器 TIM9 的基本用法:配置更新中斷,周期性觸發并通過串口輸出信息。核心流程:定時器初始化(預分頻器、周期)→ 啟用中斷 → 中斷處理(打印信息)。適用于需要周期性任務的場景(如定時采樣、心跳信號)。

8.2 下載驗證

wKgZO2gwPCWAQ5F1AACPZYxXxL8024.png

WIZnet 是一家無晶圓廠半導體公司,成立于 1998 年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU? 面向各種應用中的嵌入式互聯網設備。

WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。

香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6067

    文章

    44973

    瀏覽量

    649540
  • 以太網
    +關注

    關注

    41

    文章

    5627

    瀏覽量

    175580
  • 計數器
    +關注

    關注

    32

    文章

    2291

    瀏覽量

    96300
  • 定時器
    +關注

    關注

    23

    文章

    3298

    瀏覽量

    117764
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    第二十TIM——基本定時器

    本章介紹了W55H32基本定時器TIM6、TIM7,16位向上計數,含時鐘源、預分頻等,講解定時計算及初始化結構體。
    的頭像 發表于 06-20 13:51 ?297次閱讀
    <b class='flag-5'>第二十</b>章 <b class='flag-5'>TIM</b>——基本<b class='flag-5'>定時器</b>

    明德揚視頻分享點撥FPGA課程--第二十一章 ?矩陣鍵盤工程

    第二十一章矩陣鍵盤工程1. 矩陣掃描模塊2. 數碼顯示模塊3. for循環的使用4. 統計模塊5. generate的使用6. 進制轉換模塊7. 頂層模塊http://yunpan.cn/cjZTiDA9pY56x訪問密碼 c359
    發表于 11-09 08:47

    【每日一練】RT-Thread Nano-ESP82266 WIFI-2 代碼測試(第二十一節學習視頻)

    本視頻為【每日一練】的第二十一節學習視頻,注:剛開始學習的童鞋請從第一節視頻開始打卡哦(本節視頻在下面打卡即可)學習任務:1、本節打卡任務大家自由發揮打卡規則詳見:【每日一練】RT-Thread
    發表于 06-06 08:00

    第二十一講 組合邏輯電路中的競爭冒險

    第二十一講 組合邏輯電路中的競爭冒險 6.7.1 競爭冒險現象及其產生的原因一、競爭、冒險1.理想情況2.實際情況3.競
    發表于 03-30 16:25 ?3338次閱讀
    <b class='flag-5'>第二十一</b>講 組合邏輯電路中的競爭冒險

    模擬電路網絡課件 第二十一節:場效應管與BJT放大電路的比較

    模擬電路網絡課件 第二十一節:場效應管與BJT放大電路的比較 場效應管放大電路與BJT放大電路的性能比較
    發表于 09-17 11:01 ?1379次閱讀
    模擬電路網絡課件 <b class='flag-5'>第二十一</b>節:場效應管與BJT放大電路的比較

    第二十一屆中國西部國際投資貿易洽談會開幕 全方位展示工業4.0以來最新科技成果

    2018年5月25日上午九時,第二十一屆中國西部國際投資貿易洽談會在重慶國際博覽中心正式開幕。
    發表于 07-27 09:20 ?2597次閱讀

    西安高新第二十一小學能耗監測及電力監控系統的研究與應用

    ,為普通居民住宅的10~20倍。公共建筑是節能大戶和節能重點,做好公共建筑節能工作,對促進和帶動全社會節能工作,實現節能減排目標,落實“轉方式、調結構”重大戰略具有重要意義。本文介紹西安高新第二十一小學能耗監測及電力監控系統,采集現場配電室的
    發表于 11-25 15:57 ?917次閱讀
    西安高新<b class='flag-5'>第二十一</b>小學能耗監測及電力監控系統的研究與應用

    獲雙項榮譽:中科智云受邀出席第二十一屆中國科學家論壇

    上海2023年5月1日?/美通社/ -- 第二十一屆中國科學家論壇于2023年4月27-28日在北京正式召開。本屆論壇以"中國式現代化與科學技術體系化創新"為主題,來自全國各地的科學家、院士、教授
    的頭像 發表于 05-02 21:38 ?897次閱讀

    【節能學院】西安高新第二十一小學能耗監測及電力監控系統的研究與應用

    公共建筑節能工作,帶動全社會節能工作,實現節能減排目標,落實“轉方式、調結構”重大戰略具有重要意義。本文介紹西安高新第二十一小學能耗監測及電力監控系統,采集現場配電室的
    的頭像 發表于 11-25 18:08 ?1028次閱讀
    【節能學院】西安高新<b class='flag-5'>第二十一</b>小學能耗監測及電力監控系統的研究與應用

    第二十一屆電感變壓產業峰會正式啟動!

    2023年7月21日,第二十一屆(華東)中國磁性元器件行業智能生產暨高性能材料應用技術峰會將于蘇州太湖國際會議中心盛大開幕! 2023年上半年,在下游新能源發展的影響下,電感變壓行業迎來快速發展期
    的頭像 發表于 06-28 14:55 ?878次閱讀
    <b class='flag-5'>第二十一</b>屆電感變壓<b class='flag-5'>器</b>產業峰會正式啟動!

    圖撲軟件亮相第二十一屆中國·海峽創新項目成果交易會

    2023 年 6 月 18 日,第二十一屆中國·海峽創新項目成果交易會(以下簡稱“海創會”)在福建省福州市拉開帷幕。海創會作為福建省廣泛吸納國內外科技成果來閩對接,加快科技成果轉化的平臺,一直以來
    的頭像 發表于 06-30 10:33 ?888次閱讀
    圖撲軟件亮相<b class='flag-5'>第二十一</b>屆中國·海峽創新項目成果交易會

    閃耀灣區,諾安智能獲評第二十一屆“深圳知名品牌(灣區知名品牌)”稱號

    2024年3月5日,深圳知名品牌評價委員會召開第二十一屆“深圳知名品牌”評審會議,審核評選出113個市場占有率高、誠信度高、品牌知名度高的企業品牌為第二十一屆深圳知名品牌。諾安智能在全市50多個細分
    的頭像 發表于 03-20 09:13 ?915次閱讀
    閃耀灣區,諾安智能獲評<b class='flag-5'>第二十一</b>屆“深圳知名品牌(灣區知名品牌)”稱號

    2024第二十一屆(上海)國際物聯網展覽會4月24日-26日開幕

    交流產業信息,把脈發展方向,IOTE 國際物聯網展是每年物聯網行業、企業、用戶交流合作的大型平臺。2024年4月24-26日IOTE?2024第二十一屆國際物聯網展?上海站,在上海世博展覽館開展。
    的頭像 發表于 04-26 17:59 ?898次閱讀
    2024<b class='flag-5'>第二十一</b>屆(上海)國際物聯網展覽會4月24日-26日開幕

    第二十一屆亞太智能建筑論壇精彩回顧

    第二十一屆亞太智能建筑論壇暨第六屆青年智能建筑專家年會在靜安區洲際酒店順利落幕。為期兩天的展會吸引了眾多來賓的熱情關注。在此,安科瑞衷心感謝每一位蒞臨我們展位的朋友,你們的信任與支持是我們不斷前行
    的頭像 發表于 09-01 08:01 ?566次閱讀
    <b class='flag-5'>第二十一</b>屆亞太智能建筑論壇精彩回顧

    云知聲亮相第二十一屆中國-東盟博覽會

    以“親誠惠容同發展 鑲鉆成冠創未來——促進中國—東盟自由貿易區3.0版建設和區域高質量增長”為主題的第二十一屆中國—東盟博覽會(以下簡稱“東博會”)在廣西南寧舉辦。
    的頭像 發表于 10-12 14:18 ?815次閱讀
    云知聲亮相<b class='flag-5'>第二十一</b>屆中國-東盟博覽會
    主站蜘蛛池模板: 长海县| 武安市| 资兴市| 达孜县| 蒙自县| 建水县| 工布江达县| 乐安县| 东乡族自治县| 汉川市| 叶城县| 丽水市| 华阴市| 本溪| 茌平县| 鄂州市| 兴义市| 庆阳市| 巴彦淖尔市| 曲阜市| 吉木乃县| 嘉义市| 五家渠市| 赤峰市| 依安县| 诸城市| 英德市| 会同县| 黄梅县| 资溪县| 喀喇沁旗| 大同市| 尉犁县| 内乡县| 白城市| 西丰县| 栾城县| 略阳县| 高青县| 泗阳县| 肃宁县|