11-STM32 高級定時器TIM1/8


高級定時器

高級控制定時器(TIM1 和 TIM8)和通用定時器在基本定時器的基礎上引入了外部引腳,可以實現輸入捕獲輸出比較功能。
高級控制定時器比通用定時器增加了可編程死區互補輸出、重復計數器、帶剎車(斷路)功能,這些功能都是針對工業電機控制方面。
高級控制定時器時基單元包含:
①16 位自動重裝載寄存器ARR,
②16 位的計數器CNT,可向上/下計數
③16位可編程預分頻器 PSC,預分頻器時鍾源有多種可選,有內部的時鍾、外部時鍾

④還有一個 8 位的重復計數器 RCR,這樣最高可實現 40 位的可編程定時(僅高級定時器獨有)

 

功能框圖:

 

高級定時器的定時器的時鍾來源(有四個時鍾來源):

內部時鍾源 CK_INT

外部時鍾模式 1:外部輸入引腳 TIx(x=1,2,3,4)

外部時鍾模式 2:外部觸發輸入 ETR

內部觸發輸入(ITRx)

高級定時器時鍾掛載在APB2上

 

 

 1)內部時鍾源CK_INT    內部時鍾 CK_INT來自於芯片內部,等於72M(一般情況下,我們都是使用內部時鍾

對應於寄存器配置位

當從模式控制寄存器 TIMx_SMCR 的 SMS 位等於 000 時,則使用內部時鍾。

 

2)外部時鍾模式 1:外部輸入引腳 TIx(x=1,2,3,4)                     

①:時鍾信號輸入引腳

當使用外部時鍾模式 1 的時候,時鍾信號來自於定時器的輸入通道,總共有 4 個,分別為TI1/2/3/4,即TIMx_CH1/2/3/4。具體使用哪一路信號,由TIM_CCMRx的位CCxS[1:0]配置,其中 CCMR1 控制 TI1/2,CCMR2 控制 TI3/4。

②:濾波器

如果來自外部的時鍾信號的頻率過高或者混雜有高頻干擾信號的話,我們就需要使用濾波器對信號重新采樣,來達到降頻或者去除高頻干擾的目的,具體的由 TIMx_CCMRx的位 ICxF[3:0]配置。

③:邊沿檢測

邊沿檢測的信號來自於濾波器的輸出,在成為觸發信號之前,需要進行邊沿檢測,決定是上升沿有效還是下降沿有效,具體的由 TIMx_CCER的位 CCxP 和 CCxNP 配置。

④:觸發選擇

當使用外部時鍾模式 1時,觸發源有兩個,一個是濾波后的定時器輸入 1(TI1FP1)和濾波后的定時器輸入 2(TI2FP2),具體的由TIMxSMCR 的位 TS[2:0]配置。

⑤:從模式選擇

選定了觸發源信號后,最后我們需把信號連接到 TRGI 引腳,讓觸發信號成為外部時鍾模式1的輸入,最終等於CK_PSC,然后驅動計數器CNT計數。具體的配置TIMx_SMCR的位 SMS[2:0]為 111 即可選擇外部時鍾模式 1。

⑥:使能計數器

經過上面的 5 個步驟之后,最后我們只需使能計數器開始計數,外部時鍾模式 1 的配置就算完成。使能計數器由 TIMx_CR1 的位 CEN 配置。

 

3)外部時鍾模式 2:外部觸發輸入 ETR

 

①:時鍾信號輸入引腳

 當使用外部時鍾模式 2 的時候,時鍾信號來自於定時器的特定輸入通道 TIMx_ETR,只有 1 個。

②:外部觸發極性

來自 ETR 引腳輸入的信號可以選擇為上升沿或者下降沿有效,具體的由 TIMx_SMCR的位 ETP 配置。

③:外部觸發預分頻器

由於ETRP 的信號的頻率不能超過 TIMx_CLK(72M)的 1/4,當觸發信號的頻率很高的情況下,就必須使用分頻器來降頻,具體的由 TIMx_SMCR 的位 ETPS[1:0]配置。

 ④:濾波器

