මේ AVR Timers වල දෙවන පාඩම. කලින් පාඩමෙන් TCA කියන Timer එකේ Normal mode එක භාවිතා කරලා digital watch එක හැදුවා කියලා ඔයාලාට මතක ඇති. මම මේ පාඩමේදී කියලා දෙන්න බලාපොරොත්තු වෙන්නේ TCA වල Split Mode Operation ගැන ඔයාලාට කියලා දෙන්න.

මොකක්ද මේ SPLIT mode එක කියන්නේ?

Split mode කියන්නේ 16bit CNT register එක 8bit register දෙකක් විදිහට බෙදලා වැඩ කරන්න සකස් කරන එක. CNT register එක විතරක් නෙවෙයි split mode එකේදී 16bit හැම register එකම 8bit යුගලයක් වෙනවා. CNT එක දෙකට බෙදුන විට අපිට HCNT සහ LCNT කියලා 8 bit counter දෙකක් ලැබෙනවා.  ඒ විතරක් නෙවෙයි PER කියන period register එකත් LPER සහ HPER නම් 8 bit දෙකකට කැඩෙනවා . පහල පෙන්වලා තියෙන්නේ SPLIT mode විදිහට සකස් කල TCA වල Base Counter එකේ ආකෘතිය.

Split mode එකේ දී ගණන් කරන්න පුළුවන් TOP සිට BOTTOM දිශාවට විතරයි. එම නිසා overflow එකක් වෙනුවට අපිට ලැබෙන්නේ underflow එකක්. මේ underflow එකත් සාමාන්‍ය interrupt එක විදිහට වැඩ කරනවා. මේ mode එකේදී TOP ලෙස භාවිතා කරන්නේ HPER සහ LPER කියන 8bit register දෙක. HCNT සහ LCNT වෙන වෙනම වැඩ කරන counters දෙකක් උනාට දෙන්නම භාවිතා කරන්නේ එකම prescaler එක. ඒ නිසා එකම වේගයෙන් තමා ගණන් කරන්නේ. නමුත් HPER හා LPER හරහා එකිනෙකට වෙනස් TOP අගයක් දෙකක් දෙන්න පුළුවන්. ඒ නිසා එකිනෙකට වෙනස කාල වලදී interrupt දෙකක් වෙන වෙනම ගන්න පුළුවන්.

Split mode එකට යන්න TCA වල CTRLD register එකේ තියෙන SPLITM කියන bit එක “1” කරන්න ඕනේ.

දැන් අපි project එකක් කරලම මේ දේවල් ප්‍රායෝගිකව අත්හදා බලමු.

Project 02: TCA වල split mode වලින් digital ඔරලෝසුව සාදමු

මේ project එකේදී කරන්නේ TCA වල split mode එක භාවිතා කරලා digital watch එකක් සාදා ගන්න හැටි කියලා දෙන එක. මේ සඳහා ඔබ Atmel Studio සහ  පරිපථ නිර්මාණය කිරීමට KiCAD කියන software දෙක අවශ්‍ය කරනවා. අවසානයේ දී code එක අපේ IC එකට program කරන්න PiCKit programmer එකකතු ඕනේ. මේ ටික හරි නම් අපේ වැඩ කරන්න පටන් ගමු.

Hardware එක නිර්මාණය කිරීම.

මේ project එකට භාවිතා කරන්නෙත් project 01 එකේ hardware එකම තමයි. ඒ නිසා අමුතුවෙන් මේ ගැන විස්තර කරන්න ඕනේ නෑ කියලා මම හිතනවා. ඔයාලාට පුළුවන් දීල තියෙන link එකෙන් ඒ පරිපථ සටහන බලන්න.

Firmware එක නිර්මාණය කිරීම.

දැන් අපි firmware එක ලියමු. එකට මුලින් ම කරන්න ඕනෑ දේ තමයි අලුත් Project එකක් හදා ගන්න එක. එකත් එක්කම MCU එකේ clock source එක සකසා ගන්නත් ඕනෑ. පරිපථයේ clock source එකක් විදිහට crystal එකක් භාවිතා කලේ නැති නිසා AVR IC එක ඇතුලේම තියෙන clock source එකක් තෝරා ගන්න වෙනවා. ඒ නිසා ඇතුලේ තියන 20Mhz clock source එක තෝරා ගමු. Step 01 අනුගමනය කරන්න.

Step 01 : ATmel Studio වලින් අලුත් Project එකක් හදා ගන්න හැටි

Atmel Studio එකේ File > New > Atmel Start Project තෝරා ගන්න

ඔබ තෝරා ගත් microcontroller එක search box එක අධාරයෙන් සොයා ගන්න. ඉන් පසුව Create New Project වලට යන්න.

දැන් ඔබට පහත දැක්වෙන පරිදි window එකක් දකින්න ලැබේවි. එකේ තියෙන CLKCTRL කියන එක ඔබන්න.

