《嵌入式-STM32開發(fā)指南》第二部分 基礎(chǔ)篇 - 第4章 定時(shí)器(HAL庫)

標(biāo)準(zhǔn)庫3.5實(shí)現(xiàn):
《嵌入式-STM32開發(fā)指南》第二部分 基礎(chǔ)篇 - 第4章 定時(shí)器

4.1定時(shí)器的工作原理

STM32有三類定時(shí)器角虫,基本定時(shí)器就是單純的定時(shí)計(jì)數(shù)器,通用定時(shí)器多了四個(gè)通道委造,相對應(yīng)的增加了功能戳鹅,高級定時(shí)器具有基本,通用定時(shí)器的所有的功能昏兆,并且添加了其他功能枫虏。定時(shí)器的對比特性如下表所示。

表1各個(gè)定時(shí)器特征

4.1.1基本定時(shí)器

TIM6和TIM7定時(shí)器的主要功能包括:

● 16位自動(dòng)重裝載累加計(jì)數(shù)器
● 16位可編程(可實(shí)時(shí)修改)預(yù)分頻器爬虱,用于對輸入的時(shí)鐘按系數(shù)為1~65536之間的任意數(shù)值分頻
● 觸發(fā)DAC的同步電路
● 在更新事件(計(jì)數(shù)器溢出)時(shí)產(chǎn)生中斷/DMA請求

總的說來隶债,基本定時(shí)器 TIM6 和 TIM7 只具備最基本的定時(shí)功能,就是累加的時(shí)鐘脈沖數(shù)超過預(yù)定值時(shí)跑筝,能觸發(fā)中斷或觸發(fā) DMA 請求死讹。由于在芯片內(nèi)部與 DAC 外設(shè)相連,可通過觸發(fā)輸出驅(qū)動(dòng) DAC曲梗,也可以作為其他通用定時(shí)器的時(shí)鐘基準(zhǔn)赞警。

這兩個(gè)基本定時(shí)器使用的時(shí)鐘源都是 TIMxCLK妓忍,時(shí)鐘源經(jīng)過 PSC 預(yù)分頻器輸入至脈沖計(jì)數(shù)器 TIMx_CNT,基本定時(shí)器只能工作在向上計(jì)數(shù)模式愧旦,在重載寄存器 TIMx_ARR 中保存的是定時(shí)器的溢出值世剖。

工作時(shí),脈沖計(jì)數(shù)器 TIMx_CNT 由時(shí)鐘觸發(fā)進(jìn)行計(jì)數(shù)笤虫,當(dāng) TIMx_CNT 的計(jì)數(shù)值 X 等于重載寄存器 TIMx_ARR 中保存的數(shù)值 N 時(shí)旁瘫,產(chǎn)生溢出事件,可觸發(fā)中斷或 DMA 請求琼蚯。然后 TIMx_CNT 的值重新被置為 0酬凳,重新向上計(jì)數(shù)。

圖1基本定時(shí)器框圖

4.1.2通用定時(shí)器

通用TIMx (TIM2凌停、 TIM3粱年、 TIM4和TIM5)定時(shí)器功能包括:

● 16位向上、向下罚拟、向上/向下自動(dòng)裝載計(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ù)器啟動(dòng)、停止瓜富、初始化或者由內(nèi)部/外部觸發(fā)計(jì)數(shù))鳍咱,輸入捕獲,輸出比較与柑;
● 支持針對定位的增量(正交)編碼器和霍爾傳感器電路
● 觸發(fā)輸入作為外部時(shí)鐘或者按周期的電流管理

相比之下谤辜,通用定時(shí)器 TIM2 ~ TIM5 就比基本定時(shí)器復(fù)雜得多了。除了基本的定時(shí)价捧,它主要用在測量輸入脈沖的頻率丑念、脈沖寬與輸出 PWM 脈沖的場合,還具有編碼器的接口结蟋。

圖2通用定時(shí)器框圖