如果 ETRP 的信號的頻率過高或者混雜有高頻干擾信號的話,我們就需要使用濾波器對 ETRP 信號重新采樣,來達到降頻或者去除高頻干擾的目的。具體的由 TIMx_SMCR 的位 ETF[3:0]配置,其中的 fDTS 是由內部時鍾 CK_INT 分頻得到,具體的由 TIMx_CR1的位CKD[1:0]配置。

⑤:從模式選擇

經過濾波器濾波的信號連接到ETRF引腳后,觸發信號成為外部時鍾模式2的輸入,最終等於CK_PSC,然后驅動計數器 CNT 計數。具體的配置TIMx_SMCR 的位 ECE 為 1 即可選擇外部時鍾模式 2。

⑥:使能計數器

經過上面的 5 個步驟之后,最后我們只需使能計數器開始計數,外部時鍾模式 2 的配置就算完成。使能計數器由 TIMx_CR1 的位 CEN 配置。

 

4)內部觸發輸入

內部觸發輸入是使用一個定時器作為另一個定時器的預分頻器。硬件上高級控制定時器和通用定時器在內部連接在一起,可以實現定時器同步或級聯。主模式的定時器可以對從模式定時器執行復位、啟動、停止或提供時鍾。

 

 

控制器:

高級控制定時器控制器部分包括觸發控制器、從模式控制器以及編碼器接口。觸發控制器用來針對片內外設輸出觸發信號,比如為其它定時器提供時鍾和觸發 DAC/ADC 轉換。 編碼器接口專門針對編碼器計數而設計。從模式控制器可以控制計數器復位、啟動、遞增/遞減、計數。

 

 

時基單元:

 

高級控制定時器時基單元功能包括四個寄存器,分別是計數器寄存器(CNT)、預分頻器寄存器(PSC)、自動重載寄存器(ARR)和重復計數器寄存器(RCR)

 

預分頻器 PSC 

預分頻器 PSC,有一個輸入時鍾 CK_PSC 和一個輸出時鍾 CK_CNT。輸入時鍾CK_PSC 就是上面時鍾源的輸出,輸出 CK_CNT 則用來驅動計數器 CNT 計數。通過設置預分頻器 PSC 的值可以得到不同的 CK_CNT,實際計算為:f CK_CNT 等於 f CK_PSC /(PSC[15:0]+1),可以實現 1 至 65536 分頻。

 

計數器 CNT 

高級控制定時器的計數器有三種計數模式,分別為遞增計數模式、遞減計數模式和遞增/遞減(中心對齊)計數模式。

(1) 遞增計數模式下,計數器從 0 開始計數,每來一個 CK_CNT 脈沖計數器就增加 1,直到計數器的值與自動重載寄存器 ARR 值相等,然后計數器又從 0 開始計數並生成計數器上溢事件,計數器總是如此循環計數。如果禁用重復計數器,在計數器生成上溢事件就馬上生成更新事件(UEV);如果使能重復計數器,每生成一次上溢事件重復計數器內容就減 1,直到重復計數器內容為 0 時才會生成更新事件。 

(2) 遞減計數模式下,計數器從自動重載寄存器 ARR 值開始計數,每來一個 CK_CNT 脈沖計數器就減 1,直到計數器值為 0,然后計數器又從自動重載寄存器 ARR 值開始遞減計數並生成計數器下溢事件,計數器總是如此循環計數。如果禁用重復計數器,計數器生成下溢事件就馬上生成更新事件;如果使能重復計數器,每生成一次下溢事件重復計數器內容就減 1,直到重復計數器內容為 0 時才會生成更新事件。 

(3) 中心對齊模式下,計數器從 0 開始遞增計數,直到計數值等於(ARR-1)值生成計數器上溢事件,然后從 ARR 值開始遞減計數直到 1 生成計數器下溢事件。然后又從 0 開始計數,如此循環。每次發生計數器上溢和下溢事件都會生成更新事件。 

 

自動重載寄存器 ARR  

自動重載寄存器 ARR 用來存放與計數器 CNT 比較的值,如果兩個值相等就遞減重復計數器。可以通過 TIMx_CR1寄存器的 ARPE位控制自動重載影子寄存器功能

