STM32入門之通用定時器PWM

一、通用定時器簡介

STM32通用定時器由一個通過可編程預分頻器驅動的16位自動重裝載計數器組成,適用于多種應用場景,包括測量輸入信號的脈沖長度(利用輸入捕獲功能)和生成輸出波形(使用輸出比較及PWM功能)。借助于定時器預分頻器以及RCC時鐘控制器提供的預分頻能力,用戶可以靈活調整脈沖長度和波形周期,范圍可從幾微秒至幾毫秒不等。每個通用定時器都是完全獨立的,不共享任何資源,這保證了它們可以在互不影響的情況下單獨運行,同時也支持同步操作,以滿足復雜的實時控制需求。

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

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

二、通用定時器內部結構

通用定時器的內部結構相較于基本定時器而言復雜得多,主要由以下幾個關鍵部分組成:時基單元、時鐘發生器、輸入捕獲以及輸出比較等。

1. 時鐘源

通用定時器提供了四種不同的時鐘來源選項,具體選擇可通過配置TIMx_SMCR寄存器的相關位來實現:

(1)內部時鐘(CK_INT):這是最常見的時鐘源選擇,適用于大多數應用場景。

(2)外部時鐘模式1:使用外部輸入引腳TIx(x=1,2,3,4)作為時鐘源,允許定時器根據外部信號進行計數。

(3)外部時鐘模式2:通過外部觸發輸入ETR提供時鐘信號,進一步擴展了定時器的應用范圍。

(4)內部觸發輸入(ITRx,x=0,1,2,3):利用其他定時器或系統內部產生的觸發信號作為時鐘源。

在典型配置中,我們通常選擇內部時鐘(CK_INT)作為通用定時器的時鐘來源,并且由于APB1的時鐘分頻系數不為1,通用定時器的時鐘頻率是APB1時鐘的兩倍,即72MHz。

2. 控制器

通用定時器的控制器部分集成了觸發控制器、從模式控制器以及編碼器接口,以支持廣泛的應用需求。

觸發控制器負責生成觸發信號,可用于驅動片內外設的操作,如為其他定時器提供時鐘或觸發DAC和ADC轉換,從而增強系統內不同模塊間的同步與協調能力。

從模式控制器則管理計數器的各種操作狀態,包括復位、啟動、遞增或遞減計數,使得定時器能夠適應復雜的計數模式和同步操作要求,滿足多樣化的實時控制需求。此外,專門設計的編碼器接口用于處理來自旋轉編碼器的輸入信號,通過準確解碼位置信息調整計數器值,適用于需要精確位置反饋的應用場景。

3. 時基單元

通用定時器的時基單元由三個核心寄存器組成:計數器寄存器(TIMx_CNT)、預分頻器寄存器(TIMx_PSC)和自動重裝載寄存器(TIMx_ARR)。在高級定時器中,還額外包含一個重復計數寄存器(TIMx_RCR),這一特性在通用和基本定時器中并不存在。

在時基單元內,預分頻器寄存器(TIMx_PSC)用于對計數器時鐘頻率進行分頻調整。通過設置寄存器內的相應位,可以將分頻系數設定在1到65536之間,從而靈活控制計數器的工作頻率。由于從模式控制寄存器具備緩沖功能,預分頻器支持實時更改,新的分頻比將在下一個更新事件發生時生效。

此外,時基單元中的計數器寄存器(TIMx_CNT)支持多種計數方式:

(1)向上計數

在向上(遞增)計數模式下,計數器從0開始計數,每當接收到一個CK_CNT脈沖時,計數器的值增加1,直至達到自動重載寄存器(TIMx_ARR)中設定的值。此時,計數器會觸發一次上溢事件,并重新從0開始計數。

(2)向下計數

在向下(遞減)計數模式下,計數器從自動重載寄存器(TIMx_ARR)中設定的值開始遞減計數,每接收到一個CK_CNT脈沖時,計數器的值減少1,直至計數至0。此時,計數器觸發一次下溢事件,并重新從自動重載值開始新一輪計數。

