- 面向物聯網的CC2530與傳感器應用開發
- 廖建尚編著
- 6271字
- 2019-07-25 11:50:33
任務6 電子秒表的設計與實現
本任務重點學習微處理器的定時/計數器,掌握CC2530定時/計數器的基本原理、功能和驅動方法,通過驅動CC2530的定時/計數器來實現秒表計時。
6.1 開發場景:如何實現電子秒表
在競技類體育運動中,裁判員通常使用電子秒表來為運動員計時。打開多個手機,都調節到秒表部分,同時開始計時,在經過相同的時間段后,停止秒表,會發現各個手機上所計時間相同。為什么電子秒表的計時可信?為什么不同手機之間能做到同樣時間內統計的時間是相同的?這是因為每個電子設備都使用了定時器來作為時間計時的時基。定時器通過精確的時鐘來為秒表提供精確而穩定的時間,本項目將圍繞這個場景展開微處理器定時/計數器的學習與實踐。電子秒表如圖6.1所示。

圖6.1 電子秒表
6.2 開發目標
(1)知識要點:定時/計數器的工作原理。
(2)技能要點:掌握定時/計數器的基本原理;會使用CC2530微處理器定時/計數器。
(3)任務目標:使用CC2530微處理器模擬表/計數功能,通過編程使用CC2530微處理器的定時/計數器每秒產生一次脈沖信號,通過I/O接口連接信號燈的閃爍來表示定時/計數器秒脈沖的產生,同時使用模擬延時來比較定時1 s與延時1 s的準確性。
6.3 原理學習:定時/計數器
6.3.1 定時/計數器
定時/計數器是一種能夠對時鐘信號或外部輸入信號進行計數的器件,當計數值達到設定要求時便向微處理器提出中斷請求,從而實現定時或計數的功能。
定時/計數器的基本功能是定時和計數,且在整個工作過程中不需要微處理器進行過多參與,它將微處理器從相關任務中解放出來,提高了微處理器的使用效率。例如,任務4中實現信號燈控制采用的是軟件延時方法,在延時過程中微處理器通過執行循環指令來消耗時間,在整個延時過程中會一直占用微處理器,降低了微處理器的工作效率。若使用定時/計數器來實現延時,則在延時過程中微處理器可以去執行其他工作任務。微處理器與定時/計數器之間的交互關系如圖6.2所示。

