; list p=PIC16F628 #include ; ; Kubitama version 1.0B ; (c) 2004 Sugihara Toshio. ; All rights reserved. ; PIC16F628 ; Clock=32768Hz 8192orders/s osc=LP ; WDT=off PowerupTimer=on ; Protect=off BrownoutDetect=off ; LowVoltageProg=off MCLR=disable ; Memory for Bank 0 ; 読み取った結果。大切です。 readh equ H'20' ;上8bits readl equ H'21' ;下8bits readhb equ H'22' ;上8bits反転 readlb equ H'33' ;下8bits反転 readb equ H'24' ;読むべきbit数 ; readn equ H'25' ;0で1ワードめ 1で2ワードめ ; 時刻(4秒単位1020秒までカウント可能) time4 equ H'26' ; EEPRONのアドレス 終端ffffがあるアドレスを指す。 ; 8bits単位で動かすので範囲は0000-7ffeまで。 adrh equ H'27' ;上位8bits 00-7f adrl equ H'28' ;下位8bits 00-fe。2ずつ進む ; 待ちルーチン用 wc8 equ H'29' ;wait8xルーチンでのカウント用 ; パリティー計算ルーチン用 pcount equ H'2a' ;パリティーカウント用 pout equ H'2b' ;パリティー出力用 ptmp equ H'2c' ;パリティー作業用 ; EEPROM書き込み予定データ用 writeh equ H'2d' ;書き込み上位8bits writel equ H'2e' ;書き込み下位8bits load16h equ H'2f' ;読み出し上位8bits load16l equ H'30' ;読み出し下位8bits adrhb equ H'31' ;アドレスバックアップ用 adrlb equ H'32' ; write16h equ H'33' ;write16で書く上8bits write16l equ H'34' ;write16で書く下8bits adr16h equ H'35' ;読み書き16ルーチンに送るアドレス adr16l equ H'36' ec1 equ H'37' ;EEPROM関係のカウント用 ed1 equ H'38' ;EEPROM関係のデータ保管用 ;プログラムの開始点 boot org H'0' goto start warukomi org H'4' goto start start ;I/Oなどの初期化 clrf INTCON clrf STATUS clrf PORTB clrf PORTA movlw B'00111000' ;Select Bank 1 movwf STATUS movlw B'11000110' ;TMR0 overflows per 4 sec.(1/128) movwf OPTION_REG movlw B'11110111' ;A3 = output movwf TRISA movlw B'11001111' ;B5,B4 = output movwf TRISB bcf STATUS,RP0 ;Select Bank 0 movlw B'00010000' ;ブザーオフの状態で起動 movwf PORTB movlw B'00001000' ; PTr=Onの状態で起動 movwf PORTA movlw B'00000101' ;A1,A2=input, CMCON,7=output(A2>A1で1) movwf CMCON ;変数初期化 clrf readh clrf readl clrf readhb clrf readlb ;タイマの初期化 clrf TMR0 ;値を初期化 bcf INTCON,T0IF ;あふれフラグを下げる clrf time4 ;時刻初期化 ;起動したことを光と音声で知らせる call beepled ;書き込み開始位置の検索(ffff) clrf adr16h clrf adr16l call searchFFFF btfsc adr16h,7 ;ffffが見つかった? goto bootp4 ;いいえ。 ;はい。 ;ffffを発見。このアドレスから開始 ;アドレスのセット movf adr16h,W movwf adrh movf adr16l,W movwf adrl ;起動コード(ffef)の書き込み movlw H'ff' movwf writeh movlw H'ef' movwf writel call writeE goto bootend ;起動処理が完了 bootp4 ;ffffがなかった場合。 ; EEPROMの初期化。「ffff」を末尾と先頭に書く。 movlw H'7f' movwf adrh movlw H'fe' movwf adrl movlw H'ff' movwf writeh movwf writel call writeE ;結果としてadr[h,l]=[00,00]となる。 bootend ;起動処理終了を音とLED(3回)で知らせる。 call beepledS call beepledS call beepledS mainloop ; 読み取り状況の初期化 clrf readb ;まだトリガ信号を読んでいない状態 mloop2 ; タイマくりあがり確認 btfsc INTCON,T0IF call inctime ; 外部からの要求検出 btfss PORTB,7 goto gaibusousa ; 信号読み取り待ち(上がり:消灯待ち) btfss PORTA,0 goto mloop2 ;下がったままの場合は戻る ;あがった場合 ; 点灯(down)のタイミングを待つ waitdown1 ;1-4 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;5-8 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;9-12 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;13-16 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup waitdown2 ;1-4 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;5-8 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;9-12 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;13-16 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;17-18 btfss PORTA,0 goto waitup btfss PORTA,0 goto waitup ;残念ながら最初からやり直し goto mainloop ;消灯(up)のタイミングを待つ waitup btfsc PORTA,0 ;3 goto mainloop ;残念 btfsc PORTA,0 ;5 goto mainloop ;残念 btfsc PORTA,0 ;7 goto find1 ;1を発見 btfsc PORTA,0 ;9 goto find1 ;1を発見 btfsc PORTA,0 ;11 goto find1 ;1を発見 btfsc PORTA,0 ;13 goto find1 ;1を発見 btfsc PORTA,0 ;15 goto find1 ;1を発見 btfsc PORTA,0 ;17 goto find0 ;0を発見 btfsc PORTA,0 ;19 goto find0 ;0を発見 btfsc PORTA,0 ;21 goto find0 ;0を発見 btfsc PORTA,0 ;23 goto find0 ;0を発見 btfsc PORTA,0 ;25 goto find0 ;0を発見 btfsc PORTA,0 ;27 goto find0 ;0を発見 btfsc PORTA,0 ;29 goto findT ;トリガ btfsc PORTA,0 ;31 goto findT ;トリガ btfsc PORTA,0 ;33 goto findT ;トリガ btfsc PORTA,0 ;35 goto findT ;トリガ btfsc PORTA,0 ;37 goto findT ;トリガ btfsc PORTA,0 ;39 goto findT ;トリガ btfsc PORTA,0 ;41 goto findT ;トリガ ;残念ながら最初に戻る goto mainloop findT ; call beepled ;debug ;タイマくりあがり確認 btfsc INTCON,T0IF goto mainloop ;次の32ビットを読み始めるように指定する movlw D'32' movwf readb goto waitdown2 ;点灯待ちへ find1 ;トリガ読み込み後かどうかのチェック movf readb,W btfsc STATUS,Z ;トリガを読んだ? goto mloop2 ;いいえ。タイマ確認まで戻る。 ;値の設定 rlf readlb,F rlf readhb,F rlf readl,F rlf readh,F bsf readlb,0 ;「1」をセット ;値を読み終えたかチェック decfsz readb,F ;32bit読み終えた? goto waitdown2 ;いいえ。点灯待ちへ。次のビットを待つ。 goto doneread ;はい。読み込み終了 find0 ;トリガ読み込み後かどうかのチェック movf readb,W btfsc STATUS,Z ;トリガを読んだ? goto mloop2 ;いいえ。タイマ確認まで戻る。 ;値の設定 rlf readlb,F rlf readhb,F rlf readl,F rlf readh,F bcf readlb,0 ;「0」をセット ;値を読み終えたかチェック decfsz readb,F ;32bit読み終えた? goto waitdown2 ;いいえ。点灯待ちへ。次のビットを待つ。 goto doneread ;はい。読み込み終了 doneread ;2バイト正常に読み取った場合 ;後の2バイトが先の2バイトの反転になっているかチェック movf readhb,W xorlw H'ff' xorwf readh,W btfss STATUS,Z goto mainloop ;合わない場合 movf readlb,W xorlw H'ff' xorwf readl,W btfss STATUS,Z goto mainloop ;合わない場合 ;パリティーチェック clrf pout ;パリティー値の初期化 movf readh,W call calparity movf readl,W call calparity btfss pout,0 goto mainloop ;1が偶数個なので戻る ;パリティビットを落として値を完成 bcf readh,7 ;読み取った値が確定した。 call beepledS ;いったん短く鳴らす ;タイマのチェック btfsc INTCON,T0IF call inctime ;時刻の値が0でない場合は書き込む movf time4,W btfss STATUS,Z call writetime ;PTrから読み込んだ値を書き込む movf readh,W movwf writeh movf readl,W movwf writel call writeE ;書き込みを指示 ;LED点灯、音を鳴らして1秒ほど休む call beepled goto mainloop ;外部からEEPROMの操作を受ける状態 gaibusousa ;時間が経過している場合は記録する movf time4,W btfsc STATUS,Z goto gaibusousap1 ;time4は0 記録の必要なし ;記録する必要がある場合 call writetime ;記録を行う call beepledS ;少し鳴らす gaibusousap1 ;I/Oを外部操作受付状態に更新 bsf STATUS,RP0 ;Select Bank 1 movlw B'11111111' ;全部Input movwf TRISA movlw B'10001111' ;B6,B5,B4が出力 movwf TRISB bcf STATUS,RP0 ;Select Bank 0 movlw B'10011111' ;音なし,LEDはOff。 movwf PORTB ;B6を引き込み外部アクセスを許可。 ;外部アクセスの終了を待つ gaibusousap2 btfss INTCON,T0IF goto gaibusousap3 ;タイマが繰り上がったとき bcf INTCON,T0IF ;フラグを下げる incf time4,F ;時刻を進める gaibusousap3 ;終了判定 btfss PORTB,7 goto gaibusousap2 ;まだ続く場合 ;アクセス終了 ;I/Oを通常動作に戻す bsf STATUS,RP0 ;Select Bank 1 movlw B'11001111' ;B5,B4=output movwf TRISB ;B6=inputとなり外部アクセス許可終了。 movlw B'11110111' ;A3=output movwf TRISA bcf STATUS,RP0 ;Select Bank 0 movlw B'11111111' ;Photo Tr を入れる。 movwf PORTA movlw B'11011111';音とLEDはオフ。 movwf PORTB ;現在のアドレスがffffでない場合は ;アドレスを2進める movf adrh,W movwf adr16h movf adrl,W movwf adr16l call read16 incf load16h,W btfss STATUS,Z ;ffでしたか? goto gaibusousap5 ;いいえ。 ;はい。 incf load16l,W btfss STATUS,Z ;ffでしたか? goto gaibusousap5 ;いいえ。 ;はい。 ;メインループへ戻る goto mainloop gaibusousap5 ;ffffでなかったのでアドレスを進める movlw D'2' addwf adrl,F btfsc STATUS,Z incf adrh,F bcf adrh,7 ;8000だったら0000になる。 call beepled ;ここで鳴らす。 ;メインループへ戻る goto mainloop ; ここからサブルーチン ; タイマくりあがり確定後の処理(4秒ごと) inctime bcf INTCON,T0IF ;フラグを下げる incf time4,F movlw D'150' ;(600秒=10分ごと) subwf time4,W ;W = time4 - 150 btfss STATUS,C ;time4 >= 150 ? return ;No. ;Yes.出力が必要 ; 時刻情報をEEPROMに書き込む writetime movlw B'11111110' ;時刻経過は上8bitsをH'fe'とする movwf writeh movf time4,W movwf writel call writeE ;書き込みの実行 clrf time4 ;時刻を0に戻す return ;EEPROMにwriteh,writelを書き込む ;現在のアドレスはadrh,adrl ;まず2つ先のアドレスにffffを書く。 ;ffffをベリファイし、正しくない場合は書き直す。 ;次に現在のアドレスに指示されたwriteh,writelを書く。 ;writeh,writelをベリファイし、正しくない場合は書き直す。 ;アドレスを2進める。8000になったら0000にする。 writeE ;次の番地を算出 movf adrh,W movwf adrhb movf adrl,W addlw D'2' movwf adrlb btfsc STATUS,Z incf adrhb,F ;上位のくりあがり bcf adrhb,7 ;最上位ビットはいつも0 ;次の番地にffffを書く writeFF ;アドレスのセット movf adrhb,W movwf adr16h movf adrlb,W movwf adr16l ;データのセット movlw H'ff' movwf write16h movwf write16l call write16 ;ベリファイ call read16 movf load16h,W xorlw H'ff' btfss STATUS,Z goto writeFF ;やり直し movf load16l,W xorlw H'ff' btfss STATUS,Z goto writeFF ;やり直し ;現在の番地にwriteh,writelを書く writeHL ;アドレスのセット movf adrh,W movwf adr16h movf adrl,W movwf adr16l ;データのセット movf writeh,W movwf write16h movf writel,W movwf write16l call write16 ;ベリファイ call read16 movf load16h,W xorwf writeh,W btfss STATUS,Z goto writeHL ;不一致なのでやり直し。 movf load16l,W xorwf writel,W btfss STATUS,Z goto writeHL ;不一致なのでやり直し。 ;アドレスを2進める(7ffeの次は0000) movf adrhb,W movwf adrh movf adrlb,W movwf adrl return ;adr16h,adr16lにwrite16h,write16lを書く。 ;引数の値は変えない。 write16 call turnonE ;EEPROMの電源を入れる ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100000' ;書き込み要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto write16 ;残念。やりなおし。 ;上位アドレスを送る movf adr16h,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto write16 ;残念。やりなおし。 ;下位アドレスを送る movf adr16l,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto write16 ;残念。やりなおし。 ;データ上位を送る movf write16h,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto write16 ;残念。やりなおし。 ;データ下位を送る movf write16l,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto write16 ;残念。やりなおし。 ;ストップ信号を送る bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bsf PORTA,4 ;DA Up bcf PORTB,3 ;CL Down bcf PORTA,4 ;DA Down ;書き終わるのを待つ write16p2 ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100000' ;書き込み要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーですか? goto write16p2 ;はい。書き込み未完なので待つ。 ;いいえ。書き込み完了。 ;すぐにreadすることが前提なので、 ;I/Oの設定などは変えない。 return ;adr16h,adr16lから読みload16h,load16lに入れる。 ;引数の値は変えない。 read16 call turnonE ;EEPROMの電源を入れる ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100000' ;書き込み要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto read16 ;残念。やりなおし。 ;上位アドレスを送る movf adr16h,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto read16 ;残念。やりなおし。 ;下位アドレスを送る movf adr16l,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto read16 ;残念。やりなおし。 ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100001' ;読み取り要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto read16 ;残念。やりなおし。 ;上位(先頭)バイトの読み取り bsf STATUS,RP0 ;Select Bank 1 bsf TRISA,4 ;DAを入力に bcf STATUS,RP0 ;Select Bank 0 movlw D'8' movwf ec1 read16p2 rlf load16h,F bsf PORTB,3 ;CL Up bcf load16h,0 btfsc PORTA,4 bsf load16h,0 bcf PORTB,3 ;CL Down decfsz ec1,F goto read16p2 ;ACKを送る bsf STATUS,RP0 ;Select Bank 1 bcf TRISA,4 ;DAを出力に bcf STATUS,RP0 ;Select Bank 0 bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bcf PORTB,3 ;CL Down ;下位バイトの読み取り bsf STATUS,RP0 ;Select Bank 1 bsf TRISA,4 ;DAを入力に bcf STATUS,RP0 ;Select Bank 0 movlw D'8' movwf ec1 read16p3 rlf load16l,F bsf PORTB,3 ;CL Up bcf load16l,0 btfsc PORTA,4 bsf load16l,0 bcf PORTB,3 ;CL Down decfsz ec1,F goto read16p3 ;ACKを送らない bsf STATUS,RP0 ;Select Bank 1 bcf TRISA,4 ;DAを出力に bcf STATUS,RP0 ;Select Bank 0 bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTB,3 ;CL Down ;STOPコードを送る bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bsf PORTA,4 ;DA Up bcf PORTB,3 ;CL Down bcf PORTA,4 ;DA Down ;EEPROMの電源を切る bsf STATUS,RP0 ;Select Bank 1 movlw B'11110111' ;A3 = output movwf TRISA movlw B'11001111' ;B5,B4 = output movwf TRISB bcf STATUS,RP0 ;Select Bank 0 movlw B'00010000' ;LED,ブザーオフの状態 movwf PORTB movlw B'00001000';PTr=On movwf PORTA return ; ffffが出現するアドレスを検索。 ; 現在のadr16h,adr16lから検索を始める ; 見つかった場合0000-7ffeの範囲になる。 ; 見つからなかった場合、8000になる。 searchFFFF ;先頭の読み込み指示を送信 call turnonE ;EEPROMの電源を入れる ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100000' ;書き込み要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto searchFFFF ;残念。やりなおし。 ;上位アドレスを送る movf adr16h,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto searchFFFF ;残念。やりなおし。 ;下位アドレスを送る movf adr16l,W call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto searchFFFF ;残念。やりなおし。 ;スタートコードを送る bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTA,4 ;DA Down bcf PORTB,3 ;CL Down ;コントロールコードを送る movlw B'10100001' ;読み取り要求 call sendbyteE andlw H'ff' btfss STATUS,Z ;エラーありました? goto searchFFFF ;残念。やりなおし。 ;FFFFが出るか8000になるまで回す searchFFFFp2 ;上位バイトを読む ;DAを入力に切り替える bsf STATUS,RP0 ;Select Bank 1 bsf TRISA,4 ;DAを入力に bcf STATUS,RP0 ;Select Bank 0 ;8回くり返す movlw D'8' movwf ec1 searchFFFFp3 rlf load16h,F bsf PORTB,3 ;CL Up bcf load16h,0 btfsc PORTA,4 bsf load16h,0 bcf PORTB,3 ;CL Down decfsz ec1,F goto searchFFFFp3 ;ACKを送る bsf STATUS,RP0 ;Select Bank 1 bcf TRISA,4 ;DAを出力に bcf STATUS,RP0 ;Select Bank 0 bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bcf PORTB,3 ;CL Down ;下位バイトを読む ;DAを入力にする bsf STATUS,RP0 ;Select Bank 1 bsf TRISA,4 ;DAを入力に bcf STATUS,RP0 ;Select Bank 0 movlw D'8' movwf ec1 searchFFFFp4 rlf load16l,F bsf PORTB,3 ;CL Up bcf load16l,0 btfsc PORTA,4 bsf load16l,0 bcf PORTB,3 ;CL Down decfsz ec1,F goto searchFFFFp4 ;終了判定(データがffff or アドレスが7ffe) incf load16h,W btfss STATUS,Z ;上位8bitはff? goto searchFFFFp5 ;いいえ。 ;はい。 incf load16l,W btfss STATUS,Z ;下位8bitsはff? goto searchFFFFp5 ;いいえ。 ;はい。 ;このアドレスではffffだったことが確定。 goto searchFFFFNOACK ;このアドレスで終了 searchFFFFp5 ;ffffではない場合。 ;アドレスを進める(8000になってもそのまま) movlw D'2' addwf adr16l,F btfsc STATUS,Z incf adr16h,F ;アドレスが8000になっていたら抜ける btfsc adr16h,7 ;次のアドレスが8000? goto searchFFFFNOACK ;はい。検索を終了します。 ;いいえ。まだ続けます。 searchFFFFACK ;まだ続けて読む場合 ;ACKを送る bsf STATUS,RP0 ;Select Bank 1 bcf TRISA,4 ;DAを出力に bcf STATUS,RP0 ;Select Bank 0 bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bcf PORTB,3 ;CL Down ;読み込みを続ける goto searchFFFFp2 searchFFFFNOACK ;検索を終了する場合 ;ACKを送らない bsf STATUS,RP0 ;Select Bank 1 bcf TRISA,4 ;DAを出力に bcf STATUS,RP0 ;Select Bank 0 bsf PORTA,4 ;DA Up bsf PORTB,3 ;CL Up bcf PORTB,3 ;CL Down ;STOPコードを送る bcf PORTA,4 ;DA Down bsf PORTB,3 ;CL Up bsf PORTA,4 ;DA Up bcf PORTB,3 ;CL Down bcf PORTA,4 ;DA Down ;EEPROMの電源を切る bsf STATUS,RP0 ;Select Bank 1 movlw B'11110111' ;A3 = output movwf TRISA movlw B'11001111' ;B5,B4 = output movwf TRISB bcf STATUS,RP0 ;Select Bank 0 movlw B'00010000' ;LED,ブザーオフの状態 movwf PORTB movlw B'00001000';PTr=On movwf PORTA return ;EEPROMの電源を入れる ;ライトプロテクトは外す。DAはあがった状態。 turnonE bsf STATUS,RP0 ;Select Bank 1 movlw B'11000001' ;B5,4,3,2,1=Output movwf TRISB movlw B'11100111' ;A3,4=Output movwf TRISA bcf STATUS,RP0 ;Select Bank 0 movlw B'00010000' ;Power On = EEPROM movwf PORTB movlw B'00010000' ;DAは上げておく movwf PORTA return ;Wレジスタの値1byteをEEPROMに送る。 ;EEPROMからACKを受け取る。 ;成功でW=0。ACKなしでW=ffを返す。 sendbyteE movwf ed1 ;データを保管 movlw D'8' movwf ec1 ;8回くりかえす sendbyteEp2 ;データのセット bcf PORTA,4 ;DA Down btfsc ed1,7 bsf PORTA,4 ;DA Up rlf ed1,F ;クロックの上げ下げ bsf PORTB,3 bcf PORTB,3 ;終了判定 decfsz ec1,F goto sendbyteEp2 ;この時点でec1は0 ;ACKの読み取り bsf STATUS,RP0 ;Select Bank 1 bsf TRISA, 4 ;A4を入力にする bcf STATUS,RP0 ;Select Bank 0 bsf PORTB,3 ;CL Up btfsc PORTA,4 ;ACKが来た? decf ec1,F ;いいえ。ec1=ff ;はい。 ec1=00 bcf PORTB,3 ;CL Down bsf STATUS,RP0 ;Select Bank 1 bcf TRISA, 4 ;A4を出力にする bcf STATUS,RP0 ;Select Bank 0 bcf PORTA,4 ;DA Down movf ec1,W ;戻り値をWレジスタに入れる return ; LEDとブザーをつける。1秒ほどかかる。 beepled bsf PORTB,5 ;LED ON bcf PORTB,4 ;ブザーON ;0.5s待つ movlw H'0' call wait8x movlw H'0' call wait8x bcf PORTB,5 ;LED OFF bsf PORTB,4 ;ブザーOFF ;0.5s待つ movlw H'0' call wait8x movlw H'0' call wait8x return ; LEDとブザーをつける。0.5秒ほどかかる。 beepledS bsf PORTB,5 ;LED ON bcf PORTB,4 ;ブザーON ;0.25s待つ movlw H'0' call wait8x bcf PORTB,5 ;LED OFF bsf PORTB,4 ;ブザーOFF ;0.25s待つ movlw H'0' call wait8x return ;パリティーの計算。Wレジスタで受けた値に ;含まれる1の個数をpoutに加える calparity movwf ptmp movlw D'8' movwf pcount calparityp2 btfsc ptmp,0 incf pout,F rrf ptmp,F decfsz pcount,F goto calparityp2 return ;callとreturnを含め(Wレジスタの値の8倍)-1待つ。 wait8x movwf wc8 wait8x4 decfsz wc8,F goto wait8x2 return wait8x2 nop goto wait8x3 wait8x3 goto wait8x4 end