(3)中央對齊計數

在中心對齊模式下,計數器的操作分為兩個階段:首先從0開始遞增計數至自動重載寄存器(TIMx_ARR)中設定的值減1,此時生成計數器上溢事件;然后從自動重載值開始遞減計數至1,并生成計數器下溢事件。

在時基單元中還有一個自動重載寄存器(TIMx_ARR),它用于存儲與計數器(TIMx_CNT)進行比較的目標值。

4. 輸入捕獲單元

輸入捕獲單元主要由以下幾部分組成:輸入通道、輸入濾波器和邊沿檢測器、輸入捕獲通道、預分頻器以及捕獲/比較寄存器。

在輸入捕獲模式下,當ICx輸入信號檢測到設定的跳變沿時,計數器的當前值會被鎖存到捕獲/比較寄存器(TIMx_CCRx)。每次捕獲事件發生時,相應的捕獲標志位CCxIF(位于TIMx_SR寄存器中)被置1,并可觸發中斷或DMA請求。

ICx輸入信號經過預分頻器處理,根據TIMx_CCMRx寄存器中的ICxPSC位設置預分頻系數,決定每多少個事件進行一次捕獲。若需捕獲每個邊沿,則預分頻系數應設為1。首次捕獲時,計數器CNT的值被鎖存到CCR寄存器并產生中斷,CCxIF標志被置位;若CCR已有值且CCxIF已置1,則發生第二次捕獲時,捕獲溢出標志位CCxOF會被置位,該標志只能通過軟件寫0清零。

5. 輸出比較通道

通用定時器通常配備有多個輸出通道(TIMx_CH1/2/3/4),這些通道對應于STM32微控制器上的物理引腳。每個輸出通道可以獨立配置為不同的功能,如輸出比較、PWM生成等。

輸出比較單元與輸入捕獲單元共享捕獲/比較寄存器(TIMx_CCRx)。然而,在輸出比較模式下,這些寄存器主要發揮其比較功能的作用。當計數器CNT的值與比較寄存器CCR的值相等時,輸出參考信號OCxREF的極性會發生改變,并且會產生一個比較中斷CCxI。此時,相應的標志位CCxIF(位于SR寄存器中)會被置位。

在發生比較匹配事件后,OCxREF信號經過一系列控制處理,最終轉換為實際的輸出信號OC1/2/3/4。這些輸出信號會通過對應的管腳TIMx_CH1/2/3/4輸出到外部設備。

三、PWM簡介

什么是PWM?

PWM是 Pulse Width Modulation 的縮寫,中文意思就是脈沖寬度調制,簡稱脈寬度調制,其核心思想是通過快速開關數字信號并改變其開啟時間(脈寬)的比例來控制輸送到負載的平均功率或電壓,即控制占空比。

它是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,其控制簡單、靈活和動態響應好等優點而成為電力電子技術最廣泛應用的控制方式,其應用領域包括測量,通信,功率控制與變換,電動機控制、伺服控制、調光、開關電源,甚至某些音頻放大器,因此學習PWM具有十分重要的現實意義。

  • PWM 信號是一個周期性的方波(高電平-低電平交替)。
  • 占空比 是一個周期內高電平(脈沖開啟)時間占整個周期時間的百分比。
  • 公式:占空比 = (脈沖開啟時間 / 周期時間) × 100%
  • 例如:一個周期為 10ms 的 PWM 信號,如果高電平持續 3ms,則占空比為 30%;如果高電平持續 7ms,則占空比為 70%。

與模擬控制的區別

  • 傳統的模擬控制(如使用可變電阻)是通過連續地改變電壓或電流的大小來控制負載。
  • PWM 控制是通過改變數字脈沖的寬度比例來達到類似的連續控制效果。它是數字式的開關控制,而非連續的模擬調節。
  • PWM 控制本質上改變的是負載兩端的 平均電壓?和流經負載的 平均電流,而不是瞬時電壓或電流的峰值

通用定時器的PWM模式