එවිට අලුත් project එක save කරන්න ඕනෑ තැන සහ project එකට නමක් පවරන්න කියලා අසාවි. ඔබ කැමති නමක් භාවිතා කර කැමති තැනක save කරන්න.

MAIN CLOCK CONFIGURATION යටතේ තියෙන,

  • Enable = True
  • Main Clock Source = 20Mhz internal Osc.
  • PEN:Prescaler enable = True
  • PDIV: Prescaler Division = 10

ලෙස සකසා ගන්න. අනිත් දේවල් වලට කිසි වෙනසක් කරන්න යන්න එපා! අවසානයේ GENERATE PROJECT ඔබන්න.

සමහරක් විට save කරන්න යද්දී රූපයේ දැක්වෙන message එක පෙන්වන්න පුළුවන්. එහෙම උනොත් NO button එක click කරන්න.

දැන් අපේ project එක save වෙලා ඉවරයි. ඕනෑ නම් ATMEL START window එක close කරන්න පුළුවන්. ඔයාලාට පේනවා ඇති Solution Explorer Window එකේ ඔයාගේ project එක පෙන්නනවා. Solution Explorer එක පෙනෙන්නේ නැතිනම් View > Solution Explorer  වලින් ඒක ගන්න. main.c file එක double click කරපු විට පහත තියෙන view එක ඔයාටත් එන්න ඕනෑ. පළමු පියවර සාර්ථකයි. දැන් තියෙන්නේ Timer එකට අදාළ code එක ලියන්න

වැදගත්:
හොඳට මතක තියා ගන්න දැන් අපට 2MHz CPU clock එකක් තියෙනවා කියලා. මොකද අපි 20MHz internal clock එක 10න් බෙදලා (PDIV = 10) ගත්ත නිසා. ඒ කියන්නේ අපේ ලියන program එක IC එකේ දී ඇත්තටම run වෙන වේගය 2MHz කියන එක තමයි. මේක අමතක කරන්න එපා!

Step 02 : අපිට ඕනෑ කරන Split mode settings හොයාගමු

මම මුලින්ම HCNT සහ LCNT කියන counter දෙකෙන් LCNT එක තෝරා ගන්නම්. ඔයාටත් කැමති එකක් තෝරාගන්න පුළුවන්.  මොකක් තොර ගත්තත් නිවැරදි period register එක සහ interrupt signal එක සමඟ වැඩ කරන්න ප්‍රවේශම් වන්න! දැන් තත්පරයකට සැරයක් interrupt එකක් ගන්න ඕනේ අගයන් ටික ගණන් හදලා හොයාගමු. මුලිම අපිට හොයාගන්න ඕනේ වෙන්නේ prescale අගයක්, ඉන්පසු PER register එකට ගැලපෙන TOP අගයක් හොයාගන්න ඕනෑ . එහෙනම් අපි 8bit counter එක 2MHz වලදී underflow වෙන්න යන වෙලාව හොයාගමු.

clock pulse 1ක් ගණන් කරන්න යන කාලය = 1/f = 1/2MHz = 0.5us
ගණන් කරන්න පුළුවන් මුළු clock pulse ගණන = 28 = 256
clock pulses ගණන් කරන්න යන මුළු කාලය = 0.5us * 256 = 128 us

128us කියන්නේ හරිම පොඩි වෙලාවක් නිසා අපිට විශාල prescale අගයක් භාවිතා කරන්න වෙයි. ඒ නිසා ලොකුම prescale අගය වන 1024 භාවිතා කරලා බලමු.

Prescale එක 1024ක් නම් 1bit ගණන් කරන්න යන කාලය = 0.5us * 1024 = 512 us
Counter එක underflow වෙන්න යන උපරිම කාලය = 28 * 512 us = 131072 us = 131.072 ms

ලොකු ම prescale එක පාවිච්චි කලත් ලැබෙන්නේ 131.072 ms වගේ කුඩා කාලයක්. මේ නිසා එකවර තත්පරයක underflow එකක් ගන්න බෑ. නමුත් 100ms වලින් underflow එකක් හදා ගෙන ඒවගේ දහයක් ගැණලා තත්පරයක් ගණන් කරන්න පුළුවන් නිසා අපි මේ prescale අගය අරගමු. එහෙනම් 31.072ms කාලයක දෝෂය ඉවත් කරගමු. ඒ සඳහා 31.072ms කාලයක් ගතවෙන්න ඕනේ clock pulse ගණන සොයමු.

31.072ms වෙන්න ඕනෑ clock pulses ගණන = 31.072ms / 512us = 60.6875

