PICを使った30分、60分オフタイマープログラム
私が寝室で使っているテレビのマイコンに不具合があり、リモコンで消したテレビの電源が勝手に入ったり、オフタイマーが働かなかったりしていました。テレビ自体が古いので直す気にもなれずそのままになっていました。そのアセンブラープログラムを紹介します。
完成したオフタイマー基板と周辺機器
ほぼ完成した、PICを使った30分、60分オフタイマーの写真です。
左からDC5V用の携帯電話充電用電源アダプタ、秋月のSSRキット、PIC12F629を使ったタイマー基板です。ケースに入れる前の状態です。何度もPICのプログラムを書き換えて試せるようにICソケットを使っています。
PIC12F629で正確なタイマーを作る場合はセラロックか水晶発振子を使った方が良いのですが、内部発振でもそこそこの精度があります。また回路が非常に簡単なのも魅力です。
PIC12F629を使ったオフタイマー
PICマイコンがなんとか使えるようになったので、 PICマイコン楽天 の学習も兼ねてテレビにも使えるオフタイマーを作ってみました。うまくできましたので紹介します。PICマイコンPIC12F629と秋月電子通商のソリッドステートリレー(SSR)のキットを利用して作りました。
PICのアセンブラープログラムはフリーソフトのTera-Padエディターで作成しました。PIC開発ツールはMicrochip社のMPLAB IDE Ver.7.4、PICプログラムの書き込みは秋月のAKI-PICプログラマーVer.4を使いました。
もちろん、テレビ以外にもラジオやラジカセ、時間の変更や放熱板の変更でエアコンでも使えるようにできます。
30分、60分オフタイマープログラム
; Filename: timer30_60.asm ; Date:2007.06.02 ; File Version: 1.0 ; OFF Timer 30_60 min. ; Author: D.Ishikawa ;********************************************************************** ; Files required: ;********************************************************************** ;PICは12F629 ;GPIO,1 ;LED出力ポート ;GPIO,2 ;タイマー出力ポート ;GPIO,3 ;タイマーの時間を決める入力ポート ;GPIO,3がLの時30分オフタイマーとなります。 ;GPIO,3がHの時60分オフタイマーとなります。 ;60分オフタイマーで最初の30分はLEDが2秒周期で点滅 ;最後の30分はLEDが1秒周期で点滅 ;********************************************************************** list p=12f629 ;list directive to define processor #include <p12f629.inc> ; processor specific variable definitions errorlevel -302 ;suppress message 302 from list file __CONFIG _CP_ON & _CPD_ON & _BODEN_ON & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT __IDLOCS 0x0100 ;Ver 1.00 #define OUT_LED GPIO,1 ;LED出力ポート #define OUT_TMR GPIO,2 ;タイマー出力ポート #define IN_P GPIO,3 ;入力ポート #define ON_TIME d'30' ;最短のON期間 分で指定 ;***** VARIABLE DEFINITIONS w_temp EQU 0x20 ; variable used for context saving status_temp EQU 0x21 ; variable used for context saving CNT1 EQU 0x22 CNT2 EQU 0x23 CNT3 EQU 0x24 CNT4 EQU 0x25 ;********************************************************************** ;initialize eeprom locations ORG 0x2100 DE "OFF Timer_30_60min." ORG 0x000 ; processor reset vector goto main ;go to beginning of program ORG 0x004 ;interrupt vector location movwf w_temp ;save off current W register contents movf STATUS,w ;move status register into W register movwf status_temp ; save off contents of STATUS register ;isr code can go here or be located as a call subroutine elsewhere movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ;restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ;restore pre-isr W register contents retfie ;return from interrupt ;these first 4 instructions are not required if the internal oscillator is not used main call 0x3FF ;retrieve factory calibration value bsf STATUS,RP0 ;set file register bank to 1 movwf OSCCAL ;update register with factory cal value bcf STATUS,RP0 ;set file register bank to 0 ;remaining code goes here bcf STATUS,RP0 ;set file register bank to 0 bcf STATUS,RP1 ;set file register bank to 0 clrf INTCON ;割り込み禁止 clrf GPIO ;GPIO初期化 bsf STATUS,RP0 ;バンク1に切替 clrf TRISIO ;GPIOを出力に設定 bsf TRISIO,3 ;GP3を入力に設定 clrf IOC ;I/O状態変化チェック解除 movlw b'10000000' ;プルアップ無し、エッジ割り込み無し、タイマー0は内部クロック movwf OPTION_REG ; bcf STATUS,RP0 ;バンク0に bcf OUT_LED ;OUT_LEDを0に bcf OUT_TMR ;OUT_TMRを0に btfsc IN_P ;入力ポートチェック goto _60MIN ;Hなら _60MIN へ _30MIN bsf OUT_TMR ;OUT_TMRを1に call DLY_30 OFF_30 bcf OUT_TMR ;OUT_TMRを0に goto OFF_30 _60MIN bsf OUT_TMR ;OUT_TMRを1に call DLY_60_30 call DLY_30 OFF_60 bcf OUT_TMR ;OUT_TMRを0に goto OFF_60 ;Delay Routine DLY_30 ;30分 movlw ON_TIME ;1*30=30min movwf CNT4 DLY_6 ;60S movlw d'60' ;1*60=60S movwf CNT3 DLY_5 ;1S ;0.5*2=1S bsf OUT_LED ;0.5秒ON call DLY_500 bcf OUT_LED ;0.5秒OFF call DLY_500 decfsz CNT3,f goto DLY_5 decfsz CNT4,f goto DLY_6 return DLY_60_30 ;60分用の初めの30分 movlw ON_TIME ;1*30=30min movwf CNT4 DLY_4 ;60S movlw d'30' ;2*30=60S movwf CNT3 DLY_3 ;2S ;0.5*4=2S bsf OUT_LED ;1秒ON call DLY_500 call DLY_500 bcf OUT_LED ;1秒OFF call DLY_500 call DLY_500 decfsz CNT3,f goto DLY_3 decfsz CNT4,f goto DLY_4 return DLY_500 ;500mS movlw d'250' ;2mS*250=500mS movwf CNT2 DLY_2 ;2mS DLY_2 loop DLY_2 を一巡する時間は 6 + 8*249 + 2 = 2000μS movlw d'249' ; (1) 1cycle=1μS movwf CNT1 ; (1) nop ; (1) nop ; (1) nop ; (1) nop ; (1) DLY_1 ; DLY_1 loop nop ; 1 1 nop ; 1 1 nop ; 1 1 nop ; 1 1 nop ; 1 1 decfsz CNT1,f ;1 2 (CNT1が0になると2サイクル) goto DLY_1 ;2 (12F629の goto は2サイクル) decfsz CNT2,f ; 1 goto DLY_2 ; (2) return END ;directive 'end of program'
オフタイマーのアセンブラープログラムの使い方
アセンブラープログラムファイル名をtimer30_60.asm等にしてエディタ等で保存して使ってください。