1.捕獲 / 比較寄存器
通用定時(shí)器的基本計(jì)時(shí)功能與基本定時(shí)器的工作方式是一樣的脯倚,同樣把時(shí)鐘源經(jīng)過預(yù)分頻器輸出到脈沖計(jì)數(shù)器 TIMx_CNT 累加,溢出時(shí)就產(chǎn)生中斷或 DMA 請求椎眯。而通用定時(shí)器比基本定時(shí)器多出的強(qiáng)大功能挠将,就是因?yàn)橥ㄓ枚〞r(shí)器多出了一種寄存器——捕獲 / 比較寄存器 TIMx_CCR(capture/compare register)胳岂,它在輸入時(shí)被用于捕獲(存儲) 輸入脈沖在電平發(fā)生翻轉(zhuǎn)時(shí)脈沖計(jì)數(shù)器 TIMx_CNT 的當(dāng)前計(jì)數(shù)值编整,從而實(shí)現(xiàn)脈沖的頻率測量 舔稀;在輸出時(shí)被用來存儲一個(gè)脈沖數(shù)值,把這個(gè)數(shù)值用于與脈沖計(jì)數(shù)器TIMx_CNT 的當(dāng)前計(jì)數(shù)值進(jìn)行比較掌测,根據(jù)比較結(jié)果進(jìn)行不同的電平輸出内贮。

2. PWM 輸出過程分析
通用定時(shí)器可以利用 GPIO 引腳進(jìn)行脈沖輸出,在配置為比較輸出汞斧、PWM 輸出功能時(shí)夜郁,捕獲 /比較寄存器 TIMx_CCR 被用作比較功能,下面把它簡稱為比較寄存器粘勒。這里直接舉例說明定時(shí)器的 PWM 輸出工作過程 :若配置脈沖計(jì)數(shù)器 TIMx_CNT 為向上計(jì)數(shù)竞端,而重載寄存器 TIMx_ARR 被配置為 N,即 TIMx_CNT 的當(dāng)前計(jì)數(shù)值數(shù)值 X 在TIMxCLK 時(shí)鐘源的驅(qū)動(dòng)下不斷累加庙睡,當(dāng) TIMx_CNT 的數(shù)值 X 大于 N 時(shí)事富,會重置TIMx_CNT 數(shù)值為 0 并重新計(jì)數(shù)。

而在 TIMx_CNT 計(jì)數(shù)的同時(shí)乘陪,TIMx_CNT 的計(jì)數(shù)值 X 會與比較寄存器 TIMx_CCR 預(yù)先存儲的數(shù)值 A 進(jìn)行比較统台。當(dāng)脈沖計(jì)數(shù)器 TIMx_CNT 的數(shù)值 X 小于比較寄存器TIMx_CCR 的值 A 時(shí),輸出高電平(或低電平)啡邑;相反地贱勃,當(dāng)脈沖計(jì)數(shù)器的數(shù)值 X 大于或等于比較寄存器的值 A 時(shí),輸出低電平(或高電平)谤逼。如此循環(huán)贵扰,得到的輸出脈沖周期就為重載寄存器 TIMx_ARR 存儲的數(shù)值(N+1)乘以觸發(fā)脈沖的時(shí)鐘周期,其脈沖寬度則為比較寄存器 TIMx_CCR 的值 A 乘以觸發(fā)脈沖的時(shí)鐘周期流部,即輸出 PWM 的占空比為 A/(N+1) 戚绕。見圖3 PWM 輸出模式,圖中為重載寄存器 TIMx_ARR 被配置為 N=8贵涵,向上計(jì)數(shù) 列肢;比較寄存器 TIMx_CCR 的值被設(shè)置為 4、8宾茂、大于 8瓷马、等于 0 時(shí)的輸出時(shí)序圖。圖中OCxREF 即為 GPIO 引腳的輸出時(shí)序跨晴、CCxIF 為觸發(fā)中斷的時(shí)序欧聘。

圖3 PWM 輸出模式

3.PWM 輸入過程分析
而當(dāng)定時(shí)器被配置為輸入功能時(shí),可以用于檢測輸入到 GPIO 引腳的信號(頻率檢測端盆、輸入 PWM 檢測)怀骤,此時(shí)捕獲 / 比較寄存器 TIMx_CCR 被用作捕獲功能费封,下面把它簡稱為捕獲寄存器。見圖4蒋伦,為 PWM 輸入時(shí)的脈沖寬檢測時(shí)序圖弓摘。

