一、定時器1概述html
定時器1 是一個支持典型的定時/計數功能的獨立16 位定時器,支持輸入捕獲,輸出比較和PWM等功能。定時器有五個獨立的捕獲/比較通道。每一個通道定時器要使用一個I/O 引腳。定時器用於範圍普遍的控制和測量應用,可用的五個通道的正計數/倒計數模式將容許諸如電機控制應用的實現。數據庫
定時器1 的功能以下:數組
• 五個捕獲/比較通道
• 上升沿、降低沿或任何邊沿的輸入捕獲
• 設置、清除或切換輸出比較
• 自由運行、模或正計數/倒計數操做
• 可被1,8,32 或128 整除的時鐘分頻器
• 在每一個捕獲/比較和最終計數上生成中斷請求
• DMA 觸發功能函數
二、16 位計數器post
【關於分頻,時鐘】定時器包括一個16 位計數器,在每一個活動時鐘邊沿遞增或遞減。活動時鐘邊沿週期由寄存器位CLKCON.TICKSPD定義,它設置全球系統時鐘的劃分,提供了從0.25MHz 到32MHz 的不一樣的時鐘標籤頻率(可使用32 MHz XOSC 做爲時鐘源)。這在定時器1 中由T1CTL.DIV設置的分頻器值進一步劃分。這個分頻器值能夠從一、八、32 或128。所以當32 MHz 晶振用做系統時鐘源時,定時器1 可使用的最低時鐘頻率是1953.125Hz,最高是32 MHz。當16MHz RC 振盪器用做系統時鐘源時,定時器1 可使用的最高時鐘頻率是16MHz。學習
【讀取定時器當前值】計數器能夠做爲一個自由運行計數器,一個模計數器或一個正計數/倒計數器運行,用於中心對齊的PWM。能夠經過兩個8 位的SFR 讀取16 位的計數器值:T1CNTH 和T1CNTL,分別包含在高位字節和低位字節中。當讀取T1CNTL 時,計數器的高位字節在那時被緩衝到T1CNTH,以便高位字節能夠從T1CNTH 中讀出。所以!!!T1CNTL 必須老是在讀取T1CNTH 以前首先讀取。對T1CNTL 寄存器的全部寫入訪問將復位16 位計數器。當達到最終計數值(溢出)時,計數器產生一箇中斷請求。ui
【控制定時器】能夠用T1CTL 控制寄存器設置啓動並中止該計數器。當一個不是00 值的寫入到T1CTL.MODE 時,計數器開始運行。若是00 寫入到T1CTL.MODE,計數器中止在它如今的值上。url
三、定時器1 操做spa
通常來講控制寄存器T1CTL 用於控制定時器操做。狀態寄存器T1STAT 保存中斷標誌。各類操做模式以下所述。3d
四、自由運行模式
在自由運行操做模式下,計數器從0x0000 開始,每一個活動時鐘邊沿增長1。當計數器達到0xFFFF(溢出),計數器載入0x0000,繼續遞增它的值,如圖1 所示。當達到最終計數值0xFFFF,設置標誌IRCON.T1IF 和T1STAT.OVFIF。若是設置了相應的中斷屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,將產生一箇中斷請求。自由運行模式能夠用於產生獨立的時間間隔,輸出信號頻率。(0xFFFF型)
圖1 自由運行模式
五、模模式
當定時器運行在模模式,16 位計數器從0x0000 開始,每一個活動時鐘邊沿增長1。當計數器達到T1CC0(溢出),寄存器T1CC0H:T1CC0L 保存的最終計數值,計數器將復位到0x0000,並繼續遞增。若是定時器開始於T1CC0 以上的一個值,當達到最終計數值(0xFFFF)時,設置標誌IRCON.T1IF 和T1CTL.OVFIF。若是設置了相應的中斷屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,將產生一箇中斷請求。模模式能夠用於週期不是0xFFFF的應用程序。計數器的操做展現在圖2 中。(自定義上限型)
圖2 模模式
六、正計數/倒計數模式
在正計數/倒計數模式,計數器反覆從0x0000 開始,正計數直到達到T1CC0H:T1CC0L 保存的值。而後計數器將倒計數直到0x0000,如圖3 所示。這個定時器用於週期必須是對稱輸出脈衝而不是0xFFFF 的應用程序,所以容許中心對齊的PWM 輸出應用的實現。在正計數/倒計數模式,當達到最終計數值時,設置標誌IRCON.T1IF 和T1CTL.OVFIF。若是設置了相應的中斷屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,將產生一箇中斷請求。(增減交替型)
圖3 正計數/倒計數模式
七、通道模式控制
通道模式隨着每一個通道的控制和狀態寄存器T1CCTLn 設置。設置包括輸入捕獲和輸出比較模式。
八、 輸入捕獲模式
當一個通道配置爲輸入捕獲通道,和該通道相關的I/O 引腳必須被配置爲輸入。(什麼是輸入捕獲模式,運做機制)在啓動定時器以後,輸入引腳的一個上升沿、降低沿或任何邊沿都將觸發一個捕獲,即把16 位計數器內容捕獲到相關的捕獲寄存器中。所以定時器能夠捕獲一個外部事件發生的時間。(捕獲外部事件發生時間)
注意:在定時器可使用一個輸入/輸出引腳以前,所需的I/O 引腳必須配置爲定時器1 的外設引腳。通道輸入引腳和內部系統時鐘是同步的。所以輸入引腳上的脈衝的最低持續時間必須大於系統時鐘週期。
16 位捕獲寄存器的內容從寄存器T1CCnH:T1CCnL 中讀出。當捕獲發生時,要設置IRCON.T1IF 標誌和該通道的中斷標誌T1STAT.CHnIF(n 是通道號碼)。若是分別設置了相應的中斷屏蔽位T1CCTLn.IM,以及IEN1.T1EN,將產生一箇中斷請求。
九、輸出比較模式(最難理解的一個,下面的邊沿對其和中心對其實際上是基於輸出比較的運做核心,用上面講的幾種簡單的模式實現PWM,中心對齊是利用模模模式實現的)
在輸出比較模式中,與通道相關的IO要設置爲輸出模式。(什麼是輸出比較模式,運做機制)在定時器啓動後, 計數器的內容會和通道比較寄存器中的內容T1CCnH:T1CCnL作比較。若是這兩個內容(值)相等,輸出引腳根據比較輸出模式T1CCTLn.CMP的設置進行設置、復位或切換。(核心就是將T1CC0的值和每一個通道寄存器中的值比較,相等了則產生中斷等)
注意:輸出引腳運行在一個給定輸出比較模式下時,它上面的全部邊沿都是無端障運行的。
寫入比較寄存器T1CCnL 將被緩衝,這樣寫入到T1CCnL 的值不起做用,直到相應的高位寄存器T1CCnH 被寫入。寫入比較寄存器T1CCnH:T1CCnL 對於輸出比較值不起做用,直到定時器達到0x00。
注意:通道0 的輸出比較模式較少,由於T1CC0H:T1CC0L 在模式6 和7 有一個特殊功能,這意味着這些模式對於通道0 是不能使用的。
當發生一個比較時,設置IRCON.T1IF 標誌和該通道的中斷標誌T1STAT.CHnIF(n 是通道號碼)。若是分別設置了相應的中斷屏蔽位T1CCTLn.IM,以及IEN1.T1EN,將產生一箇中斷請求。
不一樣定時器模式下輸出比較模式的例子給定在如下圖中。
邊沿對齊:PWM 輸出信號可使用定時器在自由運行模式下,通道1 和2 在輸出比較模式6 或7(第6和第7條線)下生成(由T1CCTLn.CMP 位定義,其中n 是1 或2),如圖4 所示。PWM 信號的週期經過設置T1CC0 肯定,通道輸出的佔空比由T1CCn 肯定,其中n 是PWM 通道1 或2。也可使用定時器自由運行模式。在這種狀況下,T1CTL.DIV 位中的CLKCON.TICKSPD 和分頻器值設置PWM 信號的週期。PWM 信號的極性由使用的是輸出比較模式6 仍是7 肯定。PWM 輸出信號還可使用圖4 所示的輸出比較模式4 和5,或經過使用圖5 所示的模模式生成。對於簡單的PWM,最好使用使用輸出比較模式4 和5 來生成。
圖4 輸出比較模式,定時器自由運行模式
圖中0、一、2...6是7種模式,左邊的波形對應每種模式
圖5 輸出比較模式,定時器模模式
中心對齊:PWM 輸出能夠經過選擇定時器正計數/倒計數模式生成。根據PWM 信號所需的極性選擇通道輸出比較模式4 或5(由T1CCTLn.CMP 位定義,其中n 是1 或2)。PWM 信號的週期由T1CC0 肯定,通道輸出的佔空比由T1CCn 肯定,其中n 是PWM 通道1 或2。某些類型的電機驅動應用程序會須要中心對齊的PWM 模式,通常地這比邊沿對齊的PWM 模式產生的噪音更少,由於I/O 引腳傳輸不集中在同一個時鐘邊沿上。
圖6 輸出比較模式,定時器正計數/倒計數模式
(附加小姿式)在一些類型的應用程序中,須要在輸出之間定義一個延遲或死亡的時間。典型地,這用於輸出驅動一個H橋配置,以免H 橋的一邊交叉傳導失控。延遲或死亡時間能夠經過使用T1CCn 在PWM 輸出中得到,以下所示:
假定通道1 和通道2 使用定時器正計數/倒計數模式,用於驅動輸出,且這兩個通道分別使用輸出比較模式4 和5,那麼定時器週期(定時器1 的時鐘週期)是:
tP = T1CC0 x 2
死亡時間,即兩個輸出都爲低電平的時間,(定時器1 的時鐘週期)是:
tD = T1CC1 – T1CC2
當下列狀況發生,比較輸出引腳初始化爲表9-1 所列的值:
一個值被寫入T1CNTL(全部定時器1 通道)
0x7 被寫到T1CCTLn.CMP(通道n)
表9-1 初始的比較輸出值(比較模式)
十、IR 信號產生和線性化 (*)
本節描述了CC253x 設備只需最少的SW 參與便可產生IR 的功能。
10.一、簡介(*)
爲遠程控制產生IR 信號通常如下面兩種方式之一完成:
調製碼
非調製碼(C 碼,閃存代碼)
CC253x 包括靈活的定時器功能,以最少的CPU 參與,來執行這兩種類型的IR 信號的產生和線性化。大多數IR 協議每一個命令只需一個CPU 干預便可實現。
10.二、調製碼(*)
調製碼可使用定時器1(16 位)和定時器3(8 位)生成。處於調製模式的定時器3 用於產生載波。定時器3 有一個單獨的分頻器,用於它的輸入。它的週期使用T3CC0 設置。定時器3 通道1 用於PWM 輸出。載波的佔空比使用T3CC1 設置。通道1 使用比較模式:「在比較設置輸出,在0xFF 清除」(T3CCTL1.CMP = 101)。
表9-2 顯示了定時器3 的38kHz 載波的頻率偏差計算。(用定時器3產生載波)
38kHz 載波的頻率偏差計算
IRCTL.IRGEN 寄存器位使得IR 產生模式處於定時器1。當設置了IRGEN 位,定時器1採用定時器3通道1的輸出比較信號做爲標記,而不是採用系統標記。定時器1週期是使用T1CC0 設置的,定時器1處於調製模式(T1CTL.MODE = 10),通道0處於比較模式(T1CCTL0.MODE = 1)。通道1比較模式「在比較設置輸出,在0x0000 清除」(T1CCTL1.CMP = 011)用於輸出門控信號。
標記載波的個數由T1CC1. T1CC1 設置,須要每一個定時器1 週期由DMA 或CPU 更新一次。注意T1CC1的一個更新被緩衝,在定時器1 達到0x0000 以前不起做用。
空間載波的個數由T1CC0 設置。其值必須設置爲標記和空間載波週期但願的總數。比較值被緩衝直到定時器達到0x0000。
定時器1 通道1 的輸出進行定時器3 通道1 的輸出和運算,做爲IR 的輸出,如圖。
圖7 定時器在IR 產生模式的方框圖
定時器3 通道1 輸出和定時器1 通道1 輸出信號的時序是同步的,這樣在IR 輸出信號上就沒有故障。當設置了IRGEN 位,IR 輸出信號被送到引腳,而不是送到通常的定時器1 通道1 輸出。下圖顯示了定時器3 被初始化爲33%的佔空比(T3CC0 = 3× T3CC1)的例子。定時器1 已經被初始化爲3。(若是僅僅要實現一個空間週期,T1CC1 必須設置爲0x00。)
圖8 調製的波形示例
10.3 非調製碼(*)
要產生非調製IR 碼,定時器1 要處於模模式。信號的週期由T1CC0 給定,脈衝寬度由T1CC1 給定。T1CC1給出標記週期的長度,T1CC0 給出標記和空間週期的總數。比較值被緩衝,直到定時器達到0x0000。若是比較值不能保持不變,必須在每一個週期由DMA 或CPU 更新。
10.4 學習(*)
學習經過使用定時器1(16 位)和定時器3(8 位)的捕獲功能完成。定時器3 能夠處理載波頻率檢測,定時器1 能夠處理調製信代碼的學習。電路應該按照圖9 所述安裝。
圖9 IR 學習的方框圖
10.4.1 載波頻率檢測(*)
定時器3 用於捕獲和檢測直接從IR 引腳二極管輸入的載波頻率。定時器必須對載波進行必定次數的採樣。若是載波被檢測,被檢測出的頻率必須提供平均數,這會存儲在數據庫中。
10.4.2 解調碼學習(*)
IR 引腳二極管的輸出由一個合適的電路解調。這一電路的輸出用做處於捕獲模式的定時器1 其中一個通道的輸入。
10.5 其餘注意事項(*)
IR 輸出引腳在復位期間必須處於三態或下拉狀態,以免點亮IR LED 這一沒必要要的功耗。注意只有定時器1 通道1 的輸出P1.1 是三態的,在復位期間和復位後沒有上拉。
十一、定時器1 中斷
爲定時器分配了一箇中斷向量。當下列定時器事件之一發生時,將產生一箇中斷請求:
● 計數器達到最終計數值(溢出或回到零)
● 輸入捕獲事件
● 輸出比較事件
寄存器狀態寄存器T1STAT 包括最終計數值事件和五個通道比較/捕獲事件的中斷標誌。僅當設置了相應的中斷屏蔽位和IEN1.T1EN 時,才能產生一箇中斷請求。中斷屏蔽位是n 個通道的T1CCTLn.IM 和溢出事件TIMIF.OVFIM。若是有其它未決中斷,必須在一個新的中斷請求產生以前,經過軟件清除相應的中斷標誌。並且,若是設置了相應的中斷標誌,使能一箇中斷屏蔽位將產生一個新的中斷請求。
十二、定時器1 DMA 觸發
有三種DMA 觸發與定時器1 有關。這些是DMA 觸發T1_CH0,T1_CH1 和T1_CH2,分別在如下定時器比較事件上產生:
● T1_CH0 – 通道0 比較
● T1_CH1 – 通道1 比較
● T1_CH2 – 通道2 比較
通道3 和4 沒有相關的觸發。
1三、定時器1 寄存器
本節描述了定時器1 的寄存器,由如下寄存器組成:
● T1CNTH – 定時器1 計數高位
● T1CNTL – 定時器1 計數低位
● T1CTL – 定時器1 控制
● T1STAT –定時器1 狀態
● T1CCTLn – 定時器1 通道n 捕獲/比較控制
● T1CCnH – 定時器1 通道n 捕獲/比較高位值
● T1CCnL – 定時器1 通道n 捕獲/比較低位值
TIMIF.OVFIM 寄存器位駐留在TIMIF 寄存器,和定時器3 和定時器4 寄存器一塊兒描述。
1四、做爲數組訪問定時器1 寄存器
定時器1 捕獲/比較通道寄存器能夠在XDATA 存儲空間中做爲一個連續的區域被訪問。這使得能夠做爲一個簡單的索引結構方便地訪問寄存器。5 個捕獲/比較控制寄存器映射到0x62A0 - 0x62A4。16 位捕獲/比較值映射到0x62A6 - 0x62AF。0x62A5 不使用。
1五、代碼示例
15.一、定時器輪訓方式
下面代碼展現了經過設置定時器1計數來控制LED閃爍,這裏沒有采用中斷方式,而是採用普通的輪訓。關於LED的初始化我在前幾節已經介紹了。這裏重點看和定時器1相關的部分:
① 第33行將T1CTL設置爲0x0d=0000 1101,參考下面寄存器表可知是經過設置定時器1的控制和狀態寄存器來將定時器設置爲:128分頻,自由運行,從0x0000到0xFFFF反覆計數。因爲系統在沒配置工做頻率時默認是2分頻,即32MHz/2=16MHz,所以定時器每次溢出的時間T=1/(16MHz/128)*65536=0.524s
② 第34行將T1STAT設置爲0x21=0010 0001,參考下面的寄存器表知爲使用定時器1的通道0,且中斷有效。
③ 在49行一旦IRCON>0代表發生了某個中斷,在該例程中咱們僅僅用了TIMER1的中斷,所以代表TIMER1中斷髮生:
所以下面整個程序實現的功能是:利用定時器1的通道0產生0.524s的週期性中斷,每次發生中斷系統會自動置IRCON的第1位爲1,在main函數的輪訓中一旦檢測到該信息,則讓計數變量count加1,一旦count計數大於1時,就讓LED狀態翻轉,實現1SLED閃爍控制。
1 /**************************************************************************** 2 * 文 件 名: main.c 3 * 版 本: 1.0 4 * 描 述: 定時器T1經過查詢方式控制LED1週期性閃爍 5 ****************************************************************************/ 6 #include <ioCC2530.h> 7 8 typedef unsigned char uchar; 9 typedef unsigned int uint; 10 11 #define LED1 P1_0 // P1.0口控制LED1 12 13 /**************************************************************************** 14 * 名 稱: InitLed() 15 * 功 能: 設置LED燈相應的IO口 16 * 入口參數: 無 17 * 出口參數: 無 18 ****************************************************************************/ 19 void InitLed(void) 20 { 21 P1DIR |= 0x01; //P1.0定義爲輸出 22 LED1 = 1; //使LED1燈上電默認爲熄滅 23 } 24 25 /**************************************************************************** 26 * 名 稱: InitT1() 27 * 功 能: 定時器初始化,系統不配置工做時鐘時默認是2分頻,即16MHz 28 * 入口參數: 無 29 * 出口參數: 無 30 ****************************************************************************/ 31 void InitT1() 32 { 33 T1CTL = 0x0d; //128分頻,自動重裝 0x0000-0xFFFF 34 T1STAT= 0x21; //通道0,中斷有效 35 } 36 37 /**************************************************************************** 38 * 程序入口函數 39 ****************************************************************************/ 40 void main(void) 41 { 42 uchar count=0; 43 44 InitLed(); //調用初始化函數 45 InitT1(); 46 47 while(1) 48 { 49 if(IRCON > 0) 50 { 51 IRCON=0; 52 if(count++ >= 1) //約1s週期性閃爍,示波器測大約爲1025MS 53 { 54 count=0; 55 LED1 = !LED1; //LED1閃爍 56 } 57 } 58 } 59 }
15.二、定時器中斷方式
上面採用輪訓的方法是比較佔資源的,相似咱們按鍵那節中介紹的,除了輪訓咱們還能夠用中斷方式!在黃色初始化部分比採用輪訓方式多了使能T1中斷和總中斷的部分(3五、36行代碼)。我以前沒有加這兩句代碼,結果橙色部分的定時器1中斷回調函數沒法被觸發!查datasheet發現Interrupt Overview:若是想觸發回調函數,須要將EA開關和T1IE開關打開才行!
1 /**************************************************************************** 2 * 文 件 名: main.c 3 * 版 本: 1.0 4 * 描 述: 定時器T1經過查詢方式控制LED1週期性閃爍 5 ****************************************************************************/ 6 #include <ioCC2530.h> 7 8 typedef unsigned char uchar; 9 typedef unsigned int uint; 10 11 #define LED1 P1_0 // P1.0口控制LED1 12 13 /**************************************************************************** 14 * 名 稱: InitLed() 15 * 功 能: 設置LED燈相應的IO口 16 * 入口參數: 無 17 * 出口參數: 無 18 ****************************************************************************/ 19 void InitLed(void) 20 { 21 P1DIR |= 0x01; //P1.0定義爲輸出 22 LED1 = 1; //使LED1燈上電默認爲熄滅 23 } 24 25 /**************************************************************************** 26 * 名 稱: InitT1() 27 * 功 能: 定時器初始化,系統不配置工做時鐘時默認是2分頻,即16MHz 28 * 入口參數: 無 29 * 出口參數: 無 30 ****************************************************************************/ 31 void InitT1() 32 { 33 T1CTL = 0x0d; //128分頻,自動重裝 0x0000-0xFFFF 34 T1STAT= 0x21; //通道0,中斷有效 35 T1IE = 1; //開總中斷和T1中斷 36 EA = 1; //開總中斷 37 } 38 39 //定時器T1中斷處理函數 40 #pragma vector = T1_VECTOR 41 __interrupt void T1_ISR(void) 42 { 43 static uchar count=0; 44 IRCON = 0x00; //清中斷標誌, 也可由硬件自動完成 45 if(count++ >= 1) //約1s週期性閃爍,示波器測大約爲1025MS 46 { 47 count=0; 48 LED1 = !LED1; //LED1閃爍 49 } 50 } 51 52 /**************************************************************************** 53 * 程序入口函數 54 ****************************************************************************/ 55 void main(void) 56 { 57 InitLed(); //調用初始化函數 58 InitT1(); 59 60 while(1){} 61 }
Zigbee系列文章:
[ZigBee] 三、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅
PS:若是您以爲還不錯,點個贊,讓更多人受益~
@beautifulzzzz 2016-07-13 continue~
e-mail:beautifulzzzz@qq.com
sina:http://weibo.com/beautifulzzzz?is_all=1