PWM(脈沖寬度調制)模式是輸出比較模式的一種特例,專門用于生成具有特定頻率和占空比的PWM波形。它可以配置為PWM1模式或PWM2模式,適用于電機控制、LED亮度調節等多種應用。

PWM1模式:當計數器CNT的值小于比較寄存器CCR的值時,輸出高電平;反之,輸出低電平。這使得輸出信號的占空比由CCR值決定。

PWM2模式:與PWM1模式相反,當計數器CNT的值小于比較寄存器CCR的值時,輸出低電平;反之,輸出高電平。

通過調整計數器的自動重裝載值(TIMx_ARR)和比較寄存器(TIMx_CCRx)的值,可以精確控制PWM信號的周期和占空比。

四、代碼實現定時器輸出PWM脈沖

本實驗使用通用定時器TIM3的通道1來輸出PWM脈沖,TIM3的輸出通道1是映射在GPIO引腳PA6上,并在PA6引腳接一個LED燈。我們通過控制PWM占空比,實現呼吸燈的效果。(燈的亮度由亮到暗,再由暗到亮)

1.配置步驟

  • 使能外設TIM3、GPIOA時鐘
  • 初始GPIO
  • 初始化定時器,配置定時器的時基單元和輸出通道部分
  • 使能定時器
  • 使能輸出比較預裝載寄存器
  • 使能自動重裝載預裝載寄存器
  • 設置比較寄存器的值

2.代碼實現

編寫tim_drv.c文件

#include "tim_drv.h"/*********************************************************************************** @brief :  定時器PWM輸出配置函數*                * @param :  arr 自動重裝載值* @param :  psc 預分頻系數* @retval  : 無
**********************************************************************************/
void PWM_Config(uint16_t arr, uint16_t psc)
{//開啟外設GPIO時鐘 復用時鐘AFIO  定時器TIM3時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//GPIO初始化GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;      //引腳6GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//復用推挽輸出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//速率GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化定時器TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  //時鐘分割TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上計數模式TIM_TimeBaseInitStruct.TIM_Period = arr;         //自動重裝載值TIM_TimeBaseInitStruct.TIM_Prescaler = psc;      //預分頻系數TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//輸出比較通道參數初始化TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //PWM1模式TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; //有效電平為低電平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;  //輸出使能TIM_OCInitStruct.TIM_Pulse = 0; //初始占空比為0(整個計數周期PWM波形為高電平)TIM_OC1Init(TIM3,&TIM_OCInitStruct);//使能輸出比較預裝載寄存器TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能自動重裝載預裝載寄存器TIM_ARRPreloadConfig(TIM3,ENABLE);//使能定時器TIM_Cmd(TIM3,ENABLE);
}

編寫tim_drv.h文件

#ifndef __TIM_DRV_H__
#define __TIM_DRV_H__//頭文件包含
#include "stm32f10x.h"//函數聲明
void PWM_Config(uint16_t arr, uint16_t psc);#endif

編寫main.c文件

#include "led_drv.h"
#include "systick.h"
#include "tim_drv.h"int main(void)
{uint8_t dir=0;uint16_t ccr = 0;SysTick_Init(72);//初始化systickPWM_Config(100-1,720-1);//初始化LEDwhile (1){if(!dir){ccr++;if(ccr >= 500)dir = 1;}else{ccr--;if(ccr <= 0)dir =0;}TIM_SetCompare1(TIM3,ccr);delay_ms(5);}
}

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

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

相關文章

第十八節 MATLAB for循環

MATLAB中 for 循環是一個重復的控制結構&#xff0c;可以有效地寫一個循環&#xff0c;只是執行的次數是特定的。MATLAB for 循環語法:MATLAB中的 for循環的語法如下&#xff1a;for index values<program statements>... endfor 循環的值有下述三種形式之一&#xff1a…

嵌入式硬件篇---zigbee無線串口通信問題解決方法

