; list p=PIC12F675 ; ; Copyright 2004 Sugihara Toshio. ; All rights reserved. ; #include ; PIC12F675 ; Clock=4.00MHz 1.00M orders / s ; WDT=off, PowerUpTimer=on ; Protect=off, Oscllator=XT ; GP3=Digital IO, BrownOutDetect=off ; Timer Value tm1 equ H'20' tm2 equ H'21' tm3 equ H'22' tm4 equ H'23' tmc equ H'24' ; コンデンサ充電用タイマ ;Status Value 0=ON 1=OFF bakpos equ H'30' ;Saved Value curpos equ H'31' ;Current Value hazime equ H'32' ;Not 0 if just after boot ;Boot from here Boot org H'00' goto Start ;Interrupt comes here Warikomi org H'04' clrf STATUS ;Select Bank 0 movf GPIO, W ;Read GPIO to stop warikomi status clrf INTCON ;Clear GPIF retfie Start ;Stop interrupt clrf STATUS clrf INTCON ;Set Initial Value movlw H'01' movwf hazime INITIO ;I/O setup clrf STATUS clrf INTCON movlw B'00000001' movwf GPIO movlw H'07' ;Set GP2,GP1,GP0 to movwf CMCON ;Digital I/O bsf STATUS,RP0 ;Select Bank 1 clrf ANSEL ;Select GP3-0 to Digital I/O movlw H'08' ;Set GP0-GP2 into outputs movwf TRISIO ;GP3 is only input movlw B'11010110' ;prescaler is for TMR0 and 128:1 movwf OPTION_REG ;Pull up is globally off clrf WPU ;Pull up is off by every pin clrf IOC ; 割り込みピンの設定を消しておく bcf STATUS,RP0 ;Select Bank 0 movlw B'00000001' movwf GPIO ;Set I/O stop mode ;Read current Status call ReadButton btfsc hazime,0 ; 起動直後? goto Afterring ; はい。鳴らした後の場所へ行く ; いいえ。 movf curpos,W subwf bakpos,W ; W := bakpos - curpos btfsc STATUS,Z ; bakpos==curpos ? goto Afterring ; はい。鳴らした後の場所へ行く ; いいえ。鳴らします Ring ;Eを鳴らす movlw D'209' ; 209周期鳴らす movwf tm3 movlw D'2' movwf tmc ; 充電はおよそ2周期 bcf GPIO, 0 ; Cに充電開始 RingE1 ; ここから759命令サイクルで半波長 bcf GPIO, 2 ; Bを下げる bsf GPIO, 1 ; Aを上げる movlw D'252' movwf tm1 ; 待ちの量を指定 RingE2 decfsz tm1,f goto RingE2 ; ここから758命令サイクルで半波長 bcf GPIO, 1 ; Aを下げる bsf GPIO, 2 ; Bを上げる movlw D'249' ; 待ちの量を指定 movwf tm1 RingE3 decfsz tm1,f goto RingE3 ; 750サイクル ; 必要に応じてCの充電を終わる decf tmc,f btfsc STATUS,Z ; 充電終了? bsf GPIO, 0 ; はい。止めます。 ; いいえ。 nop nop ; 755サイクル decfsz tm3,f goto RingE1 ; Cを鳴らす RingC movlw D'2' ; (この値 - 1)*256周期を追加 movwf tm4 movlw D'75' ; 256 + 75 = 331周期鳴らす movwf tm3 movlw D'2' movwf tmc bcf GPIO, 0 ; Cに充電開始 RingC1 ; ここから955命令サイクルで半波長 bcf GPIO, 2 ;Bを下げる bsf GPIO, 1 ;Aを上げる movlw D'238' movwf tm1 ; 待ちの量を指定 RingC2 nop decfsz tm1,f goto RingC2 ; ここから956命令サイクルで半波長 bcf GPIO, 1 ; Aを下げる bsf GPIO, 2 ; Bを上げる movlw D'235' ; 待ちの量を指定 movwf tm1 RingC3 nop decfsz tm1,f goto RingC3 ; 943サイクル ; 必要に応じてCの充電を終わる decf tmc,f btfsc STATUS,Z ; 充電終了? bsf GPIO, 0 ; はい。止めます。 ; いいえ。 ; 946 ; 鳴るのは終わり? decfsz tm3,f goto RingCX1 decfsz tm4,f goto RingCX2 goto RingG RingCX1 ; 949 goto RingCX2 RingCX2 ; 951 nop nop nop goto RingC1 RingG movlw D'248' movwf tm3 movlw D'3' movwf tmc bcf GPIO, 0 ; Cに充電開始 RingG1 ; ここから638命令サイクルで半波長 bcf GPIO, 2 ; Bを下げる bsf GPIO, 1 ; Aを上げる movlw D'211' movwf tm1 ; 待ち時間を設定 RingG2 decfsz tm1,f goto RingG2 nop nop ; ここから638命令サイクルで半波長 bcf GPIO, 1 ; Aを下げる bsf GPIO, 2 ; Bを上げる movlw D'209' movwf tm1 RingG3 decfsz tm1,f goto RingG3 ; 630サイクル ; 必要に応じてCの充電を終わる decf tmc,f btfsc STATUS,Z ; 充電終了? bsf GPIO, 0 ; はい。止めます。 ; いいえ。 ; 633サイクル nop nop decfsz tm3,f ; 鳴らすの終わる? goto RingG1 ; いいえ。次の周期へ ; はい。 ; もう一度Cを鳴らす RingCC movlw D'2' ; (この値 - 1)*256周期を追加 movwf tm4 movlw D'75' ; 256 + 75 = 331周期鳴らす movwf tm3 movlw D'2' movwf tmc bcf GPIO, 0 ; Cに充電開始 RingCC1 ; ここから955命令サイクルで半波長 bcf GPIO, 2 ;Bを下げる bsf GPIO, 1 ;Aを上げる movlw D'238' movwf tm1 ; 待ちの量を指定 RingCC2 nop decfsz tm1,f goto RingCC2 ; ここから956命令サイクルで半波長 bcf GPIO, 1 ; Aを下げる bsf GPIO, 2 ; Bを上げる movlw D'235' ; 待ちの量を指定 movwf tm1 RingCC3 nop decfsz tm1,f goto RingCC3 ; 943サイクル ; 必要に応じてCの充電を終わる decf tmc,f btfsc STATUS,Z ; 充電終了? bsf GPIO, 0 ; はい。止めます。 ; いいえ。 ; 946 ; 鳴るのは終わり? decfsz tm3,f goto RingCCX1 decfsz tm4,f goto RingCCX2 goto RingStop RingCCX1 ; 949 goto RingCCX2 RingCCX2 ; 951 nop nop nop goto RingCC1 ; 鳴らした後はI/Oを確実に停止状態にする RingStop movlw B'00000001'; I/Oピンを停止状態に設定する movwf GPIO bsf STATUS,RP0 ;Select Bank 1 movlw H'08' ;Set GP0-GP2 as outputs movwf TRISIO ;GP3 is only input clrf STATUS ;Select Bank 0 movlw B'00000001'; I/Oピンを停止状態に設定する movwf GPIO ; 現在の状態をここで再び取得 call ReadButton ;鳴った後・鳴らなかった場合の動作 Afterring ; 変数の更新 clrf hazime ; もう初めてじゃない movf curpos,W ; bakpos = curpos movwf bakpos ; ; 状態固定用にGPIOを読む movf GPIO,W ;この読み込みを固定用とする movwf tm1 bcf tm1,0 btfsc tm1,3 bsf tm1,0 ;tm1::bit0 はスイッチの状態と同じ movf curpos,W ; スイッチとcurposは xorwf tm1,F ; tm1::bit0 = 一致で0 不一致で1 btfsc tm1,0 ; 不一致してる? goto AfterSleep ; はい。スリープの後の状態へ ; いいえ。 ; 割り込みの設定 bsf STATUS,RP0 ;Select Bank 1 movlw B'00001000';Set GP3 as movwf IOC ;interruptable bit 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 ; 割り込みのあとはここから実行される AfterSleep ;起きた後。割り込みを禁止してI/O初期化からはじめる clrf INTCON nop nop goto INITIO ; スイッチの状態をcurposに入れて返す。 ; ON=0 OFF=1 ; 最短で1.5ms。最大で3.5msくらいで判断できる。 ReadButton ; 変数の初期化 clrf curpos ; 初期状態はオン扱い clrf tm1 ; オンの回数 clrf tm2 ; オフの回数 ReadButtonNext ; 6cycles / loop btfss GPIO,3 ; 押されてる? goto ReadButtonOn ; はい。オン。 ; いいえ。オフ。 ReadButtonOff nop incfsz tm2,F ; 256回め? goto ReadButtonNext ; いいえ。もう一度 ; はい。オフに決定 incf curpos,F ; curposをH'01'にする return ReadButtonOn incfsz tm1,F ; 256回め? goto ReadButtonNext ; いいえ。もう一度 ; はい。オンに決定 return ; curposは0のままで返す end