圖4 PWM 輸入檢測

按照圖 4 所示時(shí)序圖來分析 PWM 輸入脈沖寬檢測的工作過程 :要測量的 PWM 脈沖通過 GPIO 引腳輸入到定時(shí)器的脈沖檢測通道,其時(shí)序?yàn)閳D中的 TI1痕届。把脈沖計(jì)數(shù)器TIMx_CNT 配置為向上計(jì)數(shù)韧献,重載寄存器 TIMx_ARR 的 N 值配置為足夠大。

在輸入脈沖 TI1 的上升沿到達(dá)時(shí)研叫,觸發(fā) IC1 和 IC2 輸入捕獲中斷锤窑,這時(shí)把脈沖計(jì)數(shù)器TIMx_CNT 的計(jì)數(shù)值復(fù)位為 0,于是 TIMx_CNT 的計(jì)數(shù)值 X 在 TIMxCLK 的驅(qū)動(dòng)下從 0 開始不斷累加嚷炉,直到 TI1 出現(xiàn)下降沿渊啰,觸發(fā) IC2 捕獲事件,此時(shí)捕獲寄存器 TIMx_CCR2 把脈沖計(jì)數(shù)器 TIMx_CNT 的當(dāng)前值 2 存儲起來申屹,而 TIMx_CNT 繼續(xù)累加绘证,直到 TI1 出現(xiàn)第二 個(gè) 上 升 沿 , 觸 發(fā) 了 IC1 捕 獲 事 件 独柑, 此 時(shí) TIMx_CNT 的 當(dāng) 前 計(jì) 數(shù) 值 4 被 保 存 到TIMx_CCR1迈窟。

很明顯 TIMx_CCR1(加 1)的值乘以 TIMxCLK 的周期,即為待檢測的 PWM 輸入脈沖周期忌栅,TIMx_CCR2(加 1)的值乘以 TIMxCLK 的周期车酣,就是待檢測的 PWM 輸入脈沖的高電平時(shí)間,有了這兩個(gè)數(shù)值就可以計(jì)算出 PWM 脈沖的頻率索绪、占空比了湖员⌒蹬模可以看出拇颅,正因?yàn)椴东@ / 比較寄存器的存在,才使得通用定時(shí)器變得如此強(qiáng)大拴驮。

4.定時(shí)器的時(shí)鐘源
從時(shí)鐘源方面來說唤反,通用定時(shí)器比基本定時(shí)器多了一個(gè)選擇凳寺,它可以使用外部脈沖作為定時(shí)器的時(shí)鐘源。使用外部時(shí)鐘源時(shí)彤侍,要使用寄存器進(jìn)行觸發(fā)邊沿肠缨、濾波器帶寬的配置。如果選擇內(nèi)部時(shí)鐘源的話則與基本定時(shí)器一樣盏阶,也為 TIMxCLK晒奕。但要注意的是,所有定時(shí)器(包括基本、通用和高級)使用內(nèi)部時(shí)鐘時(shí)脑慧,定時(shí)器的時(shí)鐘源都被稱為TIMxCLK魄眉,但 TIMxCLK 的時(shí)鐘來源并不是完全一樣的,見圖5闷袒。

圖5時(shí)鐘樹(TIMxCLK 部分)

TIM2 ~ 7 也 就 是 基 本 定 時(shí) 器 和 通 用定時(shí)器坑律,TIMxCLK 的時(shí)鐘來源是 APB1 預(yù)分頻器的輸出。當(dāng) APB1 的分頻系數(shù)為 1 時(shí)霜运,則 TIM2 ~ 7 的 TIMxCLK 直接等于該APB1 預(yù)分頻器的輸出脾歇,而 APB1 的分頻系數(shù) 不 為 1 時(shí)蒋腮,TIM2 ~ 7 的 TIMxCLK 則 為APB1 預(yù)分頻器輸出的 2 倍淘捡。
如在常見的配置中,AHB=72 MHz池摧,而 APB1 預(yù)分頻器的分頻系數(shù)被配置為 2焦除,則PCLK1 剛好達(dá)到最大值 36 MHz,而此時(shí) APB1 的分頻系數(shù)不為 1作彤,則 TIM2 ~ TIM7的時(shí)鐘 TIMxCLK = (AHB/2)×2 = 72 MHz膘魄。

