日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STC8A8K64S4A12开发板】—开始做 定时器/计数器 实验啦

發布時間:2023/12/29 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STC8A8K64S4A12开发板】—开始做 定时器/计数器 实验啦 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文為博主原創文章,轉載請附上原文出處鏈接。

文章目錄

  • 前言
  • 一、硬件設計
    • 1.TIMER概念介紹
    • 2.STC8A8K64S4A12系列單片機定時器/計數器介紹
    • 3.定時器/計數器工作模式
    • 4.定時器/計數器溢出時間計算
    • 5.定時器/計數器中斷配置步驟
  • 二、軟件設計
    • 1.定時器/計數器寄存器匯集
    • 2.寄存器解析
      • 2.1.中斷允許寄存器IE
      • 2.2.中斷允許寄存器IE2
      • 2.3.定時器/計數器中斷控制寄存器TCON
      • 2.4.輔助寄存器AUXR
      • 2.5.中斷與時鐘輸出控制寄存器INTCLKO
      • 2.6.寄存器T4T3M
      • 2.7.中斷優先級控制寄存器IP
    • 3.定時器0定時實驗
      • 3.1.工程需要用到的c文件
      • 3.2.頭文件引用和路徑設置
      • 3.3.編寫代碼
    • 4.定時器1定時實驗
      • 4.1.工程需要用到的c文件
      • 4.2.編寫代碼
    • 5.定時器2定時實驗
      • 5.1.工程需要用到的c文件
      • 5.2.編寫代碼
    • 6.定時器3定時實驗
      • 6.1.工程需要用到的c文件
      • 6.2.編寫代碼
    • 7.定時器4定時實驗
      • 7.1.工程需要用到的c文件
      • 7.2.編寫代碼
    • 8.多個定時器定時實驗
      • 8.1.工程需要用到的c文件
      • 8.2.編寫代碼
  • 總結


前言

開始做 定時器/計數器 實驗啦!先介紹原理再開始實驗。


一、硬件設計

1.TIMER概念介紹

定時器(timer)幾乎是每個MCU必有的重要外設之一,可用于定時、精確延時、計數等等,在檢測、控制領域有廣泛應用。
定時器運行時不占用CPU時間,配置好之后,可以與CPU并行工作,實現精確的定時和計數,并且可以通過軟件控制其是否產生中斷,使用起來靈活方便。通常MCU在介紹定時器外設時,總是和計數器(counter)一起出現,所以我們有必要先了解一下定時器和計數器的區別。
定時器和計數器實際都是通過計數器來計數,定時器是對周期不變的脈沖計數(一般來自于系統時鐘),由計數的個數和脈沖的周期即可計算出時間,同時,通過一個給定的預期值(即比較值,對應預期的計數值,也就是預期時間),當計數值達到預期值時產生中斷,這樣就實現了定時,應用程序通過設置不同的預期值實現不同時長的定時。
計數器是對某一事件進行計數,這個事件每發生一次,計數值加/減1,而這個事件的產生可能是沒有規律的。也就是計數器的用途是對事件的發生次數進行計數,由計數值來反映事件產生的次數。

☆注:不同MCU定時器外設使用的計數器位數是個重要的參數,STC8A8K64S4A12系列MCU的定時器使用的是16位計數器(由定時器高8位寄存器和定時器低8位寄存器組合起來實現)。

2.STC8A8K64S4A12系列單片機定時器/計數器介紹

STC8A8K64S4A12系列單片機有5個16位的定時器/計數器,即定時器/計數器T0、定時器/計數器T1、定時器/計數器T2、定時器/計數器T3、定時器/計數器T4。
這些定時器/計數器外設有2種工作方式:定時方式(定時器)和計數方式(計數器)。可通過特殊功能寄存器設置相應的C/T控制位,來選擇定時器/計數器工作在哪種方式。
定時器/計數器外設的核心部件是一個加法計數器,其本質是對脈沖信號進行計數。不同的是,定時器的脈沖信號來自于系統時鐘,而計數器的脈沖信號來自于單片機特定外部輸入引腳。STC8A8K64S4A12系列單片機計數器特定外部輸入引腳如下表。

表1:單片機計數器外部輸入引腳分配 TxINT對應IO口功能描述說明備注
T1P3.4P3.2計數器0外部輸入引腳非獨立GPIOLCD12864/LCD1602屏接口
T2P3.5P3.3計數器1外部輸入引腳非獨立GPIOLCD12864/LCD1602屏接口
T3P1.2P3.6計數器2外部輸入引腳非獨立GPIOnRF24L01P模塊接口
T4P0.4P3.7計數器3外部輸入引腳非獨立GPIOnRF24L01P模塊接口
T5P0.6P3.0計數器4外部輸入引腳非獨立GPIO電位器ADC采樣

☆注:獨立GPIO表示開發板沒有其他的電路使用這個GPIO,非獨立GPIO說明開發板有其他電路用到了該GPIO。針對非獨立GPIO使用時需特別注意。

STC8A8K64S4A12系列單片機定時器/計數器通過相關寄存器的C/T位選擇計數器輸入脈沖信號來源,也即選擇了工作方式是定時方式還是計數方式。后配置相關寄存器位控制輸入脈沖信號至計數器,計數器溢出后產生中斷,也可通過特定引腳輸出產生溢出時鐘。定時器/計數器結構原理示意圖如下。

圖1:定時器/計數器結構原理示意圖

☆注:12T模式是選擇對系統時鐘12分頻,1T模式是選擇對系統時鐘不分頻。另外,該計數器是遞增計數器,不具有遞減功能。

■ 定時器/計數器工作在定時方式(定時器)時:

  • 系統時鐘進行輸入計數,每輸入一個脈沖,計數值加1,當計數到計數器為全1時,再輸入一個脈沖就使計數值回零,同時從最高位溢出一個脈沖使特殊功能寄存器TCON的TFx位置1(T2、T3、T4沒有該寄存器位TFx),作為計數器的溢出中斷標志。
  • 由于計數脈沖的周期是固定的,所以脈沖數乘以脈沖周期就是定時時間,或者稱定時溢出時間(關于定時溢出時間計算公式后有詳述)。
  • 定時器可作為串口通信時的波特率發生器,需配置相關寄存器。
  • 可通過寄存器的TxCLKO位選擇特定時鐘輸出引腳輸出脈沖信號,該脈沖信號的頻率等于計數器溢出率的一半。
  • 表2:單片機計數器時鐘輸出引腳分配 TxCLKO對應IO口功能描述說明備注
    T0CLKOP3.5T0時鐘輸出引腳非獨立GPIOLCD12864/LCD1602屏接口
    T1CLKOP3.4T1時鐘輸出引腳非獨立GPIOLCD12864/LCD1602屏接口
    T2CLKOP1.3T2時鐘輸出引腳非獨立GPIOnRF24L01P模塊接口
    T3CLKOP0.5T3時鐘輸出引腳非獨立GPIO用戶按鍵KEY4
    T4CLKOP0.7T4時鐘輸出引腳非獨立GPIO用戶按鍵KEY3

    ☆注:獨立GPIO表示開發板沒有其他的電路使用這個GPIO,非獨立GPIO說明開發板有其他電路用到了該GPIO。針對非獨立GPIO使用時需特別注意。

    ■ 定時器/計數器工作在計數方式(計數器)時:

  • 單片機特定引腳輸入的外部脈沖信號源進行輸入計數,每輸入一個從1到0的負跳變的脈沖時,計數值加1,當計數到計數器為全1時,再輸入一個脈沖就使計數值回零,同時從最高位溢出一個脈沖使特殊功能寄存器TCON的TFx位置1(T2、T3、T4沒有該寄存器位TFx),作為計數器的溢出中斷標志。
  • 外部輸入信號的最高允許頻率不能大于系統時鐘頻率SYSclk的1/4,比如CPU運行的系統時鐘為11.0592MHz,允許外部最高輸入信號頻率為11.0592MHz/4 = 2.7648MHz,如果頻率高于這個值,輸入信號的部分脈沖在檢測過程中會被丟失,導致測量得到的頻率比真實頻率低。
  • 由于系統每個時鐘對外部計數器引腳采樣1次,當前一次采樣到外部引腳為高電平而后一次采樣到低電平則形成一個負跳變,因此確認外部輸入信號的一次負跳變至少需要2個系統時鐘周期,實際上,引腳輸入通道中還有一個同步采樣與邊沿檢測電路,所以外部輸入信號的最高允許頻率不能大于系統時鐘頻率SYSclk的1/4。
  • 3.定時器/計數器工作模式

    STC8A8K64S4A12系列MCU不同的定時器/計數器所具有的可供選擇的工作模式不同,定時器/計數器0和定時器/計數器1有多種模式可供選擇,選擇模式是通過寄存器TMOD對應的M0位和M1位實現。定時器/計數器2、定時器/計數器3和定時器/計數器4只有默認的一種工作模式。具體如下面列表所示。

    表3:STC8A8K64S4A12系列定時器/計數器工作模式 序號定時器/計數器工作模式T0T1T2T3T4
    1模式0:16位自動重裝載模式
    2模式1:16位不可重裝載模式
    3模式2:8位自動重裝載模式
    4模式3:不可屏蔽16位自動重裝載模式

    ☆注:模式0是STC官方推薦學習的定時器/計數器工作模式,也是我們講解的重點。當T0工作在模式3,T0可作為實時操作系統用節拍定時器。

    下面介紹下定時器/計數器0和定時器/計數器1使用時非常重要的一個寄存器TMOD。

    圖2:模式寄存器TMOD

    ☆注:定時器/計數器的門控位在一些特殊應用中會有使用,一般情況下是將門控位置0。

    ■ 定時器/計數器0和定時器/計數器1工作模式0分析。

    圖3:定時器/計數器0和定時器/計數器1模式0結構圖

    1)定時器/計數器0和定時器/計數器1均有GATE門控位為0、為1的情況。
    2)當GATE=0時,控制定時器/計數器完全由TRx(定時器運行控制位)決定。
    3)當GATE=1時,控制定時器/計數器不僅由TRx(定時器運行控制位)決定,還由外部中斷引腳上的信號決定。此時,可用于脈寬測量。
    4)圖中隱藏2個寄存器RL_THx和RL_TLx,RL_THx和THx共用同一個地址,RL_TLx和TLx共用同一個地址。當Tx被禁止工作時,寫入THx和TLx的內容會同時被寫入RL_THx和RL_TLx中。當Tx開啟工作時,準備寫入THx和TLx的內容,其實沒有被寫入到寫入THx和TLx中,而是寫到了RL_THx和RL_TLx中。這樣便巧妙的實現16位重裝載定時。而讀THx和TLx的內容時,讀取的就是THx和TLx的內容,而不是RL_THx和RL_TLx中的值。

    ■ 定時器/計數器2、定時器/計數器3和定時器/計數器4工作模式0分析。

    圖4:定時器/計數器2、定時器/計數器3和定時器/計數器4模式0結構圖

    1)定時器/計數器2、定時器/計數器3和定時器/計數器4不存在門控位GATE,對定時器/計數器的控制完全由TxR(定時器運行控制位)決定。
    2)定時器/計數器2、定時器/計數器3和定時器/計數器4有且只有一種模式,即16位重裝載模式,實現重裝載的原理請參考對定時器/計數器0和定時器/計數器的分析。

    4.定時器/計數器溢出時間計算

    STC8A8K64S4A12系列單片機作為定時器使用時,由于計數脈沖的周期是固定的,所以溢出前的脈沖數乘以脈沖周期就是定時時間,或者稱定時溢出時間。
    下面是定時器溢出時間計算公式:

    圖5:定時器溢出時間計算公式

    ☆注:公式中的分頻因子PSC在配置定時器/計數器為12T模式時值為12,在配置定時器/計數器為1T模式時值為1。

    舉例,配置定時器/計數器為1T模式,系統時鐘頻率為11.0592MHZ,高8位寄存器初始值為0x28,低8位寄存器初始值為0x00,計算下定時器溢出時間。
    1)十六進制0x28轉成十進制是40,十六進制0x00轉成十進制是0。這樣初始裝載值為:256*40+0=10240。
    2)16位計數器溢出前所計脈沖數為:65536-10240=55296。
    3)分頻因子PSC在1T模式下值為1。系統時鐘頻率為11059200HZ。
    4)定時器溢出時間:55296/11059200=0.005s=5ms。
    5)如果已知定時器溢出時間,計算高8位寄存器初始裝載值和低8位寄存器初始裝載值,則是反推過來即可(建議使用軟件STC-ISP的定時器計算器)。

    5.定時器/計數器中斷配置步驟

    針對STC8A8K64S4A12系列單片機5個定時器/計數器外設,軟件的配置過程如下:

    圖6:定時器/計數器中斷軟件配置步驟

    ☆注:實驗例程即是按照上述配置步驟操作寄存器相關位實現,后有詳述。

    二、軟件設計

    1.定時器/計數器寄存器匯集

    STC8A8K64S4A12系列單片機操作定時器/計數器時會用到18個寄存器,如下表所示:

    表4:STC8A8K64S4A12系列定時器/計數器使用寄存器匯總 序號寄存器名讀/寫功能描述
    1TCON讀/寫定時器/計數器中斷控制寄存器。
    2TMOD讀/寫定時器/計數器模式寄存器。
    3AUXR讀/寫輔助寄存器1。
    4INTCLKO讀/寫中斷與時鐘輸出控制寄存器。
    5IE讀/寫中斷允許寄存器1。
    6IE2讀/寫中斷允許寄存器2。
    7IP讀/寫中斷優先級寄存器1。
    8T4T3M讀/寫T3和T4控制寄存器。
    9TL0讀/寫定時器/計數器0低8位寄存器。
    10TH0讀/寫定時器/計數器0高8位寄存器。
    11TL1讀/寫定時器/計數器1低8位寄存器。
    12TH1讀/寫定時器/計數器1高8位寄存器。
    13T2L讀/寫定時器/計數器2低8位寄存器。
    14T2H讀/寫定時器/計數器2高8位寄存器。
    15T3L讀/寫定時器/計數器3低8位寄存器。
    16T3H讀/寫定時器/計數器3高8位寄存器。
    17T4L讀/寫定時器/計數器4低8位寄存器。
    18T4H讀/寫定時器/計數器4高8位寄存器。

    ☆注:上述寄存器有部分不單單是用于定時器/計數器外設中的,比如寄存器TCON、IE、IE2等。

    2.寄存器解析

    2.1.中斷允許寄存器IE

    外部中斷允許寄存器IE支持位尋址,該寄存器的B1和B3位是定時器/計數器0和定時器/計數器1的中斷允許位。

    圖7:中斷允許寄存器

    2.2.中斷允許寄存器IE2

    中斷允許寄存器IE2不支持位尋址,該寄存器的B2、B5和B6位是定時器/計數器2、定時器/計數器3和定時器/計數器4的中斷允許位。因為IE2寄存器不支持位尋址,所以舉例操作該寄存器B2位時,不可以直接“ET2=0;”進行操作,參考下圖。

    圖8:中斷允許寄存器

    2.3.定時器/計數器中斷控制寄存器TCON

    定時器/計數器中斷控制寄存器TCON支持位尋址,該寄存器的B4位和B6位是T0和T1的運行控制位,寄存器B5位和B7位是T0和T1的溢出中斷標志,含義如下圖。

    圖9:定時器/計數器中斷控制寄存器

    ☆注:TCON寄存器的低4個位是用于外部中斷的,在操作該寄存器時一定要按位操作,用不到的位不要操作。

    2.4.輔助寄存器AUXR

    輔助寄存器AUXR不支持位尋址,該寄存器的B6和B7位是定時器/計數器1和定時器/計數器0的速度控制位,寄存器的B1、B2和B3位是定時器/計數器2的速度控制位、工作方式選擇位和允許控制位。

    圖10:輔助寄存器

    ☆注:AUXR寄存器的B0和B5位在串口外設配置時可能會用到。

    2.5.中斷與時鐘輸出控制寄存器INTCLKO

    中斷與時鐘輸出控制寄存器INTCLKO不支持位尋址,該寄存器的B0、B1和B2位是定時器/計數器0、定時器/計數器1和定時器/計數器2的時鐘輸出引腳控制位。

    圖11:中斷與時鐘輸出控制寄存器

    ☆注:INTCLKO寄存器的定時器時鐘輸出功能和定時器工作模式及工作方式(定時還是計數)密切相關,用戶暫只需知道有這些關系,待項目應用時再分析頻率關系。

    2.6.寄存器T4T3M

    寄存器T4T3M不支持位尋址,該寄存器的B0到B3位是定時器/計數器3配置過程中會用到的位,寄存器的B4到B7位是定時器/計數器4配置過程中會用到的位。

    圖12:T3T4M寄存器

    2.7.中斷優先級控制寄存器IP

    中斷優先級控制寄存器IP支持位尋址,該寄存器的B1位和B3位是設置T0和T1中斷優先級的,含義如下圖。需要說明的是T2、T3和T4是沒有中斷優先級的。

    圖13:中斷優先級控制寄存器

    3.定時器0定時實驗

    ☆注:本節的實驗源碼是在“實驗2-4-1:外部中斷0(下降沿中斷方式)”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-1:定時器0定時”。

    3.1.工程需要用到的c文件

    本例需要用到的c文件如下表所示,工程需要添加下表中的c文件。

    表5:實驗需要用到的c文件 序號文件名后綴功能描述
    1led.c包含與用戶led控制有關的用戶自定義函數
    2timer.c外部定時器有關的用戶自定義函數
    3delay.c包含用戶自定義延時函數

    3.2.頭文件引用和路徑設置

    ■ 需要引用的頭文件

    #include "delay.h" #include "led.h" #include "timer.h"

    ■ 需要包含的頭文件路徑
    本例需要包含的頭文件路徑如下表:

    序號路徑描述
    1…\ Sourceled.h、timer.h和delay.h頭文件在該路徑,所以要包含
    2…\UserSTC8.h頭文件在該路徑,所以要包含

    STC8.h頭文件在該路徑,所以要包含

    圖14:添加頭文件包含路徑

    3.3.編寫代碼

    首先,在timer.c文件中編寫定時器0的初始化函數Timer0Init,代碼如下。

    程序清單:定時器0初始化函數

    /*********************************************************** 功能描述:定時器0初始化 入口參數:無 返回值:無 ************************************************************/ void Timer0Init(void) { AUXR |= 0x80; //定時器0為1T模式 TMOD &= 0xF8; //定時器0設置為定時方式,工作模式為16位自動重裝模式 TMOD &= 0xF7; //定時器0門控位GATE設置為0 TL0 = 0x00; //1T模式下初始裝載值 TH0 = 0x28; //1T模式下初始裝載值 TF0 = 0; //清除T0中斷溢出標志位 ET0 = 1; //使能定時器0的溢出中斷允許位 TR0 = 1; //定時器0開始計時 }

    然后,編寫定時器0中斷服務函數,一旦響應中斷達到一定次數會執行翻轉用戶指示燈D3的任務,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器0中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer0_int (void) interrupt 1 { cnt++; //5ms進入1次中斷 if(cnt == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt = 0; } //進入中斷時會將定時器中斷溢出標志位硬件清零,因此下面一句可以不加的 TF0 = 0; //清除T0中斷溢出標志位 }

    最后,在主函數中調用T0初始化函數,開啟總中斷,而主循環中沒有任務,說明用戶指示燈D3變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer0Init(); //定時器0初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    4.定時器1定時實驗

    ==☆注:本節的實驗源碼是在“實驗2-5-1:定時器0定時”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-2:定時器1定時”。 ==

    4.1.工程需要用到的c文件

    本實驗需要用到的頭文件以及添加頭文件包含路徑的方法請參考“實驗2-5-1:定時器0定時”部分。

    4.2.編寫代碼

    首先,在timer.c文件中編寫定時器1的初始化函數Timer1Init,代碼如下。

    程序清單:定時器1初始化函數

    /*********************************************************** 功能描述:定時器1初始化 入口參數:無 返回值:無 ************************************************************/ void Timer1Init(void) { AUXR |= 0x40; //定時器1為1T模式 TMOD &= 0x8F; //定時器1設置為定時方式,工作模式為16位自動重裝模式 TMOD &= 0x7F; //定時器1門控位GATE設置為0 TL1 = 0x00; //1T模式下初始裝載值 TH1 = 0x28; //1T模式下初始裝載值 TF1 = 0; //清除T1中斷溢出標志位 ET1 = 1; //使能定時器1的溢出中斷允許位 TR1 = 1; //定時器1開始計時 }

    然后,編寫定時器1中斷服務函數,一旦響應中斷達到一定次數會執行翻轉藍色指示燈D3的任務,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器1中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer1_int (void) interrupt TIMER1_VECTOR { cnt++; //5ms進入1次中斷 if(cnt == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt = 0; } //進入中斷時會將定時器中斷溢出標志位硬件清零,因此下面一句可以不加的 TF1 = 0; //清除T1中斷溢出標志位 }

    最后,在主函數中調用T1初始化函數,開啟總中斷,而主循環中沒有任務,說明用戶指示燈D3變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer1Init(); //定時器1初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    5.定時器2定時實驗

    ==☆注:本節的實驗源碼是在“實驗2-5-1:定時器0定時”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-3:定時器2定時”。 ==

    5.1.工程需要用到的c文件

    本實驗需要用到的頭文件以及添加頭文件包含路徑的方法請參考“實驗2-5-1:定時器0定時”部分。

    5.2.編寫代碼

    首先,在timer.c文件中編寫定時器2的初始化函數Timer2Init,代碼如下。

    程序清單:定時器2初始化函數

    /*********************************************************** 功能描述:定時器2初始化 入口參數:無 返回值:無 ************************************************************/ void Timer2Init(void) { AUXR &= 0xF7; //定時器2設置為定時方式 AUXR |= 0x04; //設置定時器2為1T模式 T2L = 0x00; //1T模式下初始裝載值 T2H = 0x28; //1T模式下初始裝載值 IE2 |= 0x04; //使能定時器2中斷 AUXR |= 0x10; //打開定時器2 }

    然后,編寫定時器2中斷服務函數,一旦響應中斷達到一定次數會執行翻轉藍色指示燈D3的任務,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器2中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer2_int (void) interrupt TIMER2_VECTOR { cnt++; //5ms進入1次中斷 if(cnt == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt = 0; } }

    最后,在主函數中調用T2初始化函數,開啟總中斷,而主循環中沒有任務,說明用戶指示燈D3變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer2Init(); //定時器2初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    6.定時器3定時實驗

    ==☆注:本節的實驗源碼是在“實驗2-5-1:定時器0定時”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-4:定時器3定時”。 ==

    6.1.工程需要用到的c文件

    本實驗需要用到的頭文件以及添加頭文件包含路徑的方法請參考“實驗2-5-1:定時器0定時”部分。

    6.2.編寫代碼

    首先,在timer.c文件中編寫定時器3的初始化函數Timer2Init,代碼如下。

    程序清單:定時器3初始化函數

    /*********************************************************** 功能描述:定時器3初始化 入口參數:無 返回值:無 ************************************************************/ void Timer3Init(void) { T4T3M &= 0xFB; //定時器3設置為定時方式 T4T3M |= 0x02; //設置定時器3為1T模式 T3L = 0x00; //1T模式下初始裝載值 T3H = 0x28; //1T模式下初始裝載值 IE2 |= (1<<5); //使能定時器3中斷 T4T3M |= 0x08; //打開定時器3 }

    然后,編寫定時器3中斷服務函數,一旦響應中斷達到一定次數會執行翻轉藍色指示燈D3的任務,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器3中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer3_int (void) interrupt TIMER3_VECTOR { cnt++; //5ms進入1次中斷 if(cnt == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt = 0; } }

    最后,在主函數中調用T3初始化函數,開啟總中斷,而主循環中沒有任務,說明用戶指示燈D3變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer3Init(); //定時器3初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    7.定時器4定時實驗

    ==☆注:本節的實驗源碼是在“實驗2-5-1:定時器0定時”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-5:定時器4定時”。 ==

    7.1.工程需要用到的c文件

    本實驗需要用到的頭文件以及添加頭文件包含路徑的方法請參考“實驗2-5-1:定時器0定時”部分。

    7.2.編寫代碼

    首先,在timer.c文件中編寫定時器4的初始化函數Timer4Init,代碼如下。

    程序清單:定時器4初始化函數

    /*********************************************************** 功能描述:定時器4初始化 入口參數:無 返回值:無 ************************************************************/ void Timer4Init(void) { T4T3M &= 0xBF; //定時器4設置為定時方式 T4T3M |= 0x20; //設置定時器4為1T模式 T4L = 0x00; //1T模式下初始裝載值 T4H = 0x28; //1T模式下初始裝載值 IE2 |= (1<<6); //使能定時器4中斷 T4T3M |= 0x80; //打開定時器4 }

    然后,編寫定時器4中斷服務函數,一旦響應中斷達到一定次數會執行翻轉藍色指示燈D3的任務,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器4中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer4_int (void) interrupt TIMER4_VECTOR { cnt++; //5ms進入1次中斷 if(cnt == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt = 0; } }

    最后,在主函數中調用T4初始化函數,開啟總中斷,而主循環中沒有任務,說明用戶指示燈D3變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer4Init(); //定時器4初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    8.多個定時器定時實驗

    ==☆注:本節的實驗源碼是在“實驗2-5-1:定時器0定時”的基礎上修改。本節對應的實驗源碼是:“實驗2-5-6:多個定時器定時”。 ==

    8.1.工程需要用到的c文件

    本實驗需要用到的頭文件以及添加頭文件包含路徑的方法請參考“實驗2-5-1:定時器0定時”部分。

    8.2.編寫代碼

    首先,在timer.c文件中編寫定時器0和定時器1的初始化函數Timer0Init和Timer1Init,代碼如下。

    程序清單:定時器0和定時器1初始化函數

    /*********************************************************** 功能描述:定時器0初始化 入口參數:無 返回值:無 ************************************************************/ void Timer0Init(void) { AUXR |= 0x80; //定時器0為1T模式 TMOD &= 0xF8; //定時器0設置為定時方式,工作模式為16位自動重裝模式 TMOD &= 0xF7; //定時器0門控位GATE設置為0 TL0 = 0x00; //1T模式下初始裝載值 TH0 = 0x28; //1T模式下初始裝載值 TF0 = 0; //清除T0中斷溢出標志位 ET0 = 1; //使能定時器0的溢出中斷允許位 TR0 = 1; //定時器0開始計時 } /*********************************************************** 功能描述:定時器1初始化 入口參數:無 返回值:無 ************************************************************/ void Timer1Init(void) { AUXR |= 0x40; //定時器1為1T模式 TMOD &= 0x8F; //定時器1設置為定時方式,工作模式為16位自動重裝模式 TMOD &= 0x7F; //定時器1門控位GATE設置為0 TL1 = 0x00; //1T模式下初始裝載值 TH1 = 0x28; //1T模式下初始裝載值 TF1 = 0; //清除T1中斷溢出標志位 ET1 = 1; //使能定時器1的溢出中斷允許位 TR1 = 1; //定時器1開始計時 }

    然后,編寫定時器0和定時器1的中斷服務函數,一旦響應中斷達到一定次數會執行翻轉對應用戶指示燈的操作,代碼如下。

    程序清單:中斷服務函數

    /*********************************************************** 功能描述:定時器0中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer0_int (void) interrupt TIMER0_VECTOR { cnt1++; //5ms進入1次中斷 if(cnt1 == 100) //100次中斷被響應后,正好500ms { led_toggle(LED_3); //翻轉用戶指示燈D3 cnt1 = 0; } //進入中斷時會將定時器中斷溢出標志位硬件清零,因此下面一句可以不加的 TF0 = 0; //清除T0中斷溢出標志位 } /*********************************************************** 功能描述:定時器1中斷服務程序 入口參數:無 返回值:無 ************************************************************/ void timer1_int (void) interrupt TIMER1_VECTOR { cnt2++; //5ms進入1次中斷 if(cnt2 == 200) //200次中斷被響應后,正好1000ms { led_toggle(LED_4); //翻轉用戶指示燈D4 cnt2 = 0; } //進入中斷時會將定時器中斷溢出標志位硬件清零,因此下面一句可以不加的 TF1 = 0; //清除T1中斷溢出標志位 }

    最后,在主函數中調用T0和T1初始化函數,開啟總中斷,而主循環中沒有任務,藍色指示燈D3和藍色指示燈D4變化來自于中斷。

    代碼清單:主函數

    int main(void) { Timer0Init(); //定時器0初始化 Timer1Init(); //定時器1初始化 EA = 1; //使能總中斷 while (1) { ; //無任務,說明LED亮滅來自于中斷 } }

    總結

    以上就是今天要講的內容,大家看完可以思考一下:本例可以設置T0和T1的中斷優先級嗎?會有什么樣的實驗現象呢?

    總結

    以上是生活随笔為你收集整理的【STC8A8K64S4A12开发板】—开始做 定时器/计数器 实验啦的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。