前一篇文章提到, 可以利用一個迴圈來達到延遲的效果, 但這其實並不是一個很好的方法.

原因有這幾點:

1. 佔用CPU的資源

2. 很難把迴圈延遲的時間換算成真實世界的時間

3. 延遲的時間是不可預期的 (可能會被中斷事件影響)


因此這篇文章想和大家介紹的是MSP430內部的計時器功能, 目標是讓LaunchPad上面的LED燈, 以1Hz的頻率閃爍, 一樣的我們先附上範例程式:

我們使用的是MSP430裡面的 TimerA 來做計時器, TimerA 有兩種模式(Capture/Compare), 在這邊我們先介紹Compare模式, 我們會先設定一個目標值, 然後CPU內部會有一個counter, 不斷的的去數數, 直到算到目標值為止.

我們可以透過 TACTL 這個16個bits的暫存器來設定 TimerA 的行為. 我們可以從TI官網下載到MSP430的datasheet, 可以找到 TimeA 的架構以及 TACTL 這個暫存器的內容.

TimerA.png 

TimerA_TACTL.png 


範例程式看到的部分

TACTL = MC_2 |ID_3|TASSEL_2|TACLR;

MC_2 : 設定 Mode Control 為2 (continuous mode), 意思就是 counter 會一直數到0xFFFF為止.

ID_3 : 設定除頻器為8.

TASSEL_2 : 設定 TimerA 的 clock source 為 SMCLK.

TACLR : TimerA clear, 當 Timer 計算到目標值後, 自動歸零, 重新再計算下一次.

綜合起來看就是, 把SMCLK的頻率(800kHz)除以8當作 Timer 的頻率(100kHz=1秒數100k次), 所以要數到0xFFFF (2^16)所需要的時間為2^16/100k = 0.66, 大致上近似一秒數到一次.


而在註解的地方則是用另一種方式來達成一秒數到一次的方法, 有興趣的讀者可以自己試試看.

TACTL = MC_1 |ID_3|TASSEL_2|TACLR;

TACCR0 = 49999;

MC_2 : 設定 Mode Control 為1 (up mode), 表示 counter要數到 TACCR0 這個值.

因為 Timer 一秒可以數到100k次, 所以從0數到49999所需要的時間為50000/100k = 0.5, 近似一秒可以數到一次.


當 Timer 計算到目標值後, CPU 要如何得知呢? 這邊我們先用最簡單的方法, 就是 CPU 不斷去詢問 Timer 是否已經算到了呢?所以我們加入了 while迴圈來判斷.

while ( (TACTL & TAIFG) == 0) { }

當 Timer 尚未計算到目標值 (TAIFG = 0), while 的判斷式成立, 所以會一直停留在迴圈內.

當 Timer 計算到目標值後, 會讓 TACTL 這個暫存器的 TAIFG (interrupt) 這個值為1, 這個時候 while 的判斷式將不成立, 導致跳出while迴圈, 接著我們先把 TAIFG 的值 reset 設為0, 之後再讓 LED 的輸出反轉, 這樣一來就可以達到讓 LED 燈一秒閃爍一次的目的了.

創作者介紹
創作者 學無止境 的頭像
kuojed

學無止境

kuojed 發表在 痞客邦 留言(0) 人氣( 5216 )