而對于 TIM1 和 TIM8 這兩個(gè)高級定時(shí)器,TIMxCLK 的時(shí)鐘來源則是 APB2 預(yù)分頻器的輸出竭讳,同樣它也根據(jù)分頻系數(shù)分為兩種情況创葡。

常見的配置中 AHB=72 MHz,APB2 預(yù)分頻器的分頻系數(shù)被配置為1绢慢, 此時(shí)PCLK2剛好達(dá)到最大值72 MHz灿渴,而 TIMxCLK 則直接等于APB2分頻器的輸出,即TIM1和 TIM8 的時(shí)鐘 TIMxCLK=AHB=72 MHz胰舆。

雖然這種配置下最終 TIMxCLK 的時(shí)鐘頻率相等骚露,但必須清楚實(shí)質(zhì)上它們的時(shí)鐘來源是有區(qū)別的。還要強(qiáng)調(diào)的是 :TIMxCLK 是定時(shí)器內(nèi)部的時(shí)鐘源缚窿,但在時(shí)鐘輸出到脈沖計(jì)數(shù)器 TIMx_CNT 前棘幸,還經(jīng)過一個(gè)預(yù)分頻器 PSC,最終用于驅(qū)動(dòng)脈沖計(jì)數(shù)器 TIMx_CNT 的時(shí)鐘頻率根據(jù)預(yù)分頻器 PSC 的配置而定倦零。

4.1.3高級定時(shí)器

TIM1和TIM8定時(shí)器的功能包括:

● 16位向上误续、向下、向上/下自動(dòng)裝載計(jì)數(shù)器
● 16位可編程(可以實(shí)時(shí)修改)預(yù)分頻器扫茅,計(jì)數(shù)器時(shí)鐘頻率的分頻系數(shù)為1~65535之間的任意數(shù)值
● 多達(dá)4個(gè)獨(dú)立通道:輸入捕獲蹋嵌,輸出比較,PWM生成(邊緣或中間對齊模式)诞帐,單脈沖模式輸出欣尼;
● 死區(qū)時(shí)間可編程的互補(bǔ)輸出;
● 使用外部信號控制定時(shí)器和定時(shí)器互聯(lián)的同步電路;
● 允許在指定數(shù)目的計(jì)數(shù)器周期之后更新定時(shí)器寄存器的重復(fù)計(jì)數(shù)器愕鼓;
● 剎車輸入信號可以將定時(shí)器輸出信號置于復(fù)位狀態(tài)或者一個(gè)已知狀態(tài)钙态;
● 如下事件發(fā)生時(shí)產(chǎn)生中斷/DMA:更新:計(jì)數(shù)器向上溢出/向下溢出,計(jì)數(shù)器初始化(通過軟件或者內(nèi)部/外部觸發(fā))菇晃,觸發(fā)事件(計(jì)數(shù)器啟動(dòng)册倒、停止、初始化或者由內(nèi)部/外部觸發(fā)計(jì)數(shù))磺送,輸入捕獲驻子,輸出比較,剎車信號輸入估灿;
● 支持針對定位的增量(正交)編碼器和霍爾傳感器電路崇呵;
● 觸發(fā)輸入作為外部時(shí)鐘或者按周期的電流管理。

圖6高級控制定時(shí)器框圖

總的來說馅袁,TIM1 和 TIM8 是兩個(gè)高級定時(shí)器域慷,它們具有基本、通用定時(shí)器的所有功能汗销,還具有三相 6 步電機(jī)的接口犹褒、剎車功能(break function)及用于 PWM 驅(qū)動(dòng)電路的死區(qū)時(shí)間控制等,使得它非常適合于電機(jī)的控制弛针。如圖6 所示為高級定時(shí)器結(jié)構(gòu)叠骑。

