「PIC10F322 扇風機のリモコンのクローンを作る 1 ON/OFFの実装」の続き。
消費電力を減らすために、4秒程度何もしないと自動的にSLEEPモードに入るようにした。
正確には 1/16000000 × 4 × 256 × 256 × 256 = 4.19秒 という計算になると思う。
Timer0の割り込みを使って実装した。
YUASA_Fan_IR_RemoCon_INT (160 ダウンロード )
SLEEPからの復帰にも割り込みを使うわけだが、2つの割り込みが発生する可能性がある場合の処理の書き方をすっかり忘れていて、少し悩んだ。
以下の部分だ。
1 2 3 4 5 6 7 8 9 |
void interrupt intr(void) { if(INTCONbits.TMR0IF == 1){ INTCONbits.TMR0IF = 0;//Timer0 Overflow Interrupt Flag Clear t0cnt--; } if(INTCONbits.INTF == 1){ INTCONbits.INTF = 0;//INT External Interrupt Flag Clear } } |
INTCONbits.TMR0IF はTIMER0のオーバーフローの割り込み用で、INTCONbits.INTF はINT Pin(RA2)の割り込み用だ。
ちゃんと分けて処理しないとね。
このときの消費電流は0.009mAとなる。
電源として使う予定のLIR2032の容量が40mAhとすると待機状態なら半年はもつ計算。
その後、データ・シートを眺めていると、Interrupt-On-Change (IOC) という機能を使えばINT Pin(RA2)だけでなくどのピンでもSLEEPからの復帰用の割り込みに使えるようだとわかったので、それ用のコードも書いてみた。
YUASA_Fan_IR_RemoCon_IOC (166 ダウンロード )
変更点は割り込み処理の部分
1 2 3 4 5 6 7 8 9 10 11 |
void interrupt intr(void) { if(INTCONbits.TMR0IF == 1){ INTCONbits.TMR0IF = 0;//Timer0 Overflow Interrupt Flag Clear t0cnt--; } if(INTCONbits.IOCIF == 1){ INTCONbits.IOCIF = 0;//Interrupt-on-Change Interrupt Flag Clear IOCAFbits.IOCAF2= 0; IOCAFbits.IOCAF3= 0; } } |
と、main()内のこの部分だ。
1 2 3 4 5 6 |
//Interrupt INTCONbits.GIE= 1;//Global Interrupt Enabled INTCONbits.PEIE = 1;//Peripheral Interrupt Enabled INTCONbits.IOCIE = 1;//Interrupt-on-Change Interrupt Enabled IOCAPbits.IOCAP2 = 1;//Interrupt-on-change PORTA Positive Edge Enabled IOCAPbits.IOCAP3 = 1;//Interrupt-on-change PORTA Positive Edge Enabled |
はじめの例ではリモコン信号を送信するボタンとSLEEPからの復帰ボタンを別にしていた。
後の例ではすべてのピンを復帰用に指定できる。
結果的にリモコン信号の送信ボタンがそのままSLEEPからの復帰ボタンを兼ねる。
電源スイッチを作り込むこと自体を忘れがちだが、これなら電源の切り忘れも無く、しかも10μA程度の消費電流で済むので都合がいい。
「PIC10F322 扇風機のリモコンのクローンを作る 3 プリント基板に組む」へ続く
Tweet