අපිට ලැබුනේ දශම සංඛ්‍යාවක්. නමුත් 8bit counter එකට දශම අගයක් ඇතුල් කරන්න බෑ. මේ නිසා 1024 presale එක ඒ තරම් හොඳ නෑ. නමුත් අපි මේ පාඩමේ SPLIT mode එක ගැන ඉගෙන ගන්න ප්‍රමුකතාව දෙන නිසා ඒ දෝෂය අමතක කරලා 60.6875 අසන්න එකට වටයලා 61 කියන අගය ගමු. අපි මේ අගය භාවිතා කරලා අලුත් TOP අගය සොයා ගමු.

131.071ms කාලයක් සඳහා යන clock ගණන = 256
31.071ms කාලයක් සඳහා යන clock ගණන = 61
එම නිසා අවශ්‍යය TOP අගය = 256 – 61 = 195

මෙන්න මේ 195 ( = 0xC316) අගය LPER කියන register එකට ලිව්වොත් ආසන්න වශයෙන් 100ms underflow එකක් ගන්න පුළුවන්. දැන් අපි මේ සොයා ගත්ත අගයන් භාවිතා කරලා අපේ code එක ලියමු. එහෙම ලියපු code එක තමා පහත රූපයේ පෙන්න තියෙන්නේ.

Code එකේ දී මුලින් ම කරන්නේ TCA එක Split mode එකට ගන්න CTRLD register එකේ SPLITM කියන bit එකට “1” ලියන එක. ඉන්පසු LPER register එකට අලුත් TOP එකක් ලියනවා. ඊට පස්සේ කරන්නේ TCA වල underflow interrupts enable කරන එක. මොකද අපිට ගෙවෙන හැම 100ms ම variable එකකට ගණන් කරගන්න ඕනේ. එකට TCA එකේ INTCTRL(interrupt control) register එකේ LUNF bit එක “1” කරනවා. ඊළඟට TCA වල CTRLA වලට prescale එක 1024ක් වෙන්න (CLKSEL[2:0]) වල අගය සහ enable bit (ENABLE) එකයි set කරනවා ( Bit settings ගැන දැන ගන්න ඔබට datasheet එකේ විස්තර ටික බලන්න වෙනවා). දැන් අපේ Timer එක වැඩ කරනවා. අවසානයේ Global interrupts එක sei() function එකෙන් enable කරනවා.  මේ වෙද්දී ඔක්කොම TCA වල settings ටික කරලා ඉවරයි.

ඉතුරු වෙලා තියෙන්නේ timer underflow උනාම වෙන්න ඕනෑ code එක ලියන්න. ඒ කියන්නේ අපේ ISR function එක ලියන එක. එකට කරන්න ඕනේ ISR function එකට TCA0_LUNF_vect කියන underflow interrupt vector pointer එක set කරන එක. (Interrupt පාඩමෙන් vector pointers කියන්නේ මොනාද කියල ඉගෙනගන්න). මෙතැනදී දැන ගන්න ඕනේ වැදගත් කරුණුක් තියෙනවා,

  • ඒ ISR එකට ගියපු විගසම TCA වල INTFLAG කියන register එකේ තියෙන LUNF FLAG bit එකට “1” ලියලා එය මකන එක. මිට හේතුව ISR එක run වුන ගමන් මෙය auto clear නො වීමයි. ඒසේ නොකලොත් ISR එක එක දිගට run වෙනවා.

දැන් ඉතින් timer එකේ වැඩ ටිකනම් ඉවරයි. ඉතුරු වෙලා තියෙන්නේ watch එකේ button දෙකයි 7-segment display එක පාලනය කරගන්න එක. ඒ ටිකත් ඉවර කරපු code එකේ source එක තමා පහත තියෙන GitHub link එකේ තියෙන්නේ.

හොඳට මතක තියාගන්න!

මතකද අපිට TOP එකට දශම ගණනක් ලැබුන නිසා අසන්න ගානකට වටයලා code එක ලිව්වා. අපි බලමු ඒසේ කලවිට ලැබෙන දෝෂය කීයද කියලා. අපිට ලැබුන TOP අගය 195.

එමනිසා සැබෑවටම Underflow වෙන්න යන වෙලාව = 195 * 512 us = 99.840 ms
මේ නිසා 100ms වලට දෝෂය = 100 ms – 99.840 ms = 0.16ms

ඒ කියන්න තත්පරයකට ලැබෙන දෝෂය 1.6ms ( =0.16msx10) වෙනවා. මේ නිසා ඔරලෝසුව අවුරුද්දක් එක දිගට වැඩ කල විට පැය 14.016ක දෝෂයක් එනවා. මේක සුළු පටු සංඛ්‍යාවක් නෙවෙයි. ඒ නිසා ඔයාල හොද product එකක් නිර්මාණය කරද්දී මෙහෙම දෝෂයක් නොවන විදිහට clock speed එක, prescale අගය වගේ දේවල් තෝරා ගන්න.

Step 03 : අපේ code එක IC එකට program කරලා run කරලා බලමු

දැන් අපි අපේ code එක IC එකට program කරලා run කරලා බලමු.