圖6.2 微處理器與定時/計數器之間的交互關系
1.微處理器中的定時/計數器功能
定時/計數器包含三個功能,分別是定時器功能、計數器功能和脈沖寬度調制(Pulse Width Modulation, PWM)輸出功能,具體如下。
(1)定時器功能:對規定時間間隔的輸入信號的個數進行計數,當計數值達到指定值時,說明定時時間已到。這是定時/計數器的常用功能,可用來實現延時或定時控制,其輸入信號一般是微處理器內部的時鐘信號。
(2)計數器功能:對任意時間間隔的輸入信號的個數進行計數,一般用來對外界事件進行計數,其輸入信號一般來自微處理器外部的開關型傳感器,可用于生產線產品計數、信號數量統計和轉速測量等方面。
(3)PWM輸出功能:對規定時間間隔的輸入信號的個數進行計數,根據設定的周期和占空比從I/O口輸出控制信號,一般用來控制LED亮度或電機轉速。
2.定時/計數器基本工作原理
無論使用定時/計數器的哪種功能,其最基本的工作原理是進行計數。定時/計數器的核心是一個計數器,可以進行加1(或減1)計數,每出現一個計數信號,計數器就自動加1(或自動減1),當計數值從最大值變成0(或從0變成最大值)溢出時,定時/計數器便向微處理器提出中斷請求。計數信號的來源可以是周期性的內部時鐘信號(如定時功能)或非周期性的外界輸入信號(如計數功能)。
6.3.2 CC2530與定時器
1.CC2530定時器概述
CC2530一共有4個定時器,分別是定時器1、定時器2、定時器3和定時器4。這4個定時器根據硬件特性可分為三類,分別是16位定時器(定時器1)、MAC定時器(定時器2)、8位定時器(定時器3和定時器4),下面詳細介紹每類定時器的特性。
(1)定時器1。定時器1是一個獨立的16位定時器,支持輸入捕獲、輸出比較和PWM輸出功能。定時器有5個獨立的捕獲/比較通道,每個通道定時器使用一個I/O引腳。定時器廣泛用于控制和測量領域,5個通道的正計數/倒計數模式可應用于諸如電機控制場合。定時器1的功能如下:
● 5個捕獲/比較通道;
● 上升沿、下降沿或任何邊沿的輸入捕獲;
● 設置、清除或切換輸出比較;
● 自由運行、?;蛘嫈?倒計數操作;
● 可作為被1、8、32或128整除的時鐘分頻器;
● 在每個捕獲/比較和最終計數時生成中斷請求;
● DMA觸發功能。
(2)定時器2。定時器2主要用于為IEEE 802.15.4 CSMA-CA算法提供定時,以及為IEEE 802.15.4 MAC層提供一般的計時功能。當定時器2和睡眠定時器一起使用時,即使系統進入低功耗模式也會提供定時功能,定時器運行在CLKCONSTA.CLKSPD指定的速度上,如果定時器2和睡眠定時器一起使用,時鐘速度必須設置為32 MHz,且必須使用一個頻率為32 kHz的外部晶體振蕩器(簡稱晶振)獲得精確的結果。定時器2的主要特性如下:
● 16位定時器提供正計數功能,如16 μs、32 μs的符號/幀周期;
● 可變周期可精確到31.25 ns;
● 2×16位定時器比較功能;
● 24位溢出計數;
● 2×24位溢出計數比較功能;
● 幀首定界符捕獲功能;
● 定時器啟動/停止與外部32 kHz時鐘同步,或由睡眠定時器提供定時;
● 比較和溢出時會產生中斷;
● 具有DMA觸發功能;
● 通過引入延遲可調整定時器值。
(3)定時器3與定時器4。定時器3和定時器4是2個8位的定時器,每個定時器有2個獨立的捕獲/比較通道,每個通道使用一個I/O引腳。定時器3和定時器4的特性如下:
● 2個捕獲/比較通道;
● 可設置、清除或切換輸出比較;
● 時鐘分頻器,可以被1、2、4、8、16、32、64、128整除;
● 在每次捕獲/比較和最終計數事件發生時會產生中斷請求;
● DMA觸發功能。
通常情況下,在沒有使用到CC2530的射頻部分的模塊時,基本上不會用到定時器2,而定時器1可以理解為定時器3與定時器4的增強版,因此本任務著重對定時器1進行詳細分析。
2.CC2530定時器1
定時器1的16位計數器計數值的大小會在每個活動時鐘邊沿遞增或遞減,活動時鐘邊沿周期由寄存器位CLKCON.TICKSPD定義,它設置了全球系統時鐘的劃分,提供了0.25~32 MHz不同的時鐘頻率(可以使用32 MHz的XOSC作為時鐘源)。在定時器1中,由T1CTL.DIV對分頻器值進一步劃分,分頻器系數可以為1、8、32或128。因此,當使用32 MHz晶振作為系統時鐘源時,定時器1可以使用的最低時鐘頻率是1953.125 Hz,最高時鐘頻率是32 MHz;當使用16 MHz的RC振蕩器作為系統時鐘源時,定時器1可以使用的最高時鐘頻率是16 MHz。
定時器1的計數器可以作為一個自由運行計數器、一個模計數器或一個正計數/倒計數器,以及用于中心對齊的PWM輸出。
定時器1在獲取計數器值時可以通過2個8位的SFR讀取16位的計數器值,分別是T1CNTH和T1CNTL,這兩個寄存器存儲的計數器值分別表示計數器數值的高位字節和低位字節。當讀取T1CNTL時,計數器的高位字節被緩沖到T1CNTH,以便高位字節從T1CNTH中讀出,因此T1CNTL需要提前從T1CNTH讀取。
對T1CNTL寄存器的所有寫入內容進行訪問操作時,將復位16位計數器,當達到最終計數值(溢出)時,計數器將產生一個中斷請求??梢杂肨1CTL控制寄存器設置啟動或者停止該計數器,當向T1CTL.MODE寫入01、10或11時,計數器開始運行;如果向T1CTL.MODE寫入00時,計數器將停止運行但計數值不會被清空。
3.CC2530定時器1的計數模式
CC2530定時器1擁有三種不同的計數模式,分別是自由運行模式、模模式、正計數/倒計數模式。自由運行模式適合產生獨立的時間間隔,輸出信號的頻率;模模式適合周期不是0xFFFF的應用程序;正計數/倒計數模式適合周期必須是對稱輸出脈沖而不是固定值的應用程序。
(1)自由運行模式。計數器從0x0000開始,在每個活動時鐘邊沿增加1,當計數器達到0xFFFF(溢出)時,計數器載入0x0000,繼續遞增,如圖6.3所示;當達到最終計數值0xFFFF時,將設置標志IRCON.T1IF和T1STAT.OVFIF。如果設置了相應的中斷屏蔽位TIMIF.OVFIM和IEN1.T1EN,將產生一個中斷請求。

