ATtiny202-SSNRのLチカプログラム (アセンブリ言語)
前回の続きで、ATtiny202-SSNRで“Lチカ”した時のプログラムのソースコードを以下に示す。アセンブリ言語で組んだ。
;******************************************************* ;タイマAを使用したLチカプログラム (ATTiny202-SSNRを使用) ;******************************************************* .include "tn202def.inc" ;---- 汎用レジスタ ---- .def R_TEMP1 = R16 ;汎用的な変数 .def R_TEMP2 = R17 ;汎用的な変数 .def STACK = R18 ;ステータス・レジスタ退避用 .def U_FLAG = R19 ;ユーザーフラグ ;ユーザーフラグのビット .EQU B_TCA_OVF = 0 ;タイマAオーバーフロー .CSEG ;コードセグメント RJMP MAIN ;リセット .ORG TCA0_OVF_vect RJMP TCA_OVF ;タイマAオーバーフロー ;********************************* ;タイマAオーバーフロー割り込み処理 ;********************************* TCA_OVF: ;---- 全割り込み禁止 ---- CLI ;---- ステータスレジスタの内容を退避 ---- IN STACK, CPU_SREG ;---- タイマAオーバーフロー割り込み要求フラグをクリア ---- CLR R_TEMP1 SBR R_TEMP1, (1<<TCA_SINGLE_OVF_bp) STS TCA0_SINGLE_INTFLAGS, R_TEMP1 ;---- タイマAオーバーフローユーザ・フラグをセット ---- SBR U_FLAG, (1<<B_TCA_OVF) ;---- ステータスレジスタの内容を復帰 ---- OUT CPU_SREG, STACK ;---- 全割り込み許可 ---- SEI RETI ;*************** ;LED切り替え処理 ;*************** LED_CHANGE: ;---- タイマAオーバーフローユーザ・フラグをクリア ---- CBR U_FLAG, (1<<B_TCA_OVF) ;---- PORTAのビット6を反転 ---- LDI R_TEMP1, 0B01000000 STS PORTA_OUTTGL, R_TEMP1 RJMP MAIN01 ;************** ;メインルーチン ;************** MAIN: ;---- 全割り込み禁止 ---- CLI ;---- PORT設定 ---- LDI R_TEMP1, 0B11001111 ;PA4とPA5は存在しないので0 STS PORTA_DIR, R_TEMP1 LDI R_TEMP1, 0B00000000 STS PORTA_OUT, R_TEMP1 ;---- タイマA設定 ---- LDS R_TEMP1, TCA0_SINGLE_INTCTRL SBR R_TEMP1, (1<<TCA_SINGLE_OVF_bp) STS TCA0_SINGLE_INTCTRL, R_TEMP1 ;タイマAオーバーフロー割り込み許可 LDI R_TEMP1, 0B00000111 STS TCA0_SINGLE_CTRLA, R_TEMP1 ;プリスケーラ8 ;---- ユーザーフラグをクリア ---- CLR U_FLAG ;---- 全割り込み許可 ---- SEI ;*********** ;タイマA待機 ;*********** MAIN01: ;---- タイマAオーバーフローユーザ・フラグを監視 ---- SBRC U_FLAG, B_TCA_OVF ;ビットがセットされていなければ1行スキップ RJMP LED_CHANGE ;ビットがセットされていたらLED切り替え処理にジャンプ RJMP MAIN01
今回使用した機能とレジスタについて解説する。
プログラム解説
- PORTA_DIR
- データ方向。0で入力。1で出力。使用しないポートは出力に設定し値を0にしておいた方が良いらしい。VPORTA_DIRも同じ機能で、IN、OUT命令でアクセスできる。
- PORTA_OUT
- 出力値。0でLow(GND電位)、1でHigh(VDD電位)。VPORTA_OUTも同じ機能で、IN、OUT命令でアクセスできる。
- PORTA_OUTTGL
- 出力値切り替え。出力値を切り替えたいビットに1を書き込むと、出力値が反転する。このプログラムの場合はビット6に1を書き込んでいるので、この動作を実行する度にPA6に接続したLEDが点灯したり消灯したりする。
- TCA0_SINGLE_INTCTRL
- タイマA標準動作割り込み制御。ビット0がオーバーフロー割り込み許可ビット”TCA_SINGLE_OVF_bp”で、1を書き込む事でタイマAオーバーフロー割り込み要求フラグがセットされた時に割り込みが起こる。
- TCA0_SINGLE_INTFLAGS
- タイマA標準動作割り込み要求フラグ。ビット0がオーバーフロー割り込み要求フラグ”TCA_SINGLE_OVF_bp”で、タイマAのカウンタが桁溢れするとセットされる。割り込みが起こっても自動で解除されず、解除するにはプログラムで1を書き込む必要がある。
- TCA0_SINGLE_CTRLA
- タイマA制御A(標準/分割動作共通)。詳細を下表に示す。
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
– | – | – | – | CLKSEL2 | CLKSEL1 | CLKSEL0 | ENABLE |
R | R | R | R | R/W | R/W | R/W | R/W |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
ビット3~1のCLKSEL2~0でプリスケーラを設定する。
000 | 1 |
001 | 2 |
010 | 4 |
011 | 8 |
100 | 16 |
101 | 64 |
110 | 256 |
111 | 1024 |
データシートによれば、ATtiny202はデフォルトで20MHzを6分周しているので、設定を触らなければ3.333333MHzで動作している事になる。
マイコンの動作クロック周波数をMCLK(MHz)、プリスケーラをPSCLとすると、16ビットタイマで作り出せる最大の時間は(65536*PSCL)/(MCLK*10^6)となる。
今回はプリスケーラを8とすると、最大時間が約157msとなり、肉眼でわりと早くLEDが点滅しているのが分かるということでこれを採用した。
また、タイマAのCTRLAレジスタのビット0に1を書き込むとカウントを始めるということで、ビット3~1のプリスケーラ8は011で、ビット0は1なので未使用のビット7~4と合わせて0B00000111となる。
この値をCTRLAレジスタに書き込む事で、タイマAはプリスケーラ8でカウントを始める。
マイコンが起動すると、157msごとにタイマAがオーバーフローし割り込みが発生する。そしてPORTA_OUTTGLのビット6に1を書き込む命令が実行され、結果として157msごとにLEDの点灯、消灯が切り替わる。LEDが点滅し、Lチカプログラムが完成した。
タイマAの割り込みルーチンでは前回の記事で説明した通り、自動で全割り込み禁止にはならず、割り込み要求フラグは自動で解除されないので、プログラムでこれを実行している。
次回はSPI通信でDDS(Direct Digital Synthesizer)を制御するプログラムについて説明する。
ピンバック: ATtiny202-SSNRとATmega328P、ATtiny13Aの違い | Tales of Black-Mant 2