針對 ZigBee 無線串口通信中接收異常的問題&#xff0c;需結合其射頻特性、網絡機制、硬件配置等多維度原因&#xff0c;采取針對性解決措施。以下從具體場景出發&#xff0c;提供可落地的解決方法&#xff1a;一、解決射頻層干擾與信號衰減問題射頻層是無線通信的基礎&#xf…

移動高清盒子6PRO-河南創維E900V22D-晶晨S905L3B-4+16G-安卓9-線刷固件包

移動高清盒子6PRO-河南創維E900V22D-晶晨S905L3B-416G-安卓9-線刷固件包線刷方法&#xff1a;1、準備好一根雙公頭USB線刷刷機線&#xff0c;長度30-50CM長度最佳&#xff0c;同時準備一臺電腦&#xff1b;2、電腦上安裝好刷機工具Amlogic USB Burning Tool 軟件 →打開軟件 →…

臺式電腦有多個風扇開機只有部分轉動的原因

一、風扇未連接或連接松動這是最常見的原因之一&#xff0c;臺式機風扇通常需要通過線材與主板或電源連接&#xff1a;主板接口問題&#xff1a;CPU 風扇、機箱風扇等多連接到主板的風扇接口&#xff08;如 CPU_FAN、SYS_FAN&#xff09;&#xff0c;若線材未插緊、插錯接口&am…

【測試報告】思緒網(Java+Selenium+Jmeter自動化測試)

一、項目簡介思緒網作為一種在線交流平臺&#xff0c;支持用戶在平臺下發布文章&#xff0c;并進行討論。主要由登錄頁面&#xff0c;論壇頁面&#xff0c;帖子編輯頁&#xff0c;帖子詳情頁等頁面組成。二、項目功能1.登錄頁面&#xff1a;輸入正確的賬號密碼進行登錄,跳轉博客…

Nestjs框架: 基于Mongodb的多租戶功能集成和優化

概述 基于前文&#xff0c;我們知道如何集成多租戶的相關功能了, 現在我們繼續集成Monodb的多租戶形式需要注意的是&#xff0c;MongoDB 在 NestJS 中的使用過程中存在一些“坑點”如果按照默認方式集成&#xff0c;會發現連接數在不斷增長&#xff0c;即使我們請求的是相同的數…

如何利用機器學習分析篩選生物標記物

在生物信息學中&#xff0c;Lasso回歸、隨機森林&#xff08;Random Forest&#xff09;和XGBoost因其各自的特性和優勢&#xff0c;被廣泛應用于基因組學、蛋白質組學、藥物發現和疾病機制研究等領域。 Lasso回歸 癌癥亞型分類&#xff1a;從TCGA數據中篩選驅動基因&#xf…

計算機網絡(基礎篇)

TCP/IP 網絡模型 應用層&#xff08;Application Layer&#xff09; 應用層只需要專注于為用戶提供應用功能&#xff0c;比如 HTTP、FTP、Telnet、DNS、SMTP等。應用層是工作在操作系統中的用戶態&#xff0c;傳輸層及以下則工作在內核態。傳輸層&#xff08;Transport Layer&a…

全面解析 CSS Flex 布局:從入門到精通的所有屬性詳解

1. Flex 容器屬性 通過 display: flex 或 display: inline-flex 將元素設置為 Flex 容器。以下是所有容器屬性。 1.1 display: flex | inline-flex 作用&#xff1a;定義一個 Flex 容器。可選值&#xff1a; flex&#xff1a;塊級容器&#xff0c;占據整行。inline-flex&#x…

數據結構:對角矩陣(Diagonal Matrix)

目錄 矩陣的傳統表示&#xff1a;二維數組 &#x1f50d; 真正有用的數據是哪些&#xff1f; 從二維數組轉為一維數組 用 C 類實現對角矩陣 1. 對角矩陣真正需要存什么&#xff1f; 2. 對角矩陣允許哪些行為&#xff1f; 3. 為什么要動態分配數組&#xff1f; 接下來推…

Leetcode_349.兩個數組的交集

