できること:タイマ割り込みを使って約500msごとに出力をトグルさせる。
プログラム↓
※ここから
Void setup() {
//入出力の設定 全て出力
PORTA.DIR = 0b11111111;
//タイマの設定
takeOverTCA0();
//CTRLA 分周とタイマのイネーブルの設定
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm;
//PER 数値
TCA0.SINGLE.PER = 10000; // 20MHz / 1024 / 10000 = 約500ms
// INTCTRL 割り込み制御 OVF
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
}
void loop() {
// ここでは何もしない。
}
ISR(TCA0_OVF_vect) {
//出力のトグル OUTTGLで出力のH/Lを切り替える
PORTA.OUTTGL = 0b11111111;
//書き込むことで割り込みフラグが解除される。
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}
※ここまで
■簡単な解説
・入出力の設定
//入出力の設定 全て出力
PORTA.DIR = 0b11111111;
レジスタの割り当ての書き方が変わっており、データシートによると<周辺機能実体名>.<レジスタ名>と書かねばならないようだ。なのでデータシートを見るとタイマーやADC、DACの項目ごとに同じレジスタ名のものがでてきてちょっとややこしい。今回の場合はPORTAのDIR(入出力を設定するレジスタ)を設定するのでPOTRA.DIR =○○と記載している。
・タイマの設定
タイマ関連は下記のリンクを参照にしている。AIってすごいね。
https://www.jh4vaj.com/archives/39209
//タイマの設定
takeOverTCA0();
実はここが何をしているか分からない。分かったら追記する。
//CTRLA 分周とタイマのイネーブルの設定
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm;
ここではタイマのクロック周波数とイネーブルの設定をしている。
TCA_SINGLE_CLKSEL_DIV1024_gcのDIV1024_gcの数字を2~1024(2の乗数)に変えることで分周比を変えることが出来る。また。TCA_SINGLE_ENABLE_bm;を有効にすることでタイマを駆動させる。
//PER 数値
TCA0.SINGLE.PER = 10000; // 20MHz / 1024 / 10000 = 約500ms
ここでタイマカウンタの最大値、結果的にタイマの周期を決めることができる。
時間はコメント欄参照、正確には512ms
// INTCTRL 割り込み制御 OVF
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
タイマの値がオーバーフローした時に割り込みが発生するように設定。
ISR(TCA0_OVF_vect) {
//出力のトグル OUTTGLで出力のH/Lを切り替える
PORTA.OUTTGL = 0b11111111;
//書き込むことで割り込みフラグが解除される。
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}
割り込みが発生した時の処理。PORTA.OUTTGLで該当する出力ポートに1を入れるとPORTAの出力を反転することが出来る。
ちなみに単純に1,0を出したいときは下記のようにすればよい。
PORTA.OUT = ○○ //○○の所に1を入れると出力に1が0を入れると0が出力される。
PORTA.OUTSET = ○○ //○○の所に1を入れると1が出力される。0は無効。
PORTA.OUTCLR = ○○ //○○の所に1を入れると0が出力される。0は無効。
あと、割り込み終了時にはピン割り込み要求フラグに1を入れないと割り込みが終了しないようだ。
ATmega88やATtiny2313とかで慣れているとひっかかる罠。
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;