天天看點

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析

目錄

前言

一、實驗相關電路圖​

二、實驗相關理論與寄存器

1.定時/計數器的基本原理

2.CC2530 的定時/計數器

 3.CC2530 的定時/計數器中斷系統

 三、源碼分析

前言

本實驗用于學習CC2530晶片:

  • GPIO的配置方法及中斷概念與方法
  • Led驅動電路及開關Led的原理
  • 定時器 T1 的配置與使用 

一、實驗相關電路圖

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析

由于發光二級管單向導電特性, 即隻有在正向電壓(二極管的正極接正,負極接負)下才能導通發光。P1.0 引腳接發光二極管D1的負極,是以 P1.0 引腳輸出低電平 D1 亮, P1.0 引腳輸出亮電平 D1 熄滅。

實驗結果:定時器 T1 通過查詢方式控制 LED1 周期性閃爍。

二、實驗相關理論與寄存器

        定時器 1 是一個獨立的 16 位定時器,支援典型的定時/計數功能,比如輸入捕獲,輸出比較和 PWM 功能。定時器有五個獨立的捕獲/比較通道。每個通道定時器使用一個 I/O 引腳。定時器用于範圍廣泛的控制和測量應用,可用的五個通道的正計數/倒計數模式将允許諸如電機控制應用的實作。

定時器 1 的功能如下:

  • 五個捕獲/比較通道
  • 上升沿、下降沿或任何邊沿的輸入捕獲
  • 設定、清除或切換輸出比較
  • 自由運作、模或正計數/倒計數操作
  • 可被 1, 8, 32 或 128 整除的時鐘分頻器
  • 在每個捕獲/比較和最終計數上生成中斷請求
  • DMA 觸發功

1.定時/計數器的基本原理

        定時/計數器,是一種能夠對内部時鐘信号或外部輸入信号進行計數,當計數值達到設定要求時,則向 CPU 提出中斷處理請求,進而實作定時或者計數功能的外設。

        定時/計數器最基本的工作原理是進行計數。 不管是定時器還是計數器,本質上都是計數器,可以進行加 1(減 1)計數,每出現一個計數信号,計數器就會自動加 1(自動減 1),當計數值從 0 變成最大值(或從最大值變成 0)溢出時,定時/計數器就會向 CPU 提出中斷請求。

2.CC2530 的定時/計數器

        CC2530 共有 5 個定時/計數器,其中定時器 1 是一個 16 位的定時器,為 CC2530 中功能最全的一個定時/計數器,在應用中應優先選用。定時器 1 的工作模式有三種:

        <1> 自由運作模式: 計數器從 0x0000 開始,在每個活動時鐘邊沿增加 1,當計數器達到0xFFFF 時溢出,計數器重新載入 0x0000 并開始新一輪的遞增計數。該模式的計數周期是固定0xFFFF,當達到最終計數值 0xFFFF 時,标志位 IRCON.T1IF 和 T1STAT.OVFIF 被設定。

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析

自由運作模式

         <2> 模模式: 計數器從 0x0000 開始,在每個活動時鐘邊沿增加 1,當計數器達到 T1CC0 寄存器儲存的值時溢出,計數器又将從 0x0000 開始新一輪的遞增計數, 模模式的計數周期可自行設定。

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析

模模式

         <3> 正計數/倒計數模式: 計數器反複從 0x0000 開始,正計數到 TICC0 儲存的最終計數值,然後再倒計數回 0x0000,當達到最終計數值時,标志位 T1IF 和 OVFIF 被設定。

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析

正計數/倒計數模式

 3.CC2530 的定時/計數器中斷系統

        定時器有 3 種情況能産生中斷請求:

        <1> 計數器達到最終計數值(溢出或回到零)。

        <2> 輸入捕獲事件。

        <3> 輸出比較事件(模模式時使用)。

        使用模模式要特别注意,需要開啟通道 0 的輸出比較模式,否則計數器的值達到 T1CC0 後,是不會産生溢出中斷的。

        定時器 1 共有 5 對 T1CCxH 和 T1CCxL 寄存器,分别對應通道 0 到通道 4。在使用定時器 1 的定時功能時,會用到 T1CC0H 和 T1CC0L 兩個寄存器存放最大計數值的高 8 位和低 8 位。最大計數值 = 定時時長 / 定時器計數周期。