這道題的意思很明確&#xff0c;就是讓尋找兩個數組中的共同元素&#xff0c;并去重&#xff0c;由此可以聯想到哈希表的特性&#xff0c;注意到題目給的數據范圍&#xff0c;在1000以內&#xff0c;所以本題可以使用 STL 的庫函數&#xff0c;也可以使用數組進行模擬。 本題要…

STM32——寄存器映射

總 &#xff1a;STM32——HAL庫總結-CSDN博客 芯片資料&#xff1a; STM32F1系列參考手冊-V10&#xff08;中&#xff09; STM32F103ZET6(English) 一、寄存器基礎 1.1 簡介 單片機內部的控制機構。 像空氣開關控制電路一樣的原理&#xff0c;打開關閉某個開關&#xff0…

Java響應式編程

Java 響應式編程是一種基于異步數據流處理的編程范式&#xff0c;它強調數據流的聲明式構建和傳播變化的自動響應。Java 9 引入的Flow API為響應式編程提供了標準接口&#xff0c;而 Reactor 和 RxJava 等第三方庫則提供了更豐富的操作符和工具。核心概念Publisher&#xff08;…

【重學數據結構】二叉搜索樹 Binary Search Tree

目錄 二叉搜索樹的數據結構 手寫實現二叉搜索樹 樹節點定義 插入節點 源碼 流程圖 二叉樹插入步驟圖解 第一步: 插入 20 第二步: 插入 10 第三步: 插入 30 第四步: 插入 5 查找節點 源碼 場景一: 查找成功 (search for 25) 第一步: 從根節點開始 第二步:…

四、計算機組成原理——第1章:計算機系統概述

目錄 1.1計算機發展歷程 1.1.1計算機硬件的發展 1.計算機的四代變化 2.計算機元件的更新換代 1.1.2計算機軟件的發展 1.2計算機系統層次結構 1.2.1計算機系統的組成 1.2.2計算機硬件 1.馮諾依曼機基本思想 2.計算機的功能部件 (1)輸入設備 (2)輸出設備 (3)存儲器 (4)運算器 (5)…

flutter TextField 失去焦點事件

在 Flutter 中&#xff0c;處理 TextField 的失去焦點事件&#xff08;即失去焦點時觸發的操作&#xff09;通常有兩種常用方式&#xff1a;使用 FocusNode 或 onEditingComplete 回調。以下是具體實現&#xff1a; import package:flutter/material.dart;class MyTextField e…

Moonlight for ChromeOS 常見問題解決方案

Moonlight for ChromeOS 常見問題解決方案 項目基礎介紹 Moonlight for ChromeOS 是一個開源的 NVIDIA GameStream 客戶端&#xff0c;允許用戶將他們的游戲從高性能的桌面電腦流式傳輸到運行 ChromeOS 的設備上。該項目還支持 Android 和 iOS/tvOS 平臺。Moonlight for Chrome…

SQL語句:讀操作、寫操作、視圖

文章目錄讀操作分類基礎查詢語句示例高級查詢--分組查詢、子查詢、表連接、聯合查詢分組查詢&#xff1a;子查詢&#xff08;嵌套查詢&#xff09;表連接聯合查詢寫操作視圖SQL&#xff1a;結構化查詢語言讀操作 重點是where查詢&#xff0c;即高級查詢部分 分類 DML &#…

Python 機器學習實戰:基于 Scikit-learn

本文圍繞《Python 機器學習實戰&#xff1a;基于 Scikit-learn 的項目開發》展開&#xff0c;先介紹 Scikit-learn 庫的基礎特性與優勢&#xff0c;再闡述機器學習項目開發的完整流程&#xff0c;包括數據收集與預處理、模型選擇與訓練、評估與優化等。通過具體實戰案例&#x…

java里List鏈式編程

java里對list的操作&#xff0c;我們一遍使用for遍歷&#xff0c;輸出或改變里面的內容。單經常在代碼里面我們發現&#xff0c;也可以使用這樣的代碼結構daPaymentActionVo.setApnolist(paymentActionVo.getApnolist().stream().map(PaymentActionVo.Voucher::getApno).collec…