akira.kei が 2025年01月26日13時46分47秒 に編集
コメント無し
本文の変更
[<前の記事](https://elchika.com/article/677c4470-fd25-4256-a6bd-fddc78466500/):[次の記事>](url) ## CCPのCompareモードを使う
定期的に割り込みルーチンを呼ぶならCCPのCompareモードを使う方が一般的だろうか(PWMは次の機会に)。前の基準のTimer0と使い方はほぼ同じだ(というかPICならこちらが一般的だ)。カウントにはTimer1を使うがコンペアマッチしてからTMR1をリセットするモードは2つある。「1011」と「0001」だ。
定期的に割り込みルーチンを呼ぶならCCPのCompareモードを使う方が一般的だろうか(PWMは次の機会に)。前の基準のTimer0と使い方はほぼ同じだ(というかPICならこちらが一般的だ)。カウントにはTimer1を使うがコンペアマッチしてからTMR1をリセットするモードは2つ(「1011」と「0001」)ある。

「0001」の方はtoggleの文字が見えるので、今回はこちらが妥当かと思ったのでが、思ったような動作をしない。なぜか1Hz周期で4回パルスを出すだけになってしまう。これが解消できないので、前回と同じように割り込み処理をさせる。モード「1011」なら2Hz周期で1パルスを出力出来た。
「0001」の方はtoggleの文字が見えるので、今回はこちらが妥当かと考えたが思ったような動作をしない。なぜか1Hz周期で4回パルスを出すだけになってしまう。これが解消できないので、前回と同じように割り込み処理をさせる。モード「1011」なら2Hz周期で1パルスを出力出来た。
 トグルモード(0001)の再確認はMCC(Cord Configuator)を使ってそのうち再確認する。 ## 割り込みルーチン 前の記事の割り込みとほぼ同じで良い。このルーチンを2Hz周期で呼び出すことで1Hz周期50%デューティの点滅を行う。 ``` unsigned char flg=0; void __interrupt() isr(void) { if(PIR4bits.CCP1IF) { PIR4bits.CCP1IF=0; if(flg) { LATAbits.LATA2=1; LATAbits.LATA5=0; } else { LATAbits.LATA2=0; LATAbits.LATA5=1; } flg=~flg; } } ``` ## mainルーチン mainルーチンではまず出力ピン指定とTimer1設定をする。Foscは1MHz、Fosc/4(=250kHz)をプリスケーラで1/8(→31250Hz)でカウントする。CCPは「1011」モードで15625とコンペアする(Timer0のように1を引かない)。あとは割り込み設定をしてnopを挟んだ無限ループだ。 ``` void main(void) { TRISAbits.TRISA2=0; TRISAbits.TRISA5=0; T1CONbits.TMR1CS=0b00; // 00: Fosc/4 T1CONbits.T1CKPS=0b11; // 11:(1/8) T1CONbits.TMR1ON=1; CCP1CONbits.CCP1MODE=0b1011; CCPR1=15625; CCP1CONbits.CCP1EN=1; PIR4bits.CCP1IF=0; PIE4bits.CCP1IE=1; INTCONbits.PEIE=1; INTCONbits.GIE=1; while(1) {__nop();} } ``` Simulatorで確認してもLEDの点滅サイクルはキッチリ1秒になっていた。オシロスコープでみても安定して1Hz点滅になっている。 