相比于通用定時(shí)器,主要多出了 BRK削茁、DTG 兩個(gè)結(jié)構(gòu)宙枷,因而具有了死區(qū)時(shí)間的控制功能。首先付材,死區(qū)時(shí)間是什么呢朦拖?在 H 橋、三相橋的 PWM 驅(qū)動(dòng)電路中厌衔,上下兩個(gè)橋臂的PWM 驅(qū)動(dòng)信號是互補(bǔ)的璧帝,即上下橋臂輪流導(dǎo)通,但實(shí)際上為了防止出現(xiàn)上下兩個(gè)臂同時(shí)導(dǎo)通(會造成短路)富寿,在上下兩臂切換時(shí)留一小段時(shí)間睬隶,上下臂都施加關(guān)斷信號,這個(gè)上下臂都關(guān)斷的時(shí)間稱為死區(qū)時(shí)間页徐。

STM32 的高級定時(shí)器可以配置出輸出互補(bǔ)的 PWM 信號苏潜,并且在這個(gè) PWM 信號中加入死區(qū)時(shí)間,為電機(jī)的控制提供了極大的便利变勇。見圖7恤左。圖中的 OCxREF 為參考信號(可理解為原信號)贴唇, OCx 和 OCxN 為定時(shí)器通過 GPIO 引腳輸出的 PWM 互補(bǔ)信號。

圖7插入死區(qū)時(shí)間

若不加入死區(qū)時(shí)間飞袋,當(dāng) OCxREF 出現(xiàn)下降沿戳气,OCx 同時(shí)輸出下降沿,OCxN 則同時(shí)輸出相反的上升沿巧鸭,即這三個(gè)信號的跳變是同時(shí)的瓶您。

加入死區(qū)時(shí)間后,當(dāng) OCxREF 出現(xiàn)下降沿纲仍,OCx 同時(shí)輸出下降沿呀袱,但 OCxN 則過了一小段延遲再輸出上升沿,OCxREF 出現(xiàn)上升沿后郑叠,OCx 要經(jīng)過一段延時(shí)再輸出上升沿夜赵。假如 OCx、 OCxN 分別控制上锻拘、下橋臂油吭,有了延遲后,就不容易出現(xiàn)上署拟、下橋臂同時(shí)導(dǎo)通的情況。這個(gè)延遲時(shí)間與 PWM 信號驅(qū)動(dòng)的電子器件特性相關(guān)歌豺,從事工控領(lǐng)域的讀者對此應(yīng)該比較熟悉推穷。

在保證不出現(xiàn)短路的情況下,死區(qū)時(shí)間越短越好类咧。見圖8馒铃、9。

圖8 死區(qū)時(shí)間太長痕惋,OCxN 輸出不正常
圖9 死區(qū)時(shí)間太長区宇,OCx 輸出不正常

4.2定時(shí)器計(jì)數(shù)模式

定時(shí)器可以向上計(jì)數(shù)、向下計(jì)數(shù)值戳、向上向下雙向計(jì)數(shù)模式议谷。

  • 向上計(jì)數(shù)模式:計(jì)數(shù)器從0計(jì)數(shù)到自動(dòng)加載值(TIMx_ARR),然后重新從0開始計(jì)數(shù)并且產(chǎn)生一個(gè)計(jì)數(shù)器溢出事件堕虹。
  • 向下計(jì)數(shù)模式:計(jì)數(shù)器從自動(dòng)裝入的值(TIMx_ARR)開始向下計(jì)數(shù)到0卧晓,然后從自動(dòng)裝入的值重新開始,并產(chǎn)生一個(gè)計(jì)數(shù)器向下溢出事件赴捞。
  • 中央對齊模式(向上/向下計(jì)數(shù)):計(jì)數(shù)器從0開始計(jì)數(shù)到自動(dòng)裝入的值-1逼裆,產(chǎn)生一個(gè)計(jì)數(shù)器溢出事件,然后向下計(jì)數(shù)到1并且產(chǎn)生一個(gè)計(jì)數(shù)器溢出事件赦政;然后再從0開始重新計(jì)數(shù)胜宇。

簡單地理解三種計(jì)數(shù)模式,可以通過下面的圖形:

圖10定時(shí)器計(jì)數(shù)模式

計(jì)數(shù)器時(shí)鐘可由下列時(shí)鐘源提供:

內(nèi)部時(shí)鐘(TIMx_CLK)
外部時(shí)鐘模式1:外部捕捉比較引腳(TIx)
外部時(shí)鐘模式2:外部引腳輸入(TIMx_ETR) 僅適用TIM2,3,4
內(nèi)部觸發(fā)輸入(ITRx):使用一個(gè)定時(shí)器作為另一個(gè)定時(shí)器的預(yù)分頻器,如可以配置一個(gè)定時(shí)器Timer1而作為另一個(gè)定時(shí)器Timer2的預(yù)分頻器桐愉。

在前文對三類定時(shí)器做了講解封寞,下面列出定時(shí)器功能引腳分布。

表2定時(shí)器引腳分布

4.2 STM32Cube生成工程

我門在流水燈程序的基礎(chǔ)上進(jìn)行修改即可仅财,不必每次都新建工程狈究。本文介紹在STM32CubeMX進(jìn)行定時(shí)器的配置,產(chǎn)生固定時(shí)間中斷的方法盏求。這里以TIM2為例抖锥。
1.GPIO配置

圖11

2.設(shè)置RCC
設(shè)置高速外部時(shí)鐘HSE,選擇外部時(shí)鐘源碎罚。

圖12 RCC配置

3.時(shí)鐘配置
筆者的板子使用的外部晶振為8MHz磅废,選擇外部時(shí)鐘HSE 8MHz ,PLL鎖相環(huán)9倍頻后為72MHz荆烈,系統(tǒng)時(shí)鐘來源選擇為PLL拯勉,設(shè)置APB1分頻器為 /2,這時(shí)候定時(shí)器的時(shí)鐘頻率為72Mhz憔购。本文筆者使用的定時(shí)器是TIM2宫峦,TIM2掛在APB1上,不同的定時(shí)器掛在不同總線上的玫鸟。

圖 13時(shí)鐘配置

4.Times配置
選擇TIM导绷,使能TIM2,指定時(shí)鐘源屎飘。

圖14使能TIM2時(shí)鐘源

【注】TIM2的時(shí)鐘源有兩個(gè)選項(xiàng)
選項(xiàng)1 :Internal Clock 內(nèi)部時(shí)鐘
選項(xiàng)2 : ETR2 外部觸發(fā)輸入(ETR)(僅適用TIM2,3,4)

定時(shí)器參數(shù)配置如下:

圖15定時(shí)器參數(shù)配置

Prtscaler (定時(shí)器分頻系數(shù)) : 71
Counter Mode(計(jì)數(shù)模式) :Up(向上計(jì)數(shù)模式)
Counter Period(自動(dòng)重裝載值) : 999
CKD(時(shí)鐘分頻因子) : No Division 不分頻

選項(xiàng): 可以選擇二分頻和四分頻
auto-reload-preload(自動(dòng)重裝載) : Enable 使能
TRGO Parameters 觸發(fā)輸出 (TRGO) :不使能

TRGO:定時(shí)器的觸發(fā)信號輸出 在定時(shí)器的定時(shí)時(shí)間到達(dá)的時(shí)候輸出一個(gè)信號(如:定時(shí)器更新產(chǎn)生TRGO信號來觸發(fā)ADC的同步轉(zhuǎn)換妥曲,)

TIM2配置選項(xiàng)的前兩個(gè)為定時(shí)器主從模式配置,很少用到钦购,我們用不到檐盟,所以全部關(guān)閉。

圖16

使能定時(shí)器中斷:

圖17使能定時(shí)器中斷

定時(shí)器溢出時(shí)間:

Tout=1/(Tclk /psc) * arr

這里我們 arr=999 ,psc=71 ,Tclk=72Mhz 押桃,
Tout=1/(72MHZ /71) * 1000=1ms

好了葵萎,配置就完成了,生成工程就行了怨规。

4.3 定時(shí)器的具體代碼分析

我們先看看主函數(shù)陌宿,其代碼如下:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
/*使能定時(shí)2*/
  HAL_TIM_Base_Start_IT(&htim2);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
        if(timer_count == 1000)
        {
            timer_count = 0;
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
            HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
        }
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