圖6.3 自由運行模式
(2)模模式。16位計數器從0x0000開始,在每個活動時鐘邊沿增加1,當計數器達到T1CC0(溢出)時,寄存器T1CC0H:T1CC0L保存的最終計數值,計數器將復位到0x0000,并繼續遞增。如果定時器開始于T1CC0以上的一個值,當達到最終計數值(0xFFFF)時,將設置標志IRCON.T1IF和T1CTL.OVFIF。如果設置了相應的中斷屏蔽位TIMIF.OVFIM及IEN1.T1EN,將產生一個中斷請求,模模式可以用于周期不是0xFFFF的應用程序,如圖6.4所示。

圖6.4 模模式
(3)正計數/倒計數模式。計數器反復從0x0000開始,當正計數直到達到T1CC0時保存的值,然后計數器將倒計數直到0x0000,如圖6.5所示。這個定時器用于周期必須是對稱的輸出脈沖,而不是0xFFFF的應用程序,因此允許用于中心對齊的PWM輸出應用。在正計數/倒計數模式,當達到最終計數值時,將設置標志IRCON.T1IF和T1CTL.OVFIF。如果設置了相應的中斷屏蔽位TIMIF.OVFIM及IEN1.T1EN,將產生一個中斷請求。

圖6.5 正計數/倒計數模式
比較三種模式可以看出,自由運行模式的溢出值為0xFFFF,不可變;其他兩種模式可通過對T1CC0賦值來精確控制定時器的溢出值。
4.CC2530定時器1中斷
CC2530為定時器分配了一個中斷矢量,當下列事件發生時,將產生一個中斷請求。
● 計數器達到最終計數值(溢出或回到0);
● 輸入捕獲事件;
● 輸出比較事件。
寄存器狀態寄存器T1STAT包括最終計數值事件和5個通道比較/捕獲事件的中斷標志。僅當設置了相應的中斷屏蔽位和IEN1.T1EN時,才能產生一個中斷請求。中斷屏蔽位是n個通道的T1CCTLn.IM和溢出事件TIMIF.OVFIM。如果有其他未決中斷,必須在一個新的中斷請求產生之前,通過軟件清除相應的中斷標志;而且如果設置了相應的中斷標志,使能一個中斷屏蔽位將產生一個新的中斷請求。
5.CC2530定時器1寄存器
定時器1是16位定時器,在時鐘上升沿或下降沿遞增或遞減,時鐘邊沿周期由寄存器CLKCON.TICKSPD定義,設置了系統時鐘的劃分,提供的頻率范圍為0.25~32 MHz。定時器1由T1CTL.DIV分頻器進一步分頻,分頻值為1、8、32或128;具有定時器/計數器/脈寬調制功能,它有3個單獨可編程輸入捕獲/輸出比較信道,每個信道都可以當成PWM輸出或捕獲輸入信號的邊沿時間。
CC2530定時器1的配置寄存器共7個,這7個寄存器分別是:T1CNTH(定時器1計數高位寄存器)、T1CNTL(定時器1計數低位寄存器)、T1CTL(定時器1控制寄存器)、T1STAT(定時器1狀態寄存器)、T1CCTLn(定時器1通道n捕獲/比較控制寄存器)、T1CCnH(定時器1通道n捕獲/比較高位值寄存器)、T1CCnL(定時器1通道n捕獲/比較低位值寄存器),其中T1CCTLn、T1CCnH、T1CCnL均有多個且結構相同,這里只介紹通道1。下面分析定時器1的每個寄存器的各個位的配置含義。
(1)T1CTL:定時器1控制寄存器,D1D0用于控制運行模式,D3D2用于設置分頻器劃分值,表6.1所示為T1CTL功能表。
表6.1 T1CTL功能表

