LIST P=12F629;PICの形式 INCLUDE P12F629.INC;Including MPLab's File ERRORLEVEL -302;302番のエラーが出ても無視する ;初期の設定 CB = _CPD_OFF;データメモリのプロテクトをしない CB &= _CP_OFF;プログラムメモリのプロテクトもしない CB &= _BODEN_ON;もし電源電圧が2ボルトを下回ったらパワーダウンする CB &= _MCLRE_OFF;No.3のピンをリセットピンとしては使用しない CB &= _PWRTE_ON;電源が入ってから動き出すまでに72ミリ秒の待機時間を作り、電圧が安定するのを待つ CB &= _WDT_OFF;定期的にリセットする機能をオフにする CB &= _XT_OSC;クリスタルを接続して動くようにする __CONFIG CB;上記「CB」に入れた設定を適用する __IDLOCS H'0100';プログラムバージョンをセット ;変数宣言 CBLOCK H'20';変数のデータを入れるメモリの位置 ;ここで変数を宣言する CNT1;ウェイトをかけるカウンタとして使用 CNT2;ウェイトをかけるカウンタとして使用 ;汎用一時的変数 TmpV ;シリアルポートに送る値を入れるバッファ SBuffer ENDC ;--------------------------------- ORG H'0';プログラムを書き込む位置を設定 GOTO SETTING ;--------------------------------- ;プログラムメモリアドレスH'4'の場所は割り込みがあったときのスタート地点 ORG H'4';プログラムを書き込む位置を設定 ;(何もしない) RETFIE;割り込み終了 ;--------------------------------- SETTING: ;まず全ての出力ピンをLにする BANKSEL GPIO;入出力レジスタに書き込む準備 MOVLW B'00000000';Wレジスタに値を書き込む MOVWF GPIO;Wレジスタから入出力レジスタに値をコピー ;コンパレータを使用しないモードにする BANKSEL CMCON;設定レジスタに書き込む準備 MOVLW B'00000111';Wレジスタに値を書き込む MOVWF CMCON;Wレジスタから設定レジスタに値をコピー ;--------------------------------- ;電源投入時、CKとつながっているD-FFの状態が不定のため、/CKを出力端子モードにしてD-FFを待機状態に偏移させ、それから/CKを入力端子モードにする ;マイコンから出ているピンを入力として使うか出力として使うかの設定 ;PORT0=IROut,PORT1~3=DATA BANKSEL TRISIO;設定レジスタに書き込む準備 MOVLW B'00001110' ;Wレジスタに値を書き込む(PORT 0= OUT, PORT 1,2,3 = IN) MOVWF TRISIO;Wレジスタから設定レジスタに値をコピー BANKSEL GPIO;入出力レジスタに書き込む準備 FIRSTSETTING: ;初期状態として出力モードに設定したピンをHにする MOVLW B'00000001';Wレジスタに値を書き込む(PORT0=1) MOVWF GPIO;Wレジスタの値を入出力レジスタに書き込む ;--------------------------------- MAIN: ;ポート0~2のいずれかがLになったら送信作業を行う BTFSS GPIO,1;指定ビットが1だったら次の行をスキップ GOTO IROUTPUTSTATE;指定ラベルへ飛ぶ BTFSS GPIO,2;指定ビットが1だったら次の行をスキップ GOTO IROUTPUTSTATE;指定ラベルへ飛ぶ BTFSS GPIO,3;指定ビットが1だったら次の行をスキップ GOTO IROUTPUTSTATE;指定ラベルへ飛ぶ GOTO MAIN;ループ ;--------------------------------- IROUTPUTSTATE: ;赤外線出力作業 ;始めに、識別用信号を送る MOVLW B'01010101' MOVWF SBuffer CALL IROUT;送信作業 ;送信バイトを赤外線ポート出力用変数に移動する MOVF GPIO,W MOVWF SBuffer CALL IROUT;送信作業 ;終わりにも、識別用信号を送る MOVLW B'10101010' MOVWF SBuffer CALL IROUT;送信作業 ;3バイト送ると推奨の送信限界時間になるので25ミリ秒以上待機(センサーの説明書で求められている作業) CALL IR1OUT CALL IR1OUT CALL IR1OUT CALL IR1OUT CALL IR1OUT CALL IR1OUT CALL IR1OUT CALL IR1OUT ;100ミリ秒待機 CALL W100MILISECOND ;100ミリ秒待機 CALL W100MILISECOND GOTO MAIN;ループ ;--------------------------------- W100MILISECOND:;1ミリ秒待機 MOVLW D'100';Wレジスタに値を代入 MOVWF CNT2;Wレジスタの値を変数CNT1に書き込む W100MILISECOND_START: ;1ミリ秒待機 MOVLW D'200';Wレジスタに値を代入 MOVWF CNT1;Wレジスタの値を変数CNT1に書き込む CALL W5MICROSECOND;5マイクロ秒の待機作業を、CNT1に入れた回数繰り返す DECFSZ CNT2,F;CNT2が0になったら次の行をスキップ GOTO W100MILISECOND_START;ループ RETURN;戻る ;--------------------------------- W5MICROSECOND:;5マイクロ秒の待機作業を、CNT1に入れた回数繰り返す GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 DECFSZ CNT1,F;変数CNT1の値を1減らし、もし値が0になったら、次の行の命令を飛ばす(RETURNと書いてある命令へジャンプする) GOTO W5MICROSECOND;ループする RETURN;サブルーチン終了 ;赤外線出力用 ;--------------------------------- IROUT: ;スタートビット CALL IR0OUT BTFSC SBuffer,0;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,0;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,1;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,1;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,2;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,2;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,3;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,3;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,4;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,4;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,5;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,5;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,6;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,6;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT BTFSC SBuffer,7;指定ビットが0ならば、次の行の命令を飛ばす CALL IR1OUT BTFSS SBuffer,7;指定ビットが1ならば、次の行の命令を飛ばす CALL IR0OUT ;ストップビット CALL IR1OUT RETURN;戻る ;--------------------------------- IR0OUT:;32KHzでポート1をオンオフし、赤外線データを300bpsで1ビット分出す ;繰り返し回数を代入 MOVLW D'127' MOVWF CNT1 S26MICROSECOND0:;26マイクロ秒周期(約32kHzでポート1をオンオフ) ;ウエィトをかけるにあたって「GOTO $+1」は2サイクル、「NOP」は1サイクル ;IROutをLにする操作 MOVLW B'00000000';Wレジスタに値を書き込む(PORT0=0) MOVWF GPIO;Wレジスタの値を入出力レジスタに書き込む GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 NOP ;何もしない ;IROutをHにする操作 MOVLW B'00000001';Wレジスタに値を書き込む(PORT0=1) MOVWF GPIO;Wレジスタの値を入出力レジスタに書き込む GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 DECFSZ CNT1,F;変数CNT1の値を1減らし、もし値が0になったら、次の行の命令を飛ばす(RETURNと書いてある命令へジャンプする) GOTO S26MICROSECOND0;ループ RETURN;サブルーチン終了 ;--------------------------------- IR1OUT:;32KHzでポート1をオンオフせず、300bpsの1ビットの長さを待機(要は時間稼ぎ) ;繰り返し回数を代入 MOVLW D'127' MOVWF CNT1 S26MICROSECOND1:;26マイクロ秒周期(約32kHzでポート1をオンオフしない) ;ウエィトをかけるにあたって「GOTO $+1」は2サイクル、「NOP」は1サイクル ;IROutをHにする操作(実質何も変化しない) MOVLW B'00000001';Wレジスタに値を書き込む(PORT0=1) MOVWF GPIO;Wレジスタの値を入出力レジスタに書き込む GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 NOP ;何もしない ;IROutをHにする操作(要は何も変化なし、形式的に命令だけ入れている) MOVLW B'00000001';Wレジスタに値を書き込む(PORT0=1) MOVWF GPIO;Wレジスタの値を入出力レジスタに書き込む GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 GOTO $+1;「何もしないで次の行へ進む」の意味。2サイクル。 DECFSZ CNT1,F;変数CNT1の値を1減らし、もし値が0になったら、次の行の命令を飛ばす(RETURNと書いてある命令へジャンプする) GOTO S26MICROSECOND1;ループ RETURN;サブルーチン終了 ;--------------------------------- END