在主循環(huán)前面,需要對TIM2進(jìn)行初始化配置:

HAL_TIM_Base_Start_IT(&htim2);

在主循環(huán)內(nèi)波丰,通過全局變量timer_count來計(jì)算延時(shí)時(shí)間壳坪,TIM2的中斷時(shí)間是1ms,我們計(jì)算1000表示1s掰烟,再讓LED反轉(zhuǎn)爽蝴。

在主函數(shù)后面還需添加以下函數(shù):

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    timer_count++;
}

4.3.1定時(shí)器外設(shè)結(jié)構(gòu)體

前文提到了初始化定時(shí)器TIM2沐批,這里介紹定時(shí)器的句柄。

typedef struct
{
  TIM_TypeDef                 *Instance;     /*!< Register base address             */
  TIM_Base_InitTypeDef        Init;          /*!< TIM Time Base required parameters */
  HAL_TIM_ActiveChannel       Channel;       /*!< Active channel                    */
  DMA_HandleTypeDef           *hdma[7];      /*!< DMA Handlers array
                                                  This array is accessed by a @ref DMA_Handle_index */
  HAL_LockTypeDef             Lock;          /*!< Locking object                    */
  __IO HAL_TIM_StateTypeDef   State;         /*!< TIM operation state               */
…/*還有其他未使用的函數(shù)*/
} TIM_HandleTypeDef;
  • Instance:TIM寄存器地址蝎亚。
  • Init:基本定時(shí)器的結(jié)伴參數(shù)九孩,后文會詳細(xì)介紹。
  • Channel:定時(shí)器的通道選擇发框。
  • hdma:定時(shí)器DMA相關(guān)的結(jié)構(gòu)體躺彬,在后面會有專門講DMA,先不管他梅惯。
  • Lock/ State:鎖定機(jī)制和定時(shí)器操作的狀態(tài)宪拥。

接下來說說配置定時(shí)器基本參數(shù)的結(jié)構(gòu)體。

typedef struct
{
  uint32_t Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */

  uint32_t CounterMode;       /*!< Specifies the counter mode.
                                   This parameter can be a value of @ref TIM_Counter_Mode */

  uint32_t Period;            /*!< Specifies the period value to be loaded into the active
                                   Auto-Reload Register at the next update event.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF.  */

  uint32_t ClockDivision;     /*!< Specifies the clock division.
                                   This parameter can be a value of @ref TIM_ClockDivision */

  uint32_t RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                    reaches zero, an update event is generated and counting restarts
                                    from the RCR value (N).
                                    This means in PWM mode that (N+1) corresponds to:
                                        - the number of PWM periods in edge-aligned mode
                                        - the number of half PWM period in center-aligned mode
                                     GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.
                                     Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */

  uint32_t AutoReloadPreload;  /*!< Specifies the auto-reload preload.
                                   This parameter can be a value of @ref TIM_AutoReloadPreload */
} TIM_Base_InitTypeDef;
  • Prescaler:定時(shí)器預(yù)分頻系數(shù)铣减,時(shí)鐘源進(jìn)過該分頻器到大定時(shí)器時(shí)鐘她君,可以設(shè)置的范圍為0~65535,我們設(shè)置的是71葫哗,這也是在STM32Cube設(shè)置的分頻系數(shù)缔刹,通過分頻后得到的時(shí)鐘是1MHz。
  • CounterMode:定時(shí)器計(jì)數(shù)方式劣针,選擇的是向上技術(shù)校镐,值得注意,基本定時(shí)器只能向上計(jì)數(shù)酿秸。
  • Period:定時(shí)器周期灭翔,本文設(shè)置的是999,可設(shè)置范圍是0~65535辣苏,因此產(chǎn)生中斷的頻率為:1MHz/1000=1KHz,即1ms的定時(shí)周期哄褒。
  • ClockDivision:時(shí)鐘分頻稀蟋,主要是設(shè)置定時(shí)器時(shí)鐘頻率與數(shù)字濾波器采樣時(shí)中頻率比,基本定時(shí)器沒有這個(gè)功能呐赡。
  • RepetitionCounter:重復(fù)計(jì)數(shù)器退客,屬于高級控制寄存器,利用它可控制PWM链嘀,后面的文章會具體講解萌狂。
  • AutoReloadPreload:自動(dòng)重裝裝載。這里使能就行怀泊。

4.3.2定時(shí)器編程流程分析

1.初始化GPIO

MX_GPIO_Init();

這個(gè)就不用多講了吧茫藏。

2.初始化定時(shí)器

MX_TIM2_Init();

函數(shù)原型如下:

static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 71;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

該函數(shù)主要初始化定時(shí)器參數(shù),比如分頻系數(shù)等霹琼,沒啥好講的务傲。

3.使能定時(shí)器

HAL_TIM_Base_Start_IT(&htim2);

4.使用定時(shí)器
前面講了定時(shí)器的初始化凉当,使能,那么定時(shí)是如何使用的呢售葡?它又是如何進(jìn)行中斷計(jì)時(shí)的呢看杭?其實(shí)和滴答定時(shí)器一樣,在stm32f1xx_it.c中定義了TIM2_IRQHandler中斷服務(wù)函數(shù)挟伙,中斷服務(wù)函數(shù)組中調(diào)用了我們自己寫的回調(diào)函數(shù)楼雹。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    timer_count++;
}

當(dāng)然,我們也可以將主函數(shù)的循環(huán)體中代碼放在上面的代碼中尖阔。值得注意的是贮缅,HAL庫提供了一個(gè)HAL_TIM_PeriodElapsedCallback函數(shù)。其原型如下:

__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file
   */
}

當(dāng)用戶沒有寫回調(diào)函數(shù)時(shí)诺祸,這個(gè)函數(shù)就會調(diào)用携悯,當(dāng)用戶寫了回調(diào)函數(shù),這個(gè)函數(shù)就不會調(diào)用筷笨,也可在這里加代碼憔鬼,但是不推薦,最好自己重新寫一個(gè)函數(shù)胃夏。

4.4 實(shí)現(xiàn)現(xiàn)象

將編譯好的程序下載到看板子中轴或,可以看到LED不停閃爍。


代碼獲取方式
1.關(guān)注公眾號[嵌入式實(shí)驗(yàn)樓]
2.在公眾號回復(fù)關(guān)鍵詞[STM32F1]獲取資料

歡迎訪問我的網(wǎng)站:
BruceOu的嗶哩嗶哩
BruceOu的主頁
BruceOu的博客
CSDN博客
簡書

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仰禀,一起剝皮案震驚了整個(gè)濱河市照雁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌答恶,老刑警劉巖饺蚊,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悬嗓,居然都是意外死亡污呼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門包竹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燕酷,“玉大人,你說我怎么就攤上這事周瞎∶缢酰” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵声诸,是天一觀的道長酱讶。 經(jīng)常有香客問我,道長双絮,這世上最難降的妖魔是什么浴麻? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任得问,我火速辦了婚禮,結(jié)果婚禮上软免,老公的妹妹穿的比我還像新娘宫纬。我一直安慰自己,他們只是感情好膏萧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布漓骚。 她就那樣靜靜地躺著,像睡著了一般榛泛。 火紅的嫁衣襯著肌膚如雪蝌蹂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天曹锨,我揣著相機(jī)與錄音孤个,去河邊找鬼。 笑死沛简,一個(gè)胖子當(dāng)著我的面吹牛齐鲤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播椒楣,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼给郊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捧灰?” 一聲冷哼從身側(cè)響起淆九,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎毛俏,沒想到半個(gè)月后炭庙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煌寇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年煤搜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唧席。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘲驾,靈堂內(nèi)的尸體忽然破棺而出淌哟,到底是詐尸還是另有隱情,我是刑警寧澤辽故,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布徒仓,位于F島的核電站,受9級特大地震影響誊垢,放射性物質(zhì)發(fā)生泄漏掉弛。R本人自食惡果不足惜症见,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殃饿。 院中可真熱鬧谋作,春花似錦、人聲如沸乎芳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奈惑。三九已至吭净,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肴甸,已是汗流浹背寂殉。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留原在,地道東北人友扰。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像晤斩,于是被迫代替她去往敵國和親焕檬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351