在前一篇文章提到, 可以利用一個迴圈來達到延遲的效果, 但這其實並不是一個很好的方法.
原因有這幾點:
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 這個暫存器的內容.
範例程式看到的部分
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 燈一秒閃爍一次的目的了.
請先 登入 以發表留言。