(2)T1STAT:定時器1狀態寄存器,D4~D0為通道4~0的中斷標志,D5為溢出標志位,當計數到最終計數值時將自動置1,表6.2所示為T1STAT功能表。
表6.2 T1STAT功能表

(3)T1CCTL0:D1、D0為捕獲模式選擇:00為不捕獲,01為上升沿捕獲,10為下降沿捕獲,11為所有邊沿都捕獲;D2位為捕獲或比較的選擇,0為捕獲模式,1為比較模式。D5~D3為比較模式的選擇:000為發生比較式輸出端置1,001為發生比較時輸出端清0,010為比較時輸出翻轉,其他模式較少使用。T1CCTL0(定時器1通道0捕獲/比較控制寄存器)如表6.3所示。
表6.3 定時器1通道0捕獲/比較控制寄存器(T1CCTL0)

(4)T1CNTH(定時器1計數高位寄存器)如表6.4所示。
表6.4 定時器1計數高位寄存器

(5)T1CNTL(定時器1計數低位寄存器)如表6.5所示。
表6.5 定時器1計數低位寄存器

(7)T1CC0H(定時器1通道0捕獲/比較高位寄存器)如表6.6所示。
表6.6 定時器1通道0捕獲/比較高位寄存器

(8)T1CC0L(定時器1通道0捕獲/比較低位寄存器)如表6.7所示。
表6.7 定時器1通道0捕獲/比較低位寄存器

6.4 任務實踐:電子秒表的軟/硬件設計
6.4.1 開發設計
1.硬件設計
本任務的硬件架構設計如圖6.6所示。

圖6.6 硬件架構設計
使用CC2530微處理器定時器可以實現像秒表一樣實現精確的秒脈沖,CC2530微處理器秒脈沖信號的精確與否取決于定時器的配置。根據CC2530微處理器定時器的性質,定時器無法產生1 s以上的延時,要實現1 s的延時就需要產生一個穩定的延時,這個延時乘以一個倍數就等于1 s,因此可以配置一個10 ms的延時,然后循環計數100次即可產生一個脈沖控制信號以此實現1 s的精確延時。
定時計算公式為:

式中,最大值為M, N為計數值,初值為X, f為晶振頻率。
先配置定時器的工作模式為模模式,然后將系統時鐘(32 MHz)進行8分頻,8分頻后系統時鐘為4 MHz,要實現10 ms延時就需要在4 MHz的時鐘下計數40000次,即1/4000000×40000=0.001 s,然后設置每完成一個定時周期觸發一次中斷使循環計數加1,循環加100次就可以實現10 ms延時。
2.軟件設計
本任務程序設計思路如下。
(1)初始化系統時鐘、LED引腳和定時器。
(2)初始化完成后程序進入主循環。
(3)軟件延時1 s,對LED1的狀態進行取反。
(4)同時定時器每經過10 ms就產生一次中斷,并統計進入中斷的次數,當達到100次時,也就是10 ms×100=1 s時,執行LED2狀態的反轉操作并將次數清0,重新開始計數。
程序設計流程如圖6.7所示。

