Monday, 22 October 2007

Timer for Embedded Programming

Timer ဆိုတာကိုေတာ့ သံုးဘူးၾကမွာပါ။ ဒီ Post က Hardware နဲ႔ဆက္စပ္တဲ့ Timer ပါ။ ARM9/ 10/ 11 CPU နဲ႔ Gameboy Hardware ကိုအေျခခံၿပီးရွင္းျပသြားပါမယ္။ Case Study သေဘာေပါ့။ ကၽြန္ေတာ္က ARM9 ကိုအသံုးျပဳၿပီး Gameboy ကေန Frequency အမ်ိဳးမ်ိဳးထုတ္ေပးႏိုင္တဲ့ Program ေရးတာပါ။ Frequency ထုတ္တာကေတာ့ Signal ကို low/ high ေတြ တစ္လွည့္စီေပးၿပီး အဲဒီ signal ေတြၾကားမွာ time interval ေလးေတြျခားေပးျခင္းအားျဖင့္ frequency ထုတ္တာပါပဲ။ Pseudo frequency သေဘာပါပဲ။ Oscilloscope နဲ႔တိုင္းတာၿပီးစစ္ေဆးလုိ႔ ရေအာင္လုိ႔ပါ။
အဲဒီအခါမွာ time interval က အလြန္တိက်ဖို႔ လိုအပ္လာပါတယ္။ ဒါေၾကာင့္ Timer နဲ႔ Interrupt ကို အသံုးျပဳၿပီး ေရးတာပါ။ ဒီ Post မွာေတာ့ Interrupt အေၾကာင္းမပါေသးပါဘူး။
ARM ရဲ႕Timer မွာ Frequency ၄ မ်ိဳးပါပါတယ္။ Frequency ေပၚမူတည္ၿပီး interval ေတြ ကြာျခားပါတယ္။ ဥပမာ - 16.384 kHz ဆိုရင္ ရဲ႕တန္ဖိုးကို တစ္ႀကိမ္မွာ 61.04
μs ႏႈန္းနဲ႔ တိုးေပးတာပါ။ Frequency ေတြကေတာ့ ဒီလိုေတြ ရွိပါတယ္။

၁။ 1 Cycle, 16.78 MHz Frequency, 59.59 ns Interval
၂။ 64 Cycle, 262.21 kHz Frequency, 3.815
μs Interval
၃။ 256 Cycle, 65.536 kHz Frequency, 15.26 μs Interval
၄။ 1024 Cycle, 16.384 kHz Frequency, 61.04 μs Interval

တစ္ျခား CPU ေတြမွာလည္း ဒီလိုသေဘာမ်ိဳးပါပဲ။ ဥပမာ - ကၽြန္ေတာ္က 1 ms ကို အတိအက် လုိခ်င္တယ္ ဆိုပါေတာ့။ C Language နဲ႔ဆိုရင္ ဒီလိုေရးရပါတယ္။

// Control Register ထဲမွာ Timer ကို အသံုးျပဳမယ္။ Timer ရဲ႕ Frequency က 16.78 Mhz ပါ (တစ္ႀကိမ္ကို ၁ စီတိုး)။ Interrupt ကိုအသံုးျပဳမယ္။
REG_TM1CNT= TM_ENABLE | TM_FREQ_SYSTEM | TM_IRQ;

// Data register ထဲမွာ Timer တန္ဖိုး ကိုထည့္ပါမယ္။ hex 4000 ရဲ႕ value က 16384 ျဖစ္လုိ႔ပါ။ (“-” ထည္ေပးတာကေတာ့ Timer က “0” အထိေရာက္ေအာင္ တိုးလုိ႔ပါ)။ တိုက္႐ိုက္တန္ဖိုး ၁၆၃၈၄ လည္းထည့္လုိ႔ရပါတယ္။
REG_TM1D = - 0x4000;

// ၿပီးရင္ Timer ကို ျပန္ပိတ္ေပးပါ။
REG_TM1CNT &= ~TM_ENABLE;

ဒါဆိုရင္ Timer1 control code ရပါၿပီ။ အဲဒီ Code ေတြကို Function တစ္ခုအျဖစ္ ခြဲထားၿပီး ယူသံုးႏိုင္ပါတယ္။
Gameboy (ARM9) မွာ Timer ၄ ခုပါပါတယ္ REG_TM0CNT, REG_TM1CNT, REG_TM2CNT, REG_TM3CNT ေတြပါ။ Timer ေတြကို Cascade ခ်ိတ္ၿပီးလည္းသံုးႏုိင္ပါတယ္။ ေနာက္ ပိုစ့္မွာ ဆက္ေျပာပါမယ္။

No comments:

Post a Comment