; Copyright 2004 Sugihara Toshio. #include ; PIC12F675 ; Clock=Internal RC NO Clock 4MHz 1M order/s ; WDT=off, PowerUpTimer=on ; Protect=off, Oscllator=Internal RC ; GP3=GPIO, BrownOutDetect=off ; LEDも信号に応じて点滅。(送出中はGP0=1のとき光る) ; 変数の定義 idhi equ H'20' ;ID上位8bits idlo equ H'21' ;ID下位8bits idhiinv equ H'22' ;ID上位8bitsの反転 idloinv equ H'23' ;ID下位8bitsの反転 o8c equ H'24' ;8bits出力ルーチン内のカウンタ o8b equ H'25' ;8bits出力ルーチン内のバッファ wtmp equ H'26' ;時間稼ぎタイマ用 ; outbuf equ H'27' ;出力バッファ ocount equ H'28' ;出力の回数をカウント ptmp equ H'29' ;パリティー算出対象変数格納用 pout equ H'2a' ;算出した奇パリティー(最下位ビット) pcount equ H'2b' ;パリティー算出ルーチン内ループ用 ; はじまり ; リセットで始まる場合 org H'00' boot goto start ; 割り込みではじまる場合 warikomi org H'04' movf GPIO, W ;Read GPIO to stop warikomi status clrf INTCON ;Clear GPIF retfie ; 通常の起動 start ;割り込みの禁止 clrf INTCON ;bank0が選択されている ; I/Oの初期化 movlw B'00000001' movwf GPIO movlw H'07' ; コンパレータを使わない movwf CMCON clrf STATUS bsf STATUS,RP0 ;Select Bank 1 movlw B'00001000';GP3だけが入力 movwf TRISIO movlw H'ff' ;プルアップ機能を無効に movwf OPTION_REG clrf ANSEL ;ADコンバータは使わない clrf STATUS ;Select Bank 0 ;出力状態の初期化 movlw B'00000001' ;I/Oの初期出力状態 movwf GPIO ; 変数の初期化 movlw H'10' ; 標識のID上位 movwf idhi movlw H'01' ; 標識のID下位 movwf idlo bcf idhi,7 ;ID最上位bitはパリティ用にあける ;パリティの算出 movlw H'1' movwf pout movf idhi,W call calparity movf idlo,W call calparity btfsc pout,0 ;パリティーが1の場合 bsf idhi,7 ;最上位bitを1にあげる ;反転データの作成 movf idhi,W xorlw H'ff' movwf idhiinv movf idlo,W xorlw H'ff' movwf idloinv ; 約3ms秒待つ movlw D'250' call wait8x movlw D'125' call wait8x ; 信号出力 movlw D'16' ;出力する回数 movwf ocount sendnext ;トリガーを出力 call sendT ;上位8bitsを出力 movf idhi,W call send8bits ;下位8bitsを出力 movf idlo,W call send8bits ;上位8bitsの反転を出力 movf idhiinv,W call send8bits ;下位8bitsの反転を出力 movf idloinv,W call send8bits ;繰り返し用ループ decfsz ocount,F goto sendnext ; 状態を切り替えておよそ100ms待つ movlw B'00000001';コンデンサ充電待ち movwf GPIO ;LED消灯 movlw D'49' ;待つ回数 movwf ocount chargenext movlw H'00' call wait8x decfsz ocount,F goto chargenext ; GP1を入力に切り替える bsf STATUS,RP0 ;Select Bank 1 bsf TRISIO, 1 ;GP1を入力に clrf STATUS ;Select Bank 0 ; GP3が下がるまでスリープする movf GPIO,W ;GPIOスリープ前のリード movwf ocount btfss ocount, 3 goto start ;GP3=0なので最初に戻って出力開始 ; スリープ処理 bsf STATUS,RP0 ;Select Bank 1 movlw B'00001000' ;GP3を割り込みの対象に movwf IOC clrf STATUS ;Select bank 0 clrf INTCON ;Clear INTCON bsf INTCON, 3 ;Set Port change enable bit bsf INTCON, 7 ;Set Global Interrupt Enable bit ; Sleep する sleep nop ; 割り込みする前にこれが実行されると思う nop ; 割り込みのあとはここから実行される ;起きた後。 clrf INTCON ;割り込み禁止 goto start ;最初に戻って出力開始 ; ここからサブルーチン ; Wレジスタに入った8bitsを出力。 ; 上位ビットから出します send8bits movwf o8b ;出力する値をバッファに書き込む movlw D'8' movwf o8c send8bitsp2 btfss o8b,7 goto send8bitsp3 ;1を出力 call send1 goto send8bitsp4 send8bitsp3 ;0を出力 call send0 send8bitsp4 rlf o8b,F ;左シフト ;8回まわすための判定 decfsz o8c,F goto send8bitsp2 return sendT ;(35/8192)秒の上げ=4272 movlw B'00000110' movwf GPIO ;出力を「上げ」状態に 0 movlw D'0' call wait8x ;2049 movlw D'0' call wait8x ;4098 movlw D'21' call wait8x ;4267 nop goto sendDown ;4270 sendDown movlw B'00000001' movwf GPIO ;出力を「下げ」状態に 4272 ;(28/8192)秒の下げ。=3418 ;ただしいくぶん少なめに movlw D'200' call wait8x movlw D'226' call wait8x ;3410 return ;3412 send1 ;(11/8192)秒の上げ=1343 movlw B'00000110' movwf GPIO ;出力を「上げ」状態に 0 movlw D'167' call wait8x ;1337 nop nop goto sendDown ;1341 後で+2=1343 send0 ;(22/8192)秒の上げ=2686 movlw B'00000110' movwf GPIO ;出力を「上げ」状態に 0 movlw D'200' call wait8x ;1601 movlw D'135' call wait8x ;2682 goto sendDown ;2684 後で+2=2686 ; poutをWレジスタに含まれる"1"の個数だけ進める calparity movwf ptmp movlw D'8' movwf pcount calparityp2 btfsc ptmp,0 incf pout,F rrf ptmp,F decfsz pcount,F goto calparityp2 return ;呼び出し、戻しを含めて8*WREGサイクル待つ wait8x movwf wtmp decf wtmp,F ;1引く wait8x2 goto wait8x3 wait8x3 goto wait8x4 wait8x4 nop decfsz wtmp,F goto wait8x2 goto wait8x5 wait8x5 nop return ;指定のサイクル待つ(call,return含む) wait8c nop wait7c nop wait6c nop wait5c nop wait4c return end