舉例:如何定時 100ms(0.1s) ?

系統在不配置工作頻率時預設為 2 分頻,32M/2=16M,則系統時鐘為 16MHz,分頻系數為128,要定時 0.1 秒,最大計數值為:

CC2530基礎實驗:(4)定時器T1-查詢方式控制LED閃爍前言一、實驗相關電路圖二、實驗相關理論與寄存器 三、源碼分析
預設情況下系統時鐘為 16MHz 時,16 位定時器每次溢出的值是 65536,溢出時間可以按此公式算出,T=1/(16M/128)*65536=0.524s

CC2530 的 T1 定時器(16 位)需要配置三個寄存器 T1CTL、 T1STAT、 IRCON。如下表所示(更詳細的可參考資料手冊):

寄存器 作用 描述
T1CTL(0xE4)

定時器 1 的控制

和狀态

T1CTL (Bit 3:2) 分頻器劃分值,如下:

00: 标記頻率(32MHz)/1

01: 标記頻率/8

10: 标記頻率/32

11: 标記頻率/128

T1CTL (Bit 1:0) 選擇定時器1模式

00: 暫停運作。

01: 自由運作,從0x0000到0xFFFF反複計數。

10: 模模式,從0x0000到T1CC0反複計數。

11: 正計數/倒計數,從 0x0000 到 T1CC0 反複計數并且從 T1CC0 倒計數到 0x0000。

T1STAT(0xAF) 定時器 1 狀态

Bit5(OVFIF): 定時器/計數器溢出中斷标志

Bit4: 定時器 1 通道 4 中斷标志

Bit3: 定時器 1 通道 3 中斷标志

Bit2: 定時器 1 通道 2 中斷标志

Bit1: 定時器 1 通道 1 中斷标志

Bit0: 定時器 1 通道 0 中斷标志

IRCON(0xC0) 中斷标志4

Bit1(T1IF): 定時器1中斷标志。當定時器1中斷發生時設為1并且當CPU向量指向中斷服務例程時清除。

0: 無中斷未決

1: 中斷未決

按照表格寄存器的内容,對 Led1 和 定時器T1 進行配置:

 Led1配置如下:

P1SEL &=~0x01; //配置P1.0為通用IO口
P1DIR |= 0x01; //配置 P1.0 為輸出
           

定時器T1配置如下:

T1CTL = 0x0d; //128 分頻,自動重裝 0x0000-0xFFFF
T1STAT= 0x21; //通道 0,中斷有效
           

本實驗運作過程:通過T1CTL和T1STAT寄存器設定模式為通道0的自由運作模式時,系統開始從0x0000向0xFFFF計數,當達到0xFFFF時,産生溢出中斷,标志位 IRCON.T1IF 被系統設為1,手動将 IRCON 歸零後,計數器重新載入 0x0000 并開始新一輪的遞增計數。

 三、源碼分析

/****************************************************************************
* 文 件 名: main.c
* 描    述: 定時器T1通過查詢方式控制LED1每1s周期性閃爍
****************************************************************************/
#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int  uint;
#define LED1 P1_0       // P1.0口控制LED1

//設定LED燈相應的IO口 入口參數: 無 出口參數: 無
void InitLed(void)
{
    P1DIR |= 0x01;      //P1.0定義為輸出
    LED1 = 1;           //使LED1燈上電預設為熄滅     
}

//定時器初始化,系統不配置工作時鐘時預設是2分頻,即16MHz 入口參數: 無 出口參數: 無
void InitT1()
{
    T1CTL = 0x0d;       //128分頻,自動重裝 0x0000-0xFFFF 
    T1STAT= 0x21;       //通道0,中斷有效   
}

//程式入口函數
void main(void)
{
    uchar count=0;       
    InitLed();		     //調用初始化函數
    InitT1();
    while(1)
    {
        if(IRCON > 0)   //當進入該條語句時,說明已經計數一次0xFFFF(0.524s)了
        { 
            IRCON=0;    
            if(count++ >= 1) //約1s周期性閃爍,示波器測大約為1025MS
            {                
              count=0;
              LED1 = !LED1;  //LED1閃爍        
            }
        } 
    }//count++ >=1規則為先判斷後加1,是以while裡每進行兩次循環約為1s
}
           

繼續閱讀