圖6.7 程序設計流程圖
6.4.2 功能實現
1.相關頭文件模塊
/**************************************************************************************** * 文件:led.h ****************************************************************************************/ #define D1 P1_1 //宏定義D1燈(即LED1)控制引腳P1_1 #define D2 P1_0 //宏定義D2燈(即LED2)控制引腳P1_0 #define ON 0 //宏定義打開狀態為ON #define OFF 1 //宏定義關閉狀態為OFF
2.主函數模塊
主函數在完成初始化系統時鐘、LED引腳和定時器后,進入主循環,通過軟件延時1 s控制LED1閃爍。主函數程序如下。
/**************************************************************************************** * 名稱:main() * 功能:主函數 ****************************************************************************************/ void main(void) { xtal_init(); //CC2530系統時鐘初始化 led_io_init(); //LED引腳初始化 time1_init(); //定時器1初始化 while(1){ delay_ss(1); //軟件延時1 s D1=! D1; //改變LED1的狀態 } }
3.系統時鐘初始化模塊
CC2530系統時鐘初始化源代碼如下。
/**************************************************************************************** * 名稱:xtal_init() * 功能:CC2530系統時鐘初始化 ****************************************************************************************/ void xtal_init(void) { CLKCONCMD&=~0x40; //選擇32 MHz的外部晶振 while(CLKCONSTA&0x40); //晶振開啟且穩定 CLKCONCMD&=~0x07; //選擇32 MHz系統時鐘 CLKCONCMD&=~0x38; //選擇32 MHz定時器時鐘 }
4.定時器初始化模塊
將定時器初始化為模模式,時鐘8分頻,重裝載寄存高位寫入0x90、低位寫入0x40,配置中斷模式,使能定時器中斷,開總中斷。定時器初始化源代碼如下。
/**************************************************************************************** * 名稱:time1_init() * 功能:定時器1初始化 ****************************************************************************************/ void time1_init(void) { T1CTL|=0x06; //8分頻,模模式,從0計數到T1CC0 T1CC0L=0x40; //定時器1通道0捕獲/比較值低位 T1CC0H=0x9C; //定時器1通道0捕獲/比較值高位,定義10 ms產生一次中斷 T1CCTL0|=0x44; //定時器1通道0捕獲/比較控制 T1IE=1; //設定定時器1中斷使能 EA=1; //設定總中斷使能 }
5.LED引腳初始化模塊
LED引腳初始化源代碼如下。
/**************************************************************************************** * 名稱:led_init() * 功能:LED引腳初始化 ****************************************************************************************/ void led_init(void) { P1SEL&=~0x03; //配置控制引腳(P1_0和P1_1)為GPIO模式 P1DIR|=0x03; //配置控制引腳(P1_0和P1_1)為輸出模式 D1=OFF; //初始狀態為關閉 D2=OFF; //初始狀態為關閉 }
6.定時器中斷服務函數模塊
該模塊有兩個功能,分別完成1 s循環計數和控制LED2反轉。定時器中斷服務函數源代碼如下。
/**************************************************************************************** * 名稱:void T1_ISR(void) * 功能:中斷服務子程序 ****************************************************************************************/ #pragma vector = T1_VECTOR __interrupt void T1_ISR(void) { EA=0; //關總中斷 counter++; //統計進入中斷的次數 if(counter>100){ //初始化中定義10ms產生一次中斷,經過100次中斷,10 ms×100=1 s counter=0; //統計的復位次數 D2=! D2; //改變LED2的狀態,打開LED2延時1 s,關閉LED2延時1 s } T1IF=0; //中斷標志位清0 EA=1; //開總中斷 }
6.5 任務驗證
使用IAR開發環境打開任務設計工程,程序通過編譯后,由SmartRF下載到CC2530微處理器中,執行程序后,開發平臺上的LED1和LED2同時開始閃爍,閃爍的時間大概為1 s,隨著時間的推移,LED1和LED2的閃爍動作逐漸拉開,無法保持同步閃爍。
6.6 任務小結
本任務通過配置CC2530微處理器的定時/計數器實現每秒產生一次脈沖的功能,由信號燈閃爍來顯示脈沖輸出,從而基于CC2530定時器實現電子秒表的開發。
通過本任務的開發,理解CC2530定時/計數器的工作原理和功能特點,通過定時器1的學習,掌握其技術模式、寄存器配置,并掌握定時/計數器的中斷初始化以及中斷服務函數,理解秒脈沖發生的工作原理。
6.7 思考與拓展
(1)CC2530定時/計數器的功能和特點有哪些?
(2)定時/計數器的計數模式有哪些?
(3)CC2530有幾個定時/計數器?分別有哪些寄存器?
(4)如何正確對CC2530定時/計數器進行中斷初始化?
(5)定時/計數器除了能夠實現1 s的精確延時,還可以產生PWM輸出,可用來控制直流電機轉速、屏幕亮度、旋轉速度等,信號指示燈實驗中的“呼吸燈”效果便是使用了模擬PWM輸出的效果。但相比模擬PWM輸出而言,通過定時中斷實現的PWM輸出具有更高的靈活性。嘗試以“呼吸燈”效果為目的,通過使用定時/計數器產生PWM輸出,由PWM輸出控制LED1和LED2產生“呼吸燈”效果。