如果 ARPE位置 1,自動重載影子寄存器有效,只有在事件更新時才把 TIMx_ARR 值賦給影子寄存器。

如果 ARPE 位為 0,則修改 TIMx_ARR 值馬上有效。 

  

 

重復計數器 RCR 

在基本/通用定時器發生上/下溢事件時直接就生成更新事件,但對於高級控制定時器卻不是這樣,高級控制定時器在硬件結構上多出了重復計數器,在定時器發生上溢或下溢事件是遞減重復計數器的值,只有當重復計數器為 0 時才會生成更新事件。在發生 N+1 個上溢或下溢事件(N 為 RCR 的值)時產生更新事件。

 

 

 

輸入捕獲功能:

可以對輸入的信號的上升沿,下降沿或者雙邊沿進行捕獲。

1)測量輸入信號的脈寬

2)測量PWM輸入信號的頻率和占空比 

 

輸入捕獲的大概的原理:

當捕獲到信號的跳變沿的時候,把計數器 CNT 的值鎖存到捕獲寄存器 CCR 中,把前后兩次捕獲到的 CCR 寄存器中的值相減,就可以算出脈寬或者頻率。(如果捕獲的脈寬的時間長度>你的捕獲定時器的周期,就會發生溢出,這個需要做額外的處理)

         

 

①輸入通道(脈沖信號輸入)    

需要被測量的信號從定時器的外部引腳 TIMx_CH1/2/3/4 進入,通常叫 TI1/2/3/4   

②輸入濾波器和邊沿檢測器 

當輸入的信號存在高頻干擾的時候,我們需要對輸入信號進行濾波,即進行重新采樣,根據采樣定律,采樣的頻率必須大於等於兩倍的輸入信號。比如輸入的信號為 1M,又存在高頻的信號干擾,那么此時就很有必要進行濾波,我們可以設置采樣頻率為 2M,這樣可以在保證采樣到有效信號的基礎上把高於 2M 的高頻干擾信號過濾掉。 濾波器的配置由 CR1 寄存器的位 CKD[1:0]和 CCMR1/2 的位 ICxF[3:0]控制。從 ICxF位的描述可知,采樣頻率 f SAMPLE 可以由 f CK_INT 和 f DTS 分頻后的時鍾提供,其中是 f CK_INT 內部時鍾,f DTS 是 f CK_INT 經過分頻后得到的頻率,分頻因子由 CKD[1:0]決定,可以是不分頻,2 分頻或者是 4 分頻。

      

      

       邊沿檢測器用來設置信號在捕獲的時候是什么邊沿有效,可以是上升沿,下降沿,或者是雙邊沿,具體的由 CCER 寄存器的位 CCxP 和 CCxNP 決定。 

      

③捕獲通道 

捕獲通道就是圖中的 IC1/2/3/4,每個捕獲通道都有相對應的捕獲寄存器 CCR1/2/3/4,當發生捕獲的時候,計數器 CNT 的值就會被鎖存到捕獲寄存器中。 

輸入通道和捕獲通道的區別:輸入通道是用來輸入信號的,捕獲通道是用來捕獲輸入信號的通道,一個輸入通道的信號可以同時輸入給兩個捕獲通道。比如輸入通道 TI1 的信號經過濾波邊沿檢測器之后的 TI1FP1 和 TI1FP2 可以進入到捕獲通道 IC1和 IC2,其實這就是我們后面要講的 PWM 輸入捕獲,只有一路輸入信號(TI1)卻占用了兩個捕獲通道(IC1 和 IC2)。當只需要測量輸入信號的脈寬時候,用一個捕獲通道即可。輸入通道和捕獲通道的映射關系具體由寄存器 CCMRx 的位 CCxS[1:0]配置。 

      

     

        ④預分頻器 

        ICx 的輸出信號會經過一個預分頻器,用於決定發生多少個事件時進行一次捕獲。具體的由寄存器 CCMRx 的位 ICxPSC 配置,如果希望捕獲信號的每一個邊沿,則不分頻。 

      

 

⑤捕獲寄存器 

