CCPのCompareモードを使う
定期的に割り込みルーチンを呼ぶならCCPのCompareモードを使う方が一般的だろうか(PWMは次の機会に)。前の基準のTimer0と使い方はほぼ同じだ(というかPICならこちらが一般的だ)。カウントにはTimer1を使うがコンペアマッチしてからTMR1をリセットするモードは2つ(「1011」と「0001」)ある。
「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点滅になっている。
投稿者の人気記事
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
(メッセージ: 初版)
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
ログインしてコメントを投稿する