怡春院2017,日韩av网页,717韩国三级理伦电影,欧美久草网,亚洲欧美日韩综合,一级特黄色片子

您現在的位置: 主頁 > 技術分享 > 硬件知識 > MCU & ARM

STM32定時器的預裝載寄存器與影子寄存器之間的關

在STM32F10xxx系列的32位MCU上,定時器資源十分豐富,包括**控制定時器,通用定時器和基本定時器。此外,還有能夠實現定時功能的系統滴答定時器,實時時鐘以及看門狗。關于這些定時器的介紹,占據了STM32F10xxx參考手冊1/5的篇幅,可見其功能的強大。
 
在低容量和中容量的STM32F103xx產品,以及互聯型產品STM32F105xx和STM32F107xx中,只有一個**控制定時器TIM1。而在高容量和超大容量的STM32F103xx產品中,有兩個**控制定時器TIM1和TIM8。
 
在所有STM32F10xxx系列產品中,都有通用定時器TIM2~TIM5,除非另有說明。除此之外,在超大容量產品中,還有通用定時器TIM9~TIM14。
 
在高容量和超大容量的STM32F101xx和STM32F103xx產品,以及互聯型產品STM32F105xx和STM32F107xx中,有兩個基本定時器TIM6和TIM7。
 
其中,**控制定時器的功能***為強大,可以實現所有其他定時器的所有功能。TrailBreaker開發板使用的是高容量的STM32F103ZE,因此有兩個**控制定時器TIM1和TIM8。下面我們就著重介紹這兩個**控制定時器。
 
TIM1和TIM8簡介
**控制定時器(TIM1和TIM8)由一個16位的自動裝載計數器組成,它由一個可編程的預分頻器驅動。它適合多種用途,包含測量輸入信號的脈沖寬度(輸入捕獲),或者產生輸出波形(輸出比較、PWM、嵌入死區時間的互補PWM等)。使用定時器預分頻器和RCC時鐘控制預分頻器,可以實現脈沖寬度和波形周期從幾個微秒到幾個毫秒的調節。
關于實驗中用到的LED部分原理圖和GPIO跑馬燈實驗所用到的相同,在此不再多做介紹。
TIM1和TIM8定時器的功能包括:
16位向上、向下、向上/下自動裝載計數器
16位可編程(可以實時修改)預分頻器,計數器時鐘頻率的分頻系數為1~65535之間的任意數值
多達4個獨立通道: ─ 輸入捕獲 ─ 輸出比較 ─ PWM生成(邊緣或中間對齊模式) ─ 單脈沖模式輸出
死區時間可編程的互補輸出
使用外部信號控制定時器和定時器互聯的同步電路
允許在指定數目的計數器周期之后更新定時器寄存器的重復計數器
剎車輸入信號可以將定時器輸出信號置于復位狀態或者一個已知狀態
如下事件發生時產生中斷/DMA:
─ 更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
─ 觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
─ 輸入捕獲
─ 輸出比較
─ 剎車信號輸入
支持針對定位的增量(正交)編碼器和霍爾傳感器電路
觸發輸入作為外部時鐘或者按周期的電流管理
 
**定時器框圖和時鐘簡介
 
計數器時鐘可由下列時鐘源提供:
● 內部時鐘(CK_INT)
● 外部時鐘模式1:外部輸入引腳
● 外部時鐘模式2:外部觸發輸入ETR
● 內部觸發輸入(ITRx):使用一個定時器作為另一個定時器的預分頻器。如可以配置一個定時器Timer1而作為另一個定時器Timer2的預分頻器。詳見數據手冊的通用定時器部分。
 
內部時鐘源(CK_INT):
如果禁止了從模式控制器(SMS=000),則CEN、DIR(TIMx_CR1寄存器)和UG位(TIMx_EGR寄存器)是事實上的控制位,并且只能被軟件修改(UG位仍被自動清除)。只要CEN位被寫成’1’,預分頻器的時鐘就由內部時鐘CK_INT提供。下圖顯示控制電路和向上計數器在一般模式下,不帶預分頻器時的操作。
 
外部時鐘源模式1
當TIMx_SMCR寄存器的SMS=111時,此模式被選中。計數器可以在選定輸入端的每個上升沿或下降沿計數。下圖為TI2外部時鐘連接例子
 
例如,要配置向上計數器在T12輸入端的上升沿計數,使用下列步驟:
1.配置TIMx_CCMR1寄存器CC2S=01
2.配置通道2檢測TI2輸入的上升沿
3.配置TIMx_CCMR1寄存器的IC2F[3:0],選擇輸入濾波器帶寬(如果不需要濾波器,保持IC2F=0000)
4.配置TIMx_CCER寄存器的CC2P=0,選定上升沿極性
5.配置TIMx_SMCR寄存器的SMS=111,選擇定時器外部時鐘模式1
6.配置TIMx_SMCR寄存器中的TS=110,選定TI2作為觸發輸入源
7.設置TIMx_CR1寄存器的CEN=1,使能計數器
注: 捕獲預分頻器不用作觸發,所以不需要對它進行配置
當上升沿出現在TI2,計數器計數一次,且TIF標志被設置。在TI2的上升沿和計數器實際時鐘之間的延時,取決于在TI2輸入端的重新同步電路。
下圖為外部時鐘模式1下的控制電路
 
外部時鐘源模式2
選定此模式的方法為:令TIMx_SMCR寄存器中的ECE=1。
計數器能夠在外部觸發ETR的每一個上升沿或下降沿計數。
下圖是外部觸發輸入的框圖
 
設置從模式控制寄存器的ETP位選擇選擇是用ETR還是ETR的反相來作為觸發操作
例如,要配置在ETR下每2個上升沿計數一次的向上計數器,使用下列步驟:
1.本例中不需要濾波器,置TIMx_SMCR寄存器中的ETF[3:0]=0000
2.設置預分頻器,置TIMx_SMCR寄存器中的ETPS[1:0]=01
3.選擇ETR的上升沿檢測,置TIMx_SMCR寄存器中的ETP=0
4.開啟外部時鐘模式2,寫TIMx_SMCR寄存器中的ECE=1
5.啟動計數器,寫TIMx_CR1寄存器中的CEN=1
計數器在每2個ETR上升沿計數一次。
在ETR的上升沿和計數器實際時鐘之間的延時取決于在ETRP信號端的重新同步電路。
下圖為外部時鐘模式2下的控制電路
 
 
如圖,該圖為STM32的時鐘樹,結合**控制定時器框圖,我們可以看出,**定時器的時鐘不是直接來自APB2,而是來自于輸入為APB2的一個倍頻器。
當APB2的預分頻系數為1時,這個倍頻器不起作用,定時器的時鐘頻率等于APB2的頻率;當APB2的預分頻系數為其它數值(即預分頻系數為2、4、8或16)時,這個分頻器起作用,定時器的時鐘頻率等于APB2的頻率相應倍數。
假定AHB=36MHz,因為APB2允許的**頻率為72MHz,所以APB2的預分頻系數可以取任意數值;當預分頻系數=1時,APB2=72MHz,TIM1和TIM8的時鐘頻率=72MHz(分頻器不起作用);當預分頻系數=2時,APB1=36MHz,在倍頻器的作用下,TIM1和TIM8的時鐘頻率=72MHz。
有人會問,既然需要TIM1和TIM8的時鐘頻率為72MHz,為什么不直接取APB2的預分頻系數=1?答案是:APB2不但要為TIM1和TIM8提供時鐘,而且還要為其它外設提供時鐘;設置這個倍頻器可以在**其它外設使用較低時鐘頻率時,TIM1和TIM8仍能得到較高的時鐘頻率。
再舉個例子:當AHB=72MHz時,APB2因為其他設備需要,時鐘為36MHZ,因為這個倍頻器,TIM1和TIM8仍然能夠得到72MHz的時鐘頻率。能夠使用更高的時鐘頻率,無疑提高了定時器的分辨率,這也正是設計這個倍頻器的初衷。
 
**定時器寄存器簡介
可編程**控制定時器的主要部分是一個16位計數器和與其相關的自動裝載寄存器。這個計數器可以向上計數、向下計數或者向上向下雙向計數。此計數器時鐘由預分頻器分頻得到。計數器、自動裝載寄存器和預分頻器寄存器可以由軟件讀寫,即使計數器還在運行讀寫仍然有效。
時基單元,也就是決定了定時器的基本功能的模塊包含:
1.計數器寄存器(Counter register,簡寫為TIMx_CNT)
2.預分頻器寄存器 (Prescaler register,簡寫為TIMx_PSC)
3.自動裝載寄存器 (Auto-reload register,簡寫為TIMx_ARR)
4.重復次數寄存器 (Repetition counter register,簡寫為TIMx_RCR)
 
1.影子寄存器
這張圖是**定時器框圖的一部分,細心的人可以發現預分頻器寄存器、自動重載寄存器和捕捉/比較寄存器下面有一個陰影,其他的寄存器有些也有陰影。
這表示在物理上這個寄存器對應2個寄存器:一個是我們可以可以寫入或讀出的寄存器,稱為預裝載寄存器,另一個是我們看不見的、無法真正對其讀寫操作的,但在使用中真正起作用的寄存器,稱為影子寄存器.
數據手冊介紹預裝載寄存器的內容可以隨時傳送到影子寄存器,即兩者是連通的(permanently),或者在每一次更新事件(UEV)時才把預裝載寄存器的內容傳送到影子寄存器。
原文如下:
The auto-reload register is preloaded. Writing to or reading from the auto-reload register accesses the preload register. The content of the preload register are transferred into the shadow register permanently or at each update event (UEV), depending on the auto-reload preload enable bit (ARPE) in TIMx_CR1 register. The update event is sent when the counter reaches the overflow (or underflow when downcounting) and if the UDIS bit equals 0 in the TIMx_CR1 register. It can also be generated by software. The generation of the update event is described in detailed for each configuration.
在圖中的,表示對應寄存器的影子寄存器可以在發生更新事件時,被更新為它的預裝載寄存器的內容;而圖中的部分,表示對應的自動重載寄存器可以產生一個更新事件(U)或更新事件中斷(UI)。
設計預裝載寄存器和影子寄存器的好處是,所有真正需要起作用的寄存器(影子寄存器)可以在同一個時間(發生更新事件時)被更新為所對應的預裝載寄存器的內容,這樣可以**多個通道的操作能夠**地同步。如果沒有影子寄存器,軟件更新預裝載寄存器時,則同時更新了真正操作的寄存器,因為軟件不可能在一個相同的時刻同時更新多個寄存器,結果造成多個通道的時序不能同步,如果再加上例如中斷等其它因素,多個通道的時序關系有可能會混亂,造成是不可預知的結果。
 
2.預分頻寄存器
預分頻器可以將計數器的時鐘頻率按1到65536之間的任意值分頻。它是基于一個在TIMx_PSC寄存器中的16位寄存器控制的16位計數器。因為這個控制寄存器帶有緩沖器,它能夠在運行時被改變。新的預分頻器的參數在下一次更新事件到來時被采用。
下面給出了在預分頻器運行時,更改計數器參數的例子
當預分頻器的參數從1變到2時,計數器的時序圖如下:
 
當預分頻器的參數從1變到4時,計數器的時序圖如下:
 
預分頻寄存器各位的描述如下:
 
位15:0 PSC[15:0]:預分頻值
計數器的時鐘頻率(CK_CNT)等于fCK_PSC / (PSC[15:0] + 1)。
PSC的值保存在預分頻寄存器的預裝載寄存器中,在每次更新事件時加載***影子寄存器.
 
3.計數器寄存器
**定時器計數模式:在向上計數模式中,計數器從0計數到自動加載值(TIMx_ARR計數器的內容),然后重新從0開始計數并且產生一個計數器溢出事件。
如果使用了重復計數器功能,在向上計數達到設置的重復計數次數(TIMx_RCR)時,產生更新事件(UEV);否則每次計數器溢出時才產生更新事件。
在事件產生寄存器寄存器中(通過軟件方式或者使用從模式控制器)設置UG位也同樣可以產生一個更新事件。設置TIMx_CR1寄存器中的UDIS位,可以禁止更新事件;這樣可以避免在向預裝載寄存器中寫入新值時更新影子寄存器。在UDIS位被清’0’之前,將不產生更新事件。但是在應該產生更新事件時,計數器仍會被清’0’,同時預分頻器的計數也被請0(但預分頻器的數值不變)。此外,如果設置了TIMx_CR1寄存器中的URS位(選擇更新請求),設置UG位將產生一個更新事件UEV,但硬件不設置UIF標志(即不產生中斷或DMA請求)。這是為了避免在捕獲模式下清除計數器時,同時產生更新和捕獲中斷。
當發生一個更新事件時,所有的寄存器都被更新,硬件同時(依據URS位)設置更新標志位(TIMx_SR寄存器中的UIF位)。
● 重復計數器被重新加載為TIMx_RCR寄存器的內容。
● 自動裝載影子寄存器被重新置入預裝載寄存器的值(TIMx_ARR)。
● 預分頻器的緩沖區被置入預裝載寄存器的值(TIMx_PSC寄存器的內容)。
下面給出一些例子,當TIMx_ARR=0x36時計數器在不同時鐘頻率下的動作。
內部時鐘分頻因子為1 時的計數器時序圖如下:
 
內部時鐘分頻因子為2 時的計數器時序圖如下:
 
內部時鐘分頻因子為4時的計數器時序圖如下:
 
內部時鐘分頻因子為N時的計數器時序圖如下:
 
當ARPE=0時的更新事件(TIMx_ARR沒有預裝入) 時的計數器時序圖如下:
 
當ARPE=1時的更新事件(TIMx_ARR預裝入) 時的計數器時序圖如下:
 
在向下模式中,計數器從自動裝入的值(TIMx_ARR計數器的值)開始向下計數到0,然后從自動裝入的值重新開始并且產生一個計數器向下溢出事件。
如果使用了重復計數器,當向下計數重復了重復計數寄存器(TIMx_RCR)中設定的次數后,將產生更新事件(UEV),否則每次計數器下溢時才產生更新事件。
在TIMx_EGR寄存器中(通過軟件方式或者使用從模式控制器)設置UG位,也同樣可以產生一個更新事件。
設置TIMx_CR1寄存器的UDIS位可以禁止UEV事件。這樣可以避免向預裝載寄存器中寫入新值時更新影子寄存器。因此UDIS位被清為0之前不會產生更新事件。然而,計數器仍會從當前自動加載值重新開始計數,并且預分頻器的計數器重新從0開始(但預分頻系數不變)。
此外,如果設置了TIMx_CR1寄存器中的URS位(選擇更新請求) ,設置UG位將產生一個更新事件UEV但不設置UIF標志(因此不產生中斷和DMA請求),這是為了避免在發生捕獲事件并清除計數器時,同時產生更新和捕獲中斷。
當發生更新事件時,所有的寄存器都被更新,并且(根據URS位的設置)更新標志位(TIMx_SR寄存器中的UIF位)也被設置。
● 重復計數器被重置為TIMx_RCR寄存器中的內容
● 預分頻器的緩存器被加載為預裝載的值(TIMx_PSC寄存器的值)。
● 當前的自動加載寄存器被更新為預裝載值(TIMx_ARR寄存器中的內容)。
注:自動裝載在計數器重載入之前被更新,因此下一個周期將是預期的值。
下面是一些當TIMx_ARR=0x36時,計數器在不同時鐘頻率下的動作。
內部時鐘分頻因子為1 時的計數器時序圖如下:
 
 
內部時鐘分頻因子為2 時的計數器時序圖如下:
 
內部時鐘分頻因子為4時的計數器時序圖如下:
 
內部時鐘分頻因子為N時的計數器時序圖如下:
 
當沒有使用重復計數器時的更新事件時的計數器時序圖:
 
中央對齊模式(up/down counting) 在中央對齊模式,計數器從0開始計數到自動加載的值(TIMx_ARR寄存器)−s211,產生一個計數器溢出事件,然后向下計數到1并且產生一個計數器下溢事件;然后再從0開始重新計數。
在此模式下,不能寫入TIMx_CR1中的DIR方向位。它由硬件更新并指示當前的計數方向。
可以在每次計數上溢和每次計數下溢時產生更新事件;也可以通過(軟件或者使用從模式控制器)設置TIMx_EGR寄存器中的UG位產生更新事件。然后,計數器重新從0開始計數,預分頻器也重新從0開始計數。
設置TIMx_CR1寄存器中的UDIS位可以禁止UEV事件。這樣可以避免在向預裝載寄存器中寫入新值時更新影子寄存器。因此UDIS位被清為0之前不會產生更新事件。然而,計數器仍會根據當前自動重加載的值,繼續向上或向下計數。此外,如果設置了TIMx_CR1寄存器中的URS位(選擇更新請求) ,設置UG位將產生一個更新事件UEV但不設置UIF標志(因此不產生中斷和DMA請求),這是為了避免在發生捕獲事件并清除計數器時,同時產生更新和捕獲中斷。
當發生更新事件時,所有的寄存器都被更新,并且(根據URS位的設置)更新標志位(TIMx_SR寄存器中的UIF位)也被設置。
● 重復計數器被重置為TIMx_RCR寄存器中的內容
● 預分頻器的緩存器被加載為預裝載(TIMx_PSC寄存器)的值。
● 當前的自動加載寄存器被更新為預裝載值(TIMx_ARR寄存器中的內容)。注:如果因為計數器溢出而產生更新,自動重裝載將在計數器重載入之前被更新,因此下一個周期將是預期的值(計數器被裝載為新的值)。
下面是一些計數器在不同時鐘頻率下的操作的例子:
內部時鐘分頻因子為1,TIMx_ARR=0x6時的計數器時序圖:
 
內部時鐘分頻因子為2時的計數器時序圖:
 
內部時鐘分頻因子為4,TIMx_ARR=0x36時的計數器時序圖:
 
注:在此無論是中心對齊模式2或3都是在溢出時與UIF標志一起使用
內部時鐘分頻因子為N,計數器時序圖如下:
 
ARPE=1時的更新事件(計數器下溢),計數器時序圖如下:
 
計數器寄存器各位的描述如下:
 
位15:0 ARR[15:0]: 自動重裝載的值 (Prescaler value)
ARR包含了將要裝載入實際的自動重裝載寄存器的值。詳細參考數據手冊13.3.1節:有關ARR的更新和動作。當自動重裝載的值為空時,計數器不工作。
 
4.重復計數器
前面解釋了計數器上溢/下溢時更新事件(UEV)是如何產生的,然而事實上它只能在重復計數達到0的時候產生。這個特性對產生PWM信號非常有用。
這意味著在每N次計數上溢或下溢時,數據從預裝載寄存器傳輸到影子寄存器(TIMx_ARR自動重載入寄存器,TIMx_PSC預裝載寄存器,還有在比較模式下的捕獲/比較寄存器TIMx_CCRx),N是TIMx_RCR重復計數寄存器中的值。
重復計數器在下述任一條件成立時遞減:
● 向上計數模式下每次計數器溢出時,
● 向下計數模式下每次計數器下溢時,
● 中央對齊模式下每次上溢和每次下溢時。雖然這樣限制了PWM的**循環周期為128,但它能夠在每個PWM周期2次更新占空比。在中央對齊模式下,因為波形是對稱的,如果每個PWM周期中僅刷新一次比較寄存器,則**的分辨率為2xTck。
重復計數器是自動加載的,重復速率是由TIMx_RCR寄存器的值定義。當更新事件由軟件產生(通過設置TIMx_EGR 中的UG位)或者通過硬件的從模式控制器產生,則無論重復計數器的值是多少,立即發生更新事件,并且TIMx_RCR寄存器中的內容被重載入到重復計數器。
下圖為不同模式下更新速率的例子,及TIMx_RCR的寄存器設置
 
重復計數器各位的描述如下:
 
位15:8 保留位,始終讀為0。
位7:0 REP[7:0]: 重復計數器的值 (Repetition counter value) 開啟了預裝載功能后,這些位允許用戶設置比較寄存器的更新速率(即周期性地從預裝載寄存器傳輸到當前寄存器);如果允許產生更新中斷,則會同時影響產生更新中斷的速率。
每次向下計數器REP_CNT達到0,會產生一個更新事件并且計數器REP_CNT重新從REP值開始計數。由于REP_CNT只有在周期更新事件U_RC發生時才重載REP值,因此對TIMx_RCR寄存器寫入的新值只在下次周期更新事件發生時才起作用。這意味著在PWM模式中,(REP+1)對應著:
- 在邊沿對齊模式下,PWM周期的數目;
- 在中心對稱模式下,PWM半周期的數目;
 
5.控制寄存器1
控制寄存器1各位的描述如下:
 
 
 
位15:10 保留,始終讀為0。
位9:8 CKD[1:0]:時鐘分頻因子 (Clock division)
這2位定義在定時器時鐘(CK_INT)頻率、死區時間和由死區發生器與數字濾波器(ETR,TIx)所用的采樣時鐘之間的分頻比例。
00:tDTS = tCK_INT
01:tDTS = 2 x tCK_INT
10:tDTS = 4 x tCK_INT
11:保留,不要使用這個配置
位7 ARPE:自動重裝載預裝載允許位 (Auto-reload preload enable)
0:TIMx_ARR寄存器沒有緩沖;
1:TIMx_ARR寄存器被裝入緩沖器。
位6:5 CMS[1:0]:選擇中央對齊模式 (Center-aligned mode selection)
00:邊沿對齊模式。計數器依據方向位(DIR)向上或向下計數。
01:中央對齊模式1。計數器交替地向上和向下計數。配置為輸出的通道(TIMx_CCMRx寄存器中CCxS=00)的輸出比較中斷標志位,只在計數器向下計數時被設置。
10:中央對齊模式2。計數器交替地向上和向下計數。配置為輸出的通道(TIMx_CCMRx寄存器中CCxS=00)的輸出比較中斷標志位,只在計數器向上計數時被設置。
11:中央對齊模式3。計數器交替地向上和向下計數。配置為輸出的通道(TIMx_CCMRx寄存器中CCxS=00)的輸出比較中斷標志位,在計數器向上和向下計數時均被設置。
在計數器開啟時(CEN=1),不允許從邊沿對齊模式轉換到中央對齊模式。
位4 DIR:方向 (Direction)
0:計數器向上計數;
1:計數器向下計數。
當計數器配置為中央對齊模式或編碼器模式時,該位為只讀。
位3 OPM:單脈沖模式 (One pulse mode)
0:在發生更新事件時,計數器不停止;
1:在發生下一次更新事件(清除CEN位)時,計數器停止。
位2 URS:更新請求源 (Update request source)
軟件通過該位選擇UEV事件的源
0:如果使能了更新中斷或DMA請求,則下述任一事件產生更新中斷或DMA請求:
−計數器溢出/下溢
−設置UG位
−從模式控制器產生的更新
1:如果使能了更新中斷或DMA請求,則只有計數器溢出/下溢才產生更新中斷或DMA請求
位1 UDIS:禁止更新 (Update disable)
軟件通過該位允許/禁止UEV事件的產生
0:允許UEV。更新(UEV)事件由下述任一事件產生:
−計數器溢出/下溢
−設置UG位
−從模式控制器產生的更新 具有緩存的寄存器被裝入它們的預裝載值。(更新影子寄存器)
1:禁止UEV。不產生更新事件,影子寄存器(ARR、PSC、CCRx)保持它們的值。如果設置了UG位或從模式控制器發出了一個硬件復位,則計數器和預分頻器被重新初始化。
位0 CEN:使能計數器 (Counter enable)
0:禁止計數器;
1:使能計數器。
在軟件設置了CEN位后,外部時鐘、門控模式和編碼器模式才能工作。觸發模式可以自動地通過硬件設置CEN位。
 
6.事件產生寄存器
位15:8 保留,始終讀為0。
位7 BG:產生剎車事件 (Break generation) 該位由軟件置’1’,用于產生一個剎車事件,由硬件自動清’0’。
0:無動作;
1:產生一個剎車事件。此時MOE=0、BIF=1,若開啟對應的中斷和DMA,則產生相應的中斷和DMA。
位6 TG:產生觸發事件 (Trigger generation) 該位由軟件置’1’,用于產生一個觸發事件,由硬件自動清’0’。
0:無動作;
1:TIMx_SR寄存器的TIF=1,若開啟對應的中斷和DMA,則產生相應的中斷和DMA。
位5 COMG:捕獲/比較事件,產生控制更新 (Capture/Compare control update generation) 該位由軟件置’1’,由硬件自動清’0’。
0:無動作;
1:當CCPC=1,允許更新CCxE、CCxNE、OCxM位。
該位只對擁有互補輸出的通道有效。
位4 CC4G:產生捕獲/比較4事件 (Capture/Compare 4 generation) 參考CC1G描述。
位3 CC3G:產生捕獲/比較3事件 (Capture/Compare 3 generation) 參考CC1G描述。
位2 CC2G:產生捕獲/比較2事件 (Capture/Compare 2 generation) 參考CC1G描述。
位1 CC1G:產生捕獲/比較1事件 (Capture/Compare 1 generation) 該位由軟件置’1’,用于產生一個捕獲/比較事件,由硬件自動清’0’。
0:無動作;
1:在通道CC1上產生一個捕獲/比較事件:
若通道CC1配置為輸出: 設置CC1IF=1,若開啟對應的中斷和DMA,則產生相應的中斷和DMA。
若通道CC1配置為輸入:當前的計數器值被捕獲***TIMx_CCR1寄存器;設置CC1IF=1,若開啟對應的中斷和DMA,則產生相應的中斷和DMA。
若CC1IF已經為1,則設置CC1OF=1。
位0 UG:產生更新事件 (Update generation) 該位由軟件置’1’,由硬件自動清’0’。
0:無動作;
1:重新初始化計數器,并產生一個更新事件。注意預分頻器的計數器也被清’0’(但是預分頻系數不變)。若在中心對稱模式下或DIR=0(向上計數)則計數器被清’0’;若DIR=1(向下計數)則計數器取TIMx_ARR的值。
關于剎車事件,觸發事件,捕獲比較事件的描述,詳見數據手冊13章
 
 
 
程序分析:
固件庫函數分析:
STM32的**定時器功能十分強大,但相應的功能強大就意味著結構復雜。復雜的結構帶來的是復雜的庫函數。
**定時器TIM1和TIM8一共有著80多個庫函數,如果對其一一介紹,不但浪費時間,浪費精力,還有可能變成類似《固件庫使用手冊》一樣的東西。在學習的時候,我們對事物的認知總是螺旋上升的,尤其是我們做嵌入式開發,當遇到一個新的系統或者硬件,指望著看一遍數據手冊,就**掌握其使用方法是不可能的。所以,我們先建立起一個***簡單,***基礎的實驗,方便對新事物有著一個感性的直觀的認知。有了清晰的認知,明白了基本原理后,后面的學習速度就會大大加快,也能的心應手了.看數據手冊和固件庫函數的時候,不要圖快,不要浮躁,指望著看看相關的資料,復制下固件庫例程的代碼把程序搞定,這不叫“寫代碼”,這叫“移植”。基礎打的不牢靠,對于細節問題理解的不清晰,是不可能真正的學好ARM的.如果想繼續學習的話,你會發現,你“節省”的時間,在越來越深入后,就會給你帶來雙倍的“節省時間”長的麻煩.
----------作者的心得在"stm32f10x_tim.h"中可以看到如下定義:
 
typedef struct { uint16_t TIM_Prescaler;   uint16_t TIM_CounterMode;   uint16_t TIM_Period;   uint16_t TIM_ClockDivision;   uint8_t TIM_RepetitionCounter;  } TIM_TimeBaseInitTypeDef; 
庫函數TIM_TimeBaseInit()的原型如下
 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { uint16_t tmpcr1 = 0; assert_param(IS_TIM_ALL_PERIPH(TIMx)); assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));   tmpcr1 = TIMx->CR1;   if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)|| (TIMx == TIM4) || (TIMx == TIM5)) { tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; }   if((TIMx != TIM6) && (TIMx != TIM7)) { tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD)); tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; }   TIMx->CR1 = tmpcr1;   TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;   if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17)) { TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; } TIMx->EGR = TIM_PSCReloadMode_Immediate; } 
正如函數名,和結構體名所描述的,這個函數的作用為,初始化TIM1的時基部分.
結合著數據手冊和上面的**定時器框圖和時鐘簡介可知,我們使用**定時器TIM1中斷時對TIM1的時基配置順序如下所示。
 
在此例中,我們可以這樣定義他.
 
 TIM_TimeBaseStructure.TIM_Prescaler=(18000-1); //時鐘預分頻 TIM_TimeBaseStructure.TIM_Period=(4000-1); //定時器初始值 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 時鐘分割 TIM_CKD_DIV1 為 0x0 TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); //初始化定時器的值 
上面的初始化流程圖已經說明,
定時器中斷頻率 = 時鐘頻率/(時鐘預分頻+1)/(計數器裝載值+1)
所以我們要達到1S間隔的跑馬燈,定時器的中斷頻率為1Hz,所以這里只要時鐘分頻的值與定時器的計數器的裝載值之積為72MHZ且不越界即可
關于計數模式,在stm32f10x.h中有如下的定義
 
 #define TIM_CounterMode_Up ((uint16_t)0x0000) #define TIM_CounterMode_Down ((uint16_t)0x0010) #define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) #define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) #define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) 

版權*轉載申明:
本站內容為本站編輯或整理,所以轉載務必通知本站并以超鏈接形式注明內容來自本站,以免帶來不必要麻煩。引文出處:http://www.360doc.com/content/17/0905/11/6973384_684717284.shtml

?