經過預分頻器的信號 ICxPS 是最終被捕獲的信號,當發生捕獲時(第一次),計數器CNT 的值會被鎖存到捕獲寄存器 CCR 中,還會產生 CCxI 中斷,相應的中斷位 CCxIF(在SR 寄存器中)會被置位,通過軟件或者讀取 CCR 中的值可以將 CCxIF清 0。如果發生第二次捕獲(即重復捕獲:CCR 寄存器中已捕獲到計數器值且 CCxIF 標志已置 1),則捕獲溢出標志位 CCxOF(在 SR 寄存器中)會被置位,CCxOF 只能通過軟件清零。

             

 

 

 

 

 

輸出比較功能:      

   

輸出比較就是通過定時器的外部引腳對外輸出控制信號,有凍結、將通道 X(x=1,2,3,4)設置為匹配時輸出有效電平、無效電平、翻轉、強制變為無效電平、強制變為有效電平、PWM1 和 PWM2 這八種模式,具體使用哪種模式由寄存器 CCMRx 的位 OCxM[2:0]配置。其中 PWM 模式是輸出比較中的特例,使用的也最多。

  

①比較寄存器    

計數器 CNT 的值跟比較寄存器 CCR 的值相等的時候,輸出參考信號 OCxREF 的信號的極性就會改變,其中 OCxREF=1(高電平)稱之為有效電平,OCxREF=0(低電平)稱之為無效電平,並且會產生比較中斷 CCxI,相應的標志位 CCxIF(SR 寄存器中)會置位。然后 OCxREF 再經過一系列的控制之后就成為真正的輸出信號 OCx/OCxN。        

②死區發生器 

在生成的參考波形 OCxREF 的基礎上,可以插入死區時間,用於生成兩路互補的輸出信號 OCx 和 OCxN,死區時間的大小具體由 BDTR 寄存器的位 DTG[7:0]配置。死區時間的大小必須根據與輸出信號相連接的器件及其特性來調整。

MOS開關和關閉需要時間-->(由 MOS 管的工藝決定)

 

在這個半橋驅動電路中,如果想讓 Q1 截止 Q2 導通,要先讓Q1 截止一段時間之后,再等一段時間才讓 Q2 導通,那么這段等待的時間就稱為死區時間,如果 Q1 關閉之后,馬上打開 Q2,那么此時一段時間內相當於 Q1 和 Q2 都導通了,這樣電路會短路。

針對上面的半橋驅動電路而畫的帶死區插入的 PWM 信號,圖中的死區時間要根據 MOS 管的工藝來調節:

 

③輸出控制 

 

在輸出比較的輸出控制中,參考信號OCxREF在經過死區發生器之后會產生兩路帶死區的互補信號 OCx_DT 和 OCxN_DT(通道 1~3 才有互補信號,通道4沒有,其余跟通道1~3 一樣),這兩路帶死區的互補信號然后就進入輸出控制電路,如果沒有加入死區控制,那么進入輸出控制電路的信號就直接是OCxREF。 

進入輸出控制電路的信號會被分成兩路,一路是原始信號,一路是被反向的信號,具體的由寄存器 CCER 的位 CCxP 和 CCxNP 控制。經過極性選擇的信號是否由 OCx 引腳輸出到外部引腳 CHx/CHxN 則由寄存器 CCER 的位 CxE/CxNE 配置。 如果加入了斷路(剎車)功能,則斷路和死區寄存器 BDTR 的 MOE、OSSI和 OSSR 這三個位會共同影響輸出的信號。 

④輸出引腳 

輸出比較的輸出信號最終是通過定時器的外部 IO 來輸出的,分別為 CH1/2/3/4,其中前面三個通道還有互補的輸出通道 CH1/2/3N

 

 

斷路功能: 就是電機控制的剎車功能。

使能斷路功能時,根據相關控制位狀態修改輸出信號電平。在任何情況下,OCx 和 OCxN 輸出都不能同時為有效電平,這關系到電機控制常用的 H 橋電路結構原因。 

 

斷路源可以是時鍾故障事件,由內部復位時鍾控制器中的時鍾安全系統(CSS)生成,也可以是外部斷路輸入 IO,兩者是或運算關系。 系統復位啟動都默認關閉斷路功能,將斷路和死區寄存器(TIMx_BDTR)的 BKE 為置 1,使能斷路功能。可通過 TIMx_BDTR 寄存器的 BKP 位設置設置斷路輸入引腳的有效電平,設置為 1 時輸入 BRK 為高電平有效,否則低電平有效。 

