;******************************************************************** ; Version History ;******************************************************************** ; V1.1 Straight Key Monitor toneを ; PORTA,BIT3 から PORTB,BIT4に変更 2000.01.08 ; V1.2 SLEEP時の消費電流削減、RB3-RB0を出力に設定してSLEEP 2000.01.09 ; V1.3 SPEED設定 0:遅く F:速くに反転 2000.01.09 ; V1.4 Speed switch change 2000.07.23 ; V1.5 State change for PTT-Delay during sleep 2000.08.02 ; V1.6 Modified to add delay to KEYOUT 2002.01.05 ;******************************************************************** ; EleKey2.asm ;EleKey ;******************************************************************** include "P16F84.INC" ;ファイルを組みこむ include "DEFINE.INC" ;定数の定義 ;******************************************************************** ORG 00h ;00番地より始まる GOTO START ;ラベルSTARTヘ ORG 04h ;割り込みベクター GOTO INT_START ;割り込みルーチンINT_STARTへ START ; ;******************************************************************** ; ;PORTA初期化 ;******************************************************************** BSF STATUS,RP0 ;Select Bank1 MOVLW 11100000B ;1110000BをレジスタWにロード RA4-0:Output Mode MOVWF TRISA ;PORTA[4:0]を出力に設定 BCF STATUS,RP0 ;Select Bank0 MOVLW 00010010B ;PWR on and PTT off, V1.6 MOVWF PORTA ;RA4=High(PTT off),RA1=High(PWR on) ;PORTB初期化 BSF STATUS,RP0 ;Select Bank1 MOVLW 11101111B ;PORTBはBIT 7-5, 3-0:INPUT Mode MOVWF TRISB ; MOVLW 00000100B ;00000100B RB[7:0]PullUp,プリスケーラ 1/32, MOVWF OPTION_REG ;RB3-0のINTは立ち下がりで発生にセット BCF STATUS,RP0 ;Select Bank0 ;******************************************************************** ; ;各レジスタの初期化 ;******************************************************************** CALL CLRSHIFTER ;RAM0-RAM31 Clear MOVLW SCALE ;Initial Value MOVWF SCALER ; MOVLW PTTVAL1 ;PTTDLY Initial Value MOVWF PTTDLY1 ; CLRF PTTDLY2 ; CLRF INT_FLAG ;インタラプトFLAGクリア CLRF MEMORYREG ;MEMORYREGクリア CLRF PORTA_BUF ;Clear PORTA_BUF CLRF STATEREG ;Initialize STATEREG BSF PORTA_BUF,DELAY_PTT ;DELAY_PTT off BSF PORTA_BUF,PWR_LED ;PWR_LED on (for Demo board) CALL READ_SWITCH ; ;Timer初期値設定 MOVLW TIMER ; MOVWF TMR0 ; ;******************************************************************** ; ;インタラプト許可 ;******************************************************************** MOVLW 10100000B ;GIE TOIE RBIE = 1 (Enable) MOVWF INTCON ;INTCONにレジスタWのデータを移動 ;******************************************************************** ; ;インタラプト待ちLOOP ;******************************************************************** ;Timer INT 処理 IDLELOOP ;Idle Loop BTFSS INT_FLAG,TIMEINT ;1600Hz Timer INT有り? GOTO IDLELOOPEND ;Do Nothing BCF INT_FLAG,TIMEINT ;Reset TIMEINT Flag ;TIME INT あり BTFSS PORTB,DASH_IN ; BSF MEMORYREG,DASHMEMORY ;SET DASH MEMORY BTFSS PORTB,DOT_IN ; BSF MEMORYREG,DOTMEMORY ;SET DOT MEMORY BTFSS PORTB,KEY_IN ;Straight Key SPACE? GOTO IDLELOOP_KEY1 ;MARK 出力セット BTFSS MEMORYREG,MARK_AUTO ;MARK? GOTO IDLELOOP_KEY2 ;SPACE→出力 IDLELOOP_KEY1 BSF MEMORYREG,MANUAL_KEY; V1.6 PORTA_BUF,KEY_OUT ;MARK→出力 GOTO IDLELOOP_KEY3 ; IDLELOOP_KEY2 BCF MEMORYREG,MANUAL_KEY; V1.6 PORTA_BUF,KEY_OUT ;SPACE→出力 IDLELOOP_KEY3 MOVF PORTA_BUF,w ;PORTAの設定 MOVWF PORTA ;comment out for keyout delay V1.6 ;SLEEPの判定 BTFSS INT_FLAG,DLYMARKBIT ;Mark ならSLEEP Counter Initialize GOTO IDLELOOP2 ;SLEEP 処理続行 CALL SLEEPINIT ;INITIALIZE SLEEP COUNTER GOTO IDLELOOPEND ;IDLE LOOP END IDLELOOP2 CALL SLEEPDEC ;SLEEP 処理続行 BTFSS INT_FLAG,SLEEPFLAG ;COUNTER EXPIRED ? GOTO IDLELOOPEND ;NO BCF INT_FLAG,SLEEPFLAG ;さあSLEEP処理だ ; ;RB3-0をOUT MODEに(消費電流削減) BSF STATUS,RP0 ;Select Bank1 MOVLW 11100000B ;PORTBはBIT7-5, BIT 3-0もOUTPUT Modeに MOVWF TRISB ; BCF STATUS,RP0 ;Select Bank0 ; MOVLW 00001000B ;RB INT ENABLE MOVWF INTCON ;SET INTCON REG ; BSF PORTA,PWR_LED ;PWR LED OFF MOVLW 01010000B ;PWR LED OFF and PTT-delay off,V1.5 MOVWF PORTA ;V1.5 SLEEP ;おやすみ NOP ;WAKEUP GOTO START ;START AGAIN IDLELOOPEND GOTO IDLELOOP ; ;******************************************************************** ; ;SPEED設定スイッチの読み込み ;******************************************************************** READ_SWITCH MOVLW SPEED_SW_PART ;SPEED設定SWITCH部分を取り出す ANDWF PORTB,w ;SPEED設定PARTの取り出し ; XORLW SPEED_SW_PART ;反転、番号の大きいほどWd/min大きく CALL READ_SWITCH1 ; RETURN ; READ_SWITCH1 ADDWF PCL,f ;変換TABLE RETLW DIGIT0 ;最速 RETLW DIGIT1 ; RETLW DIGIT2 ; RETLW DIGIT3 ; RETLW DIGIT4 ; RETLW DIGIT5 ; RETLW DIGIT6 ; RETLW DIGIT7 ; RETLW DIGIT8 ; RETLW DIGIT9 ; RETLW DIGIT10 ; RETLW DIGIT11 ; RETLW DIGIT12 ; RETLW DIGIT13 ; RETLW DIGIT14 ; RETLW DIGIT15 ;最遅 ;******************************************************************** ; ;インタラプト処理はここから開始 ;******************************************************************** ; ;発生するインタラプトの種類 ; ;INTCON,T0IF TMR0オーバーフロー 1.6KHzのクロック ; ; INT_START ;インタラプト処理 MOVWF SAVE_W ;save W value BTFSC INTCON,T0IF ;TMR0インタラプトあり? CALL INT_TMR0 ;TMR0のINT処理を実行 INT_END MOVF SAVE_W,W ;return W value RETFIE ;インタラプト処理終了戻る ;******************************************************************** ; 以下SUBROUTINE "INT_TMR0" ;******************************************************************** INT_TMR0 BSF INT_FLAG,TIMEINT ;TIMEINT発生フラグセット BCF INTCON,T0IF ;レジスタINTCONのT0IFをクリア MOVLW TIMER ;TMR0に数値を設定 MOVWF TMR0 ; CALL DEC_EK_CLK_CTR ;Timing Counter Decrement CALL SHIFTING ;Digital Delayの実行 CALL OSC800 ;遅延800Hz発生 CALL OSC800ST ;ストレート(遅延無し)800Hz発生 CALL PTTCOUNTDOWN1 ;PTTのDelay RETURN ;******************************************************************** ; 以下Subroutine "DEC_EK_CLK_CTR" ;******************************************************************** DEC_EK_CLK_CTR ;Timing Counter処理 MOVF STATEREG,f ;State check BTFSC STATUS,Z ;Status=Not zero GOTO ELEKEY ;no Decrement when state = Idle(0) DECFSZ ELEKEY_DEV,f ; RETURN ;Divider not zero CALL READ_SWITCH ;SPEEDの設定 MOVWF ELEKEY_DEV ; BTFSC INT_FLAG,EK_CLK_CTR_ZERO ;Need Decrement? If set, NO GOTO ELEKEY ;decrement not necessary DECFSZ EK_CLK_CTR,f ;Decrement end? GOTO ELEKEY ;not end BSF INT_FLAG,EK_CLK_CTR_ZERO ;end of decrement ELEKEY ;ELEKEY State Check & Branch BTFSC STATEREG,7 ;must Positive GOTO FALSE_STATE ;negative is false MOVLW 5 ;Max state value +1 SUBWF STATEREG,w ;(f)-(w) should be negative BTFSC STATUS,C ;Carry=0ならNegative GOTO FALSE_STATE MOVF STATEREG,w ;must be 0-4 ADDWF PCL,f ;STATE 別にJUMP GOTO EK_IDLE ;0:Idle GOTO EK_DOTACT ;1:Dot Active GOTO EK_DOTSP ;2:Space after DOT GOTO EK_DASHACT ;3:Dash Active GOTO EK_DASHSP ;4:Space after DASH EK_IDLE ;IDLE State BTFSC MEMORYREG,DOTMEMORY ;Check DOT Memory GOTO EK_TODOT ;to DOT state BTFSC MEMORYREG,DASHMEMORY ;Check DASH Memory GOTO EK_TODASH ;to Dash state RETURN ;END of ELEKEY EK_TODOT ;Idle -> DOT BSF MEMORYREG,MARK_AUTO ;Set Mark MOVLW DOT_ACT ;state MOVWF STATEREG ;State = DOT_ACT MOVLW DOT_COUNT ;Dot = 4count MOVWF EK_CLK_CTR ;INIT counter CALL READ_SWITCH ;SPEEDの設定 MOVWF ELEKEY_DEV ;syncronize clock RETURN ; EK_TODASH ;Idle -> DASH BSF MEMORYREG,MARK_AUTO ;Set Mark MOVLW DASH_ACT ; MOVWF STATEREG ;State 0 -> 3 MOVLW DASH_COUNT ;dash = 12count MOVWF EK_CLK_CTR ;INIT counter MOVF ELEKEY_CLOCK,w ; CALL READ_SWITCH ;SPEEDの設定 MOVWF ELEKEY_DEV ;syncronize clock RETURN ; EK_DOTACT ;DOT 出力中 EK_CLK_CTRがゼロになるまで BTFSS INT_FLAG,EK_CLK_CTR_ZERO ; RETURN ; BCF INT_FLAG,EK_CLK_CTR_ZERO ;Clear It BCF MEMORYREG,MARK_AUTO ;set Space MOVLW SP_AFT_DOT ;State MOVWF STATEREG ;State DOTACT -> DOTSP(Space after DOT) MOVLW DOT_COUNT ;Dot = 4count MOVWF EK_CLK_CTR ;INIT counter RETURN ; EK_DOTSP ;space after DOT EK_CLK_CTRがゼロになるまで BTFSS INT_FLAG,EK_CLK_CTR_ZERO ;End of space time? GOTO EK_DOTSP3 ;DOT memory clearへ BCF INT_FLAG,EK_CLK_CTR_ZERO ;Clear It BTFSC MEMORYREG,DASHMEMORY ;DASH memoryあるか GOTO EK_DOTSP2 ; MOVLW ST_IDLE MOVWF STATEREG ;set IDLE State RETURN EK_DOTSP2 ;DASH memoryあり MOVLW DASH_ACT ; MOVWF STATEREG ;set dash active MOVLW DASH_COUNT ;DASH = 12count MOVWF EK_CLK_CTR ;INIT counter BSF MEMORYREG,MARK_AUTO ;Set mark RETURN ; EK_DOTSP3 ;DOT memory Clear MOVLW MEMORY_DOT_CLR ; SUBWF EK_CLK_CTR,w ;4の時 Positive BTFSS STATUS,C ;Carry=1ならPositive RETURN BCF MEMORYREG,DOTMEMORY ;memory clear RETURN ; EK_DASHACT ;DASH 出力中 EK_CLK_CTRがゼロになるまで BTFSS INT_FLAG,EK_CLK_CTR_ZERO ; RETURN ; BCF INT_FLAG,EK_CLK_CTR_ZERO ;Clear It BCF MEMORYREG,MARK_AUTO ;set Space MOVLW SP_AFT_DASH ; MOVWF STATEREG ;State DASHACT -> DASHSP(Space after DASH) MOVLW DOT_COUNT ;Dot = 4count MOVWF EK_CLK_CTR ;INIT counter RETURN ; EK_DASHSP ;space after DASH EK_CLK_CTRがゼロになるまで BTFSS INT_FLAG,EK_CLK_CTR_ZERO ;End of space time? GOTO EK_DASHSP3 ;DASH memory clearへ BCF INT_FLAG,EK_CLK_CTR_ZERO ;Clear It BTFSC MEMORYREG,DOTMEMORY ;DOT memoryあるか GOTO EK_DASHSP2 ; MOVLW ST_IDLE MOVWF STATEREG ;set IDLE State RETURN EK_DASHSP2 ;DOT memoryあり MOVLW DOT_ACT ; MOVWF STATEREG ;set dot active MOVLW DOT_COUNT ;DOT = 4count MOVWF EK_CLK_CTR ;INIT counter BSF MEMORYREG,MARK_AUTO ;Set mark RETURN ; EK_DASHSP3 ;DASH memory Clear MOVLW MEMORY_DASH_CLR ; SUBWF EK_CLK_CTR,w ;4,3の時 Positive BTFSS STATUS,C ;Carry=1ならPositive RETURN BCF MEMORYREG,DASHMEMORY ;DASHMEMORY clear RETURN FALSE_STATE ;Stateの誤り CLRF STATEREG ; GOTO ELEKEY_END ; ELEKEY_END RETURN ;ELEKEY処理終了 ;*********************************************************** ; DELAY処理 ;*********************************************************** SHIFTING DECFSZ SCALER,f ;Shift Needed? GOTO SHIFTEND ;NO, Exit MOVLW SCALE ;Reload Scale Value MOVWF SCALER ; RLF RAM0,f ;8bit Delay BTFSS MEMORYREG,MANUAL_KEY; V1.6 PORTA_BUF,KEY_OUT ;KEY出力読み取り GOTO SPACE1 ;1=Space BSF RAM0,0 ;1=Mark CALL PTTSET ;PTT Start GOTO SHIFT3 ; SPACE1 BCF RAM0,0 ;0=Space SHIFT3 CALL SHIFT2 ;Shift RAM1-RAM31 BTFSS STATUS,C ;Carry = 1? (Mark) GOTO SHIFT4 ;No, Space BSF INT_FLAG,DLYMARKBIT ;MarkBit Set GOTO SHIFTEND ;Delay処理終了 SHIFT4 ; BCF INT_FLAG,DLYMARKBIT ;MarkBit Clear SHIFTEND RETURN ;SHIFTING SUBROUTIN終了 ;*********************************************************** ; SIDE TONE 処理 ;*********************************************************** OSC800 ;800Hz OSC BTFSS INT_FLAG,DLYMARKBIT ;DLYMARKBIT ONならOSC ON GOTO OSC_CLR ;DLYMARKBIT offならClear MOVLW 01h ;Bit0=1 XORWF PORTA_BUF,f ;Invert PORTA_BUF Bit0 GOTO OSC800END ;OSC処理終了 OSC_CLR BCF PORTA_BUF,DELAY_TONE ;OSC Clear OSC800END ; MOVF PORTA_BUF,w ;V1.6 for KEYOUT delay ; MOVWF PORTA ;V1.6 for KEYOUT delay RETURN ;OSC800 SUBROUTINE終了 OSC800ST ;800Hz OSC BTFSS MEMORYREG, MANUAL_KEY; V1.6 PORTA_BUF,KEY_OUT ;KEY_OUT=1ならMARK, OSC ON GOTO OSC_CLRST ;0ならClear MOVLW 010h ;Bit4=1 XORWF PORTB,f ;Invert PortB Bit3 GOTO OSC800STEND ;OSC処理終了 OSC_CLRST BCF PORTB,SIDE_TONE ;OSC Clear OSC800STEND RETURN ;OSC800ST SUBROUTINE 終了 ;*********************************************************** ; PTT DELAY 処理 ;*********************************************************** PTTCOUNTDOWN1 ;PTTDLY count down DECFSZ PTTDLY1,f ;PTT Prescaler GOTO PTTEND ;exit MOVLW PTTVAL1 ;init value MOVWF PTTDLY1 ; PTTCOUNTDOWN2 MOVF PTTDLY2,f ;STATUS set BTFSC STATUS,Z ;Non Zeroか GOTO PTTCLR ;PTTDLY2=0 このときDECしない DECF PTTDLY2,f ;Not Zero GOTO PTTEND ;Dec のみ PTTCLR ;DELAY終了 BSF PORTA_BUF,DELAY_PTT ;PTT High=off BCF PORTA_BUF,KEY_OUT;V1.6 for KEYOUT delay ; MOVF PORTA_BUF,w ;V1.6 for KEYOUT delay ; MOVWF PORTA ;both KEYOUT and PTT off PTTEND ;END of PTT RETURN ; PTTSET BCF PORTA_BUF,DELAY_PTT ;PTT Low=on BSF PORTA_BUF,KEY_OUT;V1.6 for KEYOUT delay ; MOVF PORTA_BUF,w ; MOVWF PORTA ;both KEYOUT and PTT on MOVLW PTTVAL1 ;init value MOVWF PTTDLY1 ; MOVLW PTTVAL2 ;Restart Timer MOVWF PTTDLY2 ; RETURN ;return ;******************************************************************** ; 以下SUBROUTINE ;******************************************************************** SLEEPINIT ;SLEEP Counter Initialize MOVLW SLEEPVAL16 ; MOVWF SLEEPDEV1 ; MOVLW SLEEPVAL100 ; MOVWF SLEEPDEV2 ; MOVLW SLEEPVAL60 ; MOVWF SLEEPDEVSEC ; MOVLW SLEEPVALMIN ; MOVWF SLEEPDEVMIN ; RETURN ; SLEEPDEC ;Decrement Sleep Counter DECFSZ SLEEPDEV1,f ;1/16 Divider GOTO SLEEPDECEND ; MOVLW SLEEPVAL16 ;Reload Value MOVWF SLEEPDEV1 ; DECFSZ SLEEPDEV2,f ;1/100 Divider GOTO SLEEPDECEND ; MOVLW SLEEPVAL100 ;Reload Value MOVWF SLEEPDEV2 ; DECFSZ SLEEPDEVSEC,f ;Sec Divider GOTO SLEEPDECEND ; MOVLW SLEEPVAL60 ;Reload Sec MOVWF SLEEPDEVSEC ; DECFSZ SLEEPDEVMIN,f ;Min Divider GOTO SLEEPDECEND ; MOVLW SLEEPVALMIN ;Reload Value MOVWF SLEEPDEVMIN ; BSF INT_FLAG,SLEEPFLAG ;SLEEP bit set SLEEPDECEND ; RETURN ; CLRSHIFTER ;Shifter Clear CLRF RAM0 ;初期値は0 CLRF RAM1 ; CLRF RAM2 ; CLRF RAM3 ; CLRF RAM4 ; CLRF RAM5 ; CLRF RAM6 ; CLRF RAM7 ; CLRF RAM8 ;初期値は0 CLRF RAM9 ; CLRF RAM10 ; CLRF RAM11 ; CLRF RAM12 ; CLRF RAM13 ; CLRF RAM14 ; CLRF RAM15 ; CLRF RAM16 ; CLRF RAM17 ; CLRF RAM18 ; CLRF RAM19 ; CLRF RAM20 ; CLRF RAM21 ; CLRF RAM22 ; CLRF RAM23 ; CLRF RAM24 ; CLRF RAM25 ; CLRF RAM26 ; CLRF RAM27 ; CLRF RAM28 ; CLRF RAM29 ; CLRF RAM30 ; CLRF RAM31 ; RETURN ; SHIFT2 ;Shift RAM1-RAM31 RLF RAM1,f ;16bit Delay RLF RAM2,f ;24bit Delay RLF RAM3,f ;32bit Delay RLF RAM4,f ;40bit Delay RLF RAM5,f ;48bit Delay RLF RAM6,f ;56bit Delay RLF RAM7,f ;64bit Delay RLF RAM8,f ;72bit Delay RLF RAM9,f ;80bit Delay RLF RAM10,f ;88bit Delay RLF RAM11,f ;96bit Delay RLF RAM12,f ;104bit Delay RLF RAM13,f ;112bit Delay RLF RAM14,f ;120bit Delay RLF RAM15,f ;128bit Delay RLF RAM1,f ;16bit Delay RLF RAM2,f ;24bit Delay RLF RAM3,f ;32bit Delay RLF RAM4,f ;40bit Delay RLF RAM5,f ;48bit Delay RLF RAM6,f ;56bit Delay RLF RAM7,f ;64bit Delay RLF RAM8,f ;72bit Delay RLF RAM9,f ;80bit Delay RLF RAM10,f ;88bit Delay RLF RAM11,f ;96bit Delay RLF RAM12,f ;104bit Delay RLF RAM13,f ;112bit Delay RLF RAM14,f ;120bit Delay RLF RAM15,f ;128bit Delay RLF RAM16,f ;136bit Delay RLF RAM17,f ;144bit Delay RLF RAM18,f ;152bit Delay RLF RAM19,f ;160bit Delay RLF RAM20,f ;168bit Delay RLF RAM21,f ;176bit Delay RLF RAM22,f ;184bit Delay RLF RAM23,f ;192bit Delay RLF RAM24,f ;200bit Delay RLF RAM25,f ;208bit Delay RLF RAM26,f ;216bit Delay RLF RAM27,f ;224bit Delay RLF RAM28,f ;232bit Delay RLF RAM29,f ;240bit Delay RLF RAM30,f ;248bit Delay RLF RAM31,f ;256bit Delay RETURN ;Return ;******************************************************************** END ;プログラムおわり ;********************************************************************