發送斷路時,將產生以下效果:

①TIMx_BDTR寄存器中主輸出模式使能(MOE)位被清零,輸出處於無效、空閑或復位狀態; 

②根據相關控制位狀態控制輸出通道引腳電平;當使能通道互補輸出時,會根據情況自動控制輸出通道電平; 

③將TIMx_SR寄存器中的BIF位置 1,並可產生中斷和DMA傳輸請求。 

④如果TIMx_BDTR寄存器中的自動輸出使能(AOE)位置1,則MOE位會在發生下一個UEV事件時自動再次置 1。

 

 

結構體:

時基結構體

1 1 typedef struct
2 2 {
3 3   uint16_t TIM_Prescaler;          //16位   預分頻值                                
4 4   uint16_t TIM_CounterMode;   //計數模式(向上、向下...)    基本定時器只能向上,故不用設置                              
5 5   uint16_t TIM_Period;              //16位  定時器周期        ARR自動重裝值        
6 6   uint16_t TIM_ClockDivision;       //時鍾分頻 設置定時器時鍾 CK_INT 頻率與數字濾波器采樣時鍾頻率分頻比,基本定時器沒有此功能,不用設置                 
7 7   uint8_t TIM_RepetitionCounter; //重復計數器,只有TIM1和TIM8才有  利用它可以非常容易控制輸出 PWM 的個數
8 8                                        
9 9 } TIM_TimeBaseInitTypeDef; 

輸出比較結構體

 1 typedef struct
 2 {
 3   uint16_t TIM_OCMode;        //比較輸出模式選擇,總共有八種,常用的為 PWM1/PWM2。它設定CCMRx 寄存器 OCxM[2:0]位的值                               
 4   uint16_t TIM_OutputState;  //比較輸出使能,決定最終的輸出比較信號 OCx 是否通過外部引腳輸出
 5   uint16_t TIM_OutputNState;  //比較互補輸出使能,決定 OCx 的互補信號 OCxN 是否通過外部引腳輸出
 6   uint16_t TIM_Pulse;       //比較輸出脈沖寬度,實際設定比較寄存器 CCR 的值,決定脈沖寬度。可設置范圍為 0 至 65535
 7   uint16_t TIM_OCPolarity;    //比較輸出極性,可選 OCx 為高電平有效或低電平有效。它決定着定時器通道有效電平
 8   uint16_t TIM_OCNPolarity; // 比較互補輸出極性,可選 OCxN 為高電平有效或低電平有效
 9   uint16_t TIM_OCIdleState;   //空閑狀態時通道輸出電平設置,可選輸出 1 或輸出 0
10   uint16_t TIM_OCNIdleState;  //空閑狀態時互補通道輸出電平設置,可選輸出 1 或輸出 0
11 } TIM_OCInitTypeDef;    

 

 

帶死區和剎車功能的互補輸出實驗:

 1 void PWM_OC_IN(void)
 2 {
 3   GPIO_InitTypeDef          GPIO_InitStructure;
 4     TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
 5     TIM_OCInitTypeDef         TIM_OCInitStructure;
 6     TIM_BDTRInitTypeDef       TIM_BDTRInitStructure;
 7     
 8     
 9     //時鍾配置
10     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);// 默認復用
11     
12     
13     //復用管腳配置--輸出比較通道
14     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 
15     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //復用推挽輸出模式
16     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //輸出速度頻率 
17     GPIO_Init(GPIOA, &GPIO_InitStructure);   //GPIOA
18     
19     //輸出比較通道互補通道初始化
20     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; 
21     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //復用推挽輸出模式
22     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //輸出速度頻率 
23     GPIO_Init(GPIOB, &GPIO_InitStructure);   //GPIOB
24     
25     //輸出比較通道剎車通道
26     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 
27     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //復用推挽輸出模式
28     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //輸出速度頻率 
29     GPIO_Init(GPIOB, &GPIO_InitStructure);   //GPIOB
30     GPIO_ResetBits(GPIOB,GPIO_Pin_12);//默認輸出低電平
31     
32     
33      //時基配置
34     TIM_TimeBaseStructure.TIM_Prescaler = 0;   //預分頻 --72MHZ來驅動
35     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數模式
36     TIM_TimeBaseStructure.TIM_Period = 7199;     //TimerPeriod;    //ARR (占空比CCR/AAR)10kHz
37     TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //定時器濾波,通常為0,這里死區時間用到
38     TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//配置寄存器TIM_RCR(重復次數寄存器) 
39     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
40     
41     
42     
43      //輸出比較功能配置
44     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;    //pwm1模式
45     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比較輸出使能
46     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比較輸出互補輸出使能
47     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//!!!!!!高電平有效!!!!!
48     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//!!!!!!高電平有效!!!!!
49     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;//經死區后輸出高電平
50     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;//經死區后輸出低電平
51     TIM_OCInitStructure.TIM_Pulse = 1500;   //Channel1Pulse(CCR);
52     TIM_OC1Init(TIM1, &TIM_OCInitStructure); //通道1
53     
54     //使能TIM的ARR和CRR,以及使能TIM定時器,開啟pwm輸出
55     TIM_ARRPreloadConfig(TIM1, ENABLE);                 //使能TIM1的寄存器ARR的預裝載功能,disable時將會使改變ARR值時立即生效
56     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIM1通道1的CCR的預裝載功能,disable時將會使改變CRR值時立即生效
57     
58      
59      //剎車和死區結構體初始化
60   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;//運行狀態下關閉狀態選擇
61   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;//空閑狀態下關閉狀態選擇
62   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;//鎖定配置級別
63   TIM_BDTRInitStructure.TIM_DeadTime = 11;  //輸出比較信號死區時間配置,具體如何計算可參考BDTR:UTG[7:0]的描述
64                                              //這里配置的死區時間為152ns
65   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;//斷路控制使能
66   //當BKIN引腳--PB12檢測到高電平時,輸出比較信號被禁止,就好像是剎車一樣
67   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;//斷路輸入極性-高電平
68   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自動輸出使能
69   TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
70     
71     
72   TIM_Cmd(TIM1, ENABLE);//計數使能
73   TIM_CtrlPWMOutputs(TIM1, ENABLE);//主輸出使能,當使用的是通用定時器時,這句話不要
74 
75 }

 

輸出捕獲實驗:

  1 /*******************************************************************
  2   *@使用TIM5的輸入捕獲功能進行按鍵按下的時間---高電平的時間(按鍵下拉)
  3   *@輸入捕獲引腳--PA0  5   *@注意:這里的溢出中斷和捕獲中斷屬於不同的兩個中斷
  8 *******************************************************************/
  9 
 10 
 11 //定時器輸入捕獲用戶自定義變量結構體聲明
 12 typedef struct 
 13 {
 14    u8  Capture_FinishFlag;  //捕獲結束標志位
 15    u8  Capture_StartFlag;  //捕獲開始標志位
 16    u16 Capture_CcrValue; //捕獲寄存器的值
 17    u16 Capture_Period;   //自動重裝載寄存器更新標志
 18 }TIM_ICUserValueTypeDef;
 20 TIM_ICUserValueTypeDef  TIM_ICUserValueStructure;//結構體初始化
 21 
 22 void GET_PluseWidth(void)
 23 {
 24   GPIO_InitTypeDef          GPIO_InitStructure;
 25   TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
 26   TIM_ICInitTypeDef         TIM_ICInitStructure;
 27   NVIC_InitTypeDef          NVIC_InitStructure;
 28     
 29     //RCC configuration
 30     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 31     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
 32     
 33     //GPIO configuration
 34     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
 35     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入模式
 36     GPIO_Init(GPIOA, &GPIO_InitStructure);   //GPIOA
 37     
 38     
 39      //值得注意的是input capture period(1us*(65535+1)=65.536ms) > 捕獲脈寬的時間,當小於時會溢出,需額外處理
 40     TIM_TimeBaseStructure.TIM_Prescaler = 72-1;   //預分頻 --1MHZ來驅動
 41     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數模式
 42     TIM_TimeBaseStructure.TIM_Period =0xFFFF;     //TimerPeriod;    //ARR 
 43     TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //定時器濾波,通常為0
 44     TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//配置寄存器TIM_RCR(重復次數寄存器) 
 45     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 46     
 47     //中斷優先級配置
 48     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
 49     NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
 50     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
 51     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //響應優先級
 52     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 53     NVIC_Init(&NVIC_InitStructure);
 54     
 55     
 56   TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//輸入捕獲的通道,由具體的GPIO來配置
 57   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//捕獲信號極性配置
 58   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//輸入通道與捕獲通道的映射關系,有直連和非直連
 59   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//輸入的需要被捕獲的信號的分頻系數
 60   TIM_ICInitStructure.TIM_ICFilter = 0x0;//輸入的需要被捕獲的信號的濾波系數
 61   TIM_ICInit(TIM5, &TIM_ICInitStructure);
 62     
 63   TIM_ClearFlag(TIM5, TIM_FLAG_Update|TIM_FLAG_CC1);//清除TIM5的更新標志位和捕獲標志位
 64   TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1, ENABLE);//開啟更新中斷和捕獲中斷
 65     
 66   TIM_Cmd(TIM5, ENABLE);
 67 }
 68 
 69 //中斷服務函數
 70 void TIM5_IRQHandler(void)
 71 {
 72      //被捕獲的信號周期大於定時器的最長定時時,定時器就會溢出,產生更新中斷
 73      //特殊處理;把這個最長的定時周期加到捕獲信號的時間里面去
 74    if(TIM_GetITStatus(TIM5,TIM_IT_Updata) != RESET)//產生中斷
 75      {
 76        TIM_ICUserValueStructure.Capture_Period ++;
 77      TIM_ClearITPendingBit(TIM5,TIM_FLAG_Update);        //清中斷標志位 
 78      }
 79      
 80      //第一次捕獲中斷
 81      if(TIM_GetITStatus(TIM5,TIM_IT_CC1)!=RESET)//產生捕獲中斷
 82      {
 83         if(TIM_ICUserValueStructure.Capture_StartFlag ==0)
 84             {
 85               TIM_SetCounter(TIM5,0);//計數器清0
 86                 TIM_ICUserValueStructure.Capture_Period =0;//自動重裝載寄存器更新標志清零
 87                 TIM_ICUserValueStructure.Capture_CcrValue =0;//捕獲比較寄存器的值的變量清0
 88                 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//當第一次捕獲到上升沿時,就把捕獲邊沿配置為下降沿
 89                 TIM_ICUserValueStructure.Capture_StartFlag =1; //開始捕獲標志位置1
 90             }
 91             else//第二次捕獲
 92             {
 93                 //獲取捕獲比較寄存器的值,這個值就是捕獲到的高電平的時間的值
 94               TIM_ICUserValueStructure.Capture_CcrValue =TIM_GetCapture1(TIM5);
 95                 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising);//當第二次捕獲到下降沿時,就把捕獲邊沿配置為上升沿,進行新一輪捕獲
 96               TIM_ICUserValueStructure.Capture_StartFlag =0;//開始捕獲標志位置0
 97                 TIM_ICUserValueStructure.Capture_FinishFlag =1;//捕獲完成標志位置1
 98             }
 99               TIM_ClearITPendingBit(TIM5,TIM_IT_CC1);        //清中斷標志位 
100      }
101 }

main:

 1 int main(void)
 2 {
 3     u32 time;
 4     u32 TIM_Psclk =72000000/72;
 5     Usart_init();//初始化串口
 6     GET_PluseWidth();//初始化定時器5
 7     
 8     while(1)
 9     {
10       if(TIM_ICUserValueStructure.Capture_FinishFlag ==1)
11         {
12           time = TIM_ICUserValueStructure.Capture_Period *(0xFFFF+1) + (TIM_ICUserValueStructure.Capture_CcrValue +1);//計算高電平的計數器值
13           printf("測得按下的時間:%d.%d\n",time/TIM_Psclk,time%Psclk);//打印高電平脈寬時間
14             
15             TIM_ICUserValueStructure.Capture_FinishFlag =0;
16         }
17     }
19 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM