;***************************************************************** ;1999年3月28日; ;プログラム名:K99.ASM Ver0.92 ; ; このプログラムは、後閑氏のサンプルを基に、以前から使っていた ; 自作エレキーのZ80プログラムを、PIC用に書き換えたものです。 ; ;PICマイコンのポートでRSー232C信号を読み込んでいるため ;9600BPSではエラーが起こるので1200BPSで使用しています。 ;まだ、冗長度の有りすぎる記述や、レジスターの使い方をしています。 ;今後、最適化を加えて行きます。 ; ;JE3JLB 石原 ; ; ;アセンブラーは MPLAB 4.0 を使いました。 ;最新の MPLAB は、ホームページをご覧下さい。 ;EEPROMへの書き込みは、秋月電子のPICライターキットを ;使用しました。 ; ;PICは16F84を使用しています。 ;書き込み時のモードは、 ;WDT=OFF 発振=HSを設定しています。 ; ; Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | | | |ERROR |RECV |RXBUSY | |TXBUSY |RESULT ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; |RS_B4SP|RS_EC1 |NK_LCD |NK_SCD |USE |USE |USE |USE |ELKST ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; |USE |USE |USE |USE | |USE |USE |USE |RS_ING ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | | |_USE |_USE | | | | |MPIOB ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; ;以下は、後閑氏のソースファイルの記述の一部です。 ; ; The parameters are defined as shown below. ; BAUDRATE : Desired baud rate 300 to 9600 at 10MHz clock. ; 5=300bps 3=1200bps 2=2400bps 1=4800bps 0=9600bps ; ; The status register "RESULT"'s bits are explained below. ; BIT0 : TXBUSY (1 is tarnsimission in progress) ; BIT1 : unused ; BIT2 : RXBUSY (1 indicates in receive process) ; BIT3 : RECV (1 indicates there are received data) ; BIT4 : ERROR (1 indicates any error) ; The flag of "BUSY" is send/receive busy flag,check before use. ; ;***************************************************************** ; LIST P=PIC16F84 ;PIC16F84 を宣言 include "p16f84.inc" ;MAPLAB use ;16C73A.INC より転用して定義:間接アドレス(受信バッファに使用する) INDF EQU H'0000' ;間接読み出し・書き込み時の仮想レジスター FSR EQU H'0004' ;間接データメモリ・ポインタ ;;;************************************ ;;; ;;; ____==______======__==__======______==__==______________ ;;; ;;; D D D D D D D S ;;; O O O A A A O P ;;; 1 2 4 3 4 6 2 4 ;;; 0 0 0 0 0 0 0 0 ;;; ;************************************* ; Define constant module 後閑氏の記述のまま。 ;************************************* #DEFINE TXBUSY RESULT,0 ;sending #DEFINE RXBUSY RESULT,2 ;receiving #DEFINE RECV RESULT,3 ;receive end #DEFINE ERROR RESULT,4 ;error bit ;**** Define Variables ***** RESULT EQU 0CH ;current status WREG EQU 0DH ;wreg save area SREG EQU 0EH ;status reg save area BITCNT EQU 0FH ;send bit counter EXTRA EQU 10H ;stop bit flag TXREG EQU 11H ;send data buffer RXREG EQU 12H ;receive data buffer CNT2 EQU 13H ;counter for delay ;- 追加記述部 -------------------------------------------------- #DEFINE NK_SCD ELKST,4 ;NEXT KET STATUS SCD #DEFINE NK_LCD ELKST,5 ;NEXT KEY STATUS LCD #DEFINE RS_EC1 ELKST,6 ;RS ESC FLAG #DEFINE RS_B4SP ELKST,7 ;RS 一つ前のスペースを記憶 ELKST EQU CNT2+1h ;Elekey status CLCT EQU CNT2+2h ;Clock counter value W_TEMP EQU CNT2+3H ;外部(RB0)割込み発生時のWレジ退避用 ST_TEMP EQU CNT2+4H ;外部(RB0)割込み発生時のSTATUSレジ退避用 M_DO10 EQU CNT2+5H ;ドット単位時間 M_DO20 EQU CNT2+6H ;ドット終了文字の 確保時間 DO+DOSP M_DO40 EQU CNT2+7H ;ドット終了文字の 語間 M_DA30 EQU CNT2+8H ;ダッシュ単位時間 M_DA40 EQU CNT2+9H ; ダッシュ終了文字の 確保時間 DA+DASP M_DA60 EQU CNT2+0AH ;ダッシュ終了文字の 語間 M_SP40 EQU CNT2+0BH ;語間の時間(スペース) ; IB_IP EQU CNT2+0CH ;入力バッファーの現在ポイント(入力用) IB_OP EQU CNT2+0DH ;入力バッファーの現在ポイント(出力用) IB_LG EQU CNT2+0EH ;入力バッファーの現在文字数 RS_NOW EQU CNT2+0FH ; 1 Byte RS,処理中のテンポラリィ RS_ING EQU CNT2+10H ;RS-232C 処理中 ステータス RSTMP EQU CNT2+11H ;RS-232C 処理のテンポラリー MPIOB EQU CNT2+012H ;PIOBのメモリー上のイメージ IB_ST_A EQU CNT2+13H ;受信バッファ スタートアドレス IB_ED_A EQU 04FH ;受信バッファ エンドアドレス IB_L EQU IB_ED_A - IB_ST_A + 1 ;バッファー長 ; ;----------- 標準値 -------------------------------------------------- MI1 equ 1 ;Mark interval clock count 基準 MI04 equ (MI1)*4 ;Mark interval x 04 MI10 equ (MI1)*10 ;Mark interval x 10 MI20 equ (MI1)*20 ;Mark interval x 20 MI30 equ (MI1)*30 ;Mark interval x 30 MI40 equ (MI1)*40 ;Mark interval x 40 ;;;******************************** ;;;    スタート ;;;******************************** ORG 0 ;reset GOTO START ;電源ON時のスタート ORG 4 ;割り込み発生時のアドレス ;;;; GOTO INTERRUPT ;PIC TMR0 の割り込み。 GOTO ELEKEY ;スピード調整の割り込み ORG 08H ;code ;************************************* START BCF INTCON,GIE ;Interrupt disable CLRF RESULT ;Reset status CALL PORT_INI ;Initialise CALL KEY_SET ;モールスコード長を設定。 BCF PORTA,2 ;DEBUG用(未使) MAIN BSF INTCON,INTE ;RB0/INT 許可 BCF INTCON,INTF ;RB0/INT 割り込みフラグをクリヤー ;RS−232C入力バッファー、初期設定 ; CW0: BCF INTCON,GIE ;割込禁止 MOVLW IB_ST_A ;スタートアドレス MOVWF IB_IP ; MOVWF IB_OP ; CLRF RESULT ; BCF INTCON,T0IF ; CLRF RS_NOW ; CLRF RS_ING ;RS232C 処理中ステータス = 00H CLRF IB_LG ;バッファー文字数 = 0 CLRF RSTMP ; BSF INTCON,GIE ;割込許可 CALL GETCHAR ;受信スタート CW1 MOVF IB_LG,W ; SUBLW IB_L - 5 ;入力文字数手前 5CHR BTFSC STATUS,C ;SUBLW PIC は正でC=1 BCF PORTA,0 ;CTS=ON CW11 ;**** Received data process BTFSS RECV ;受信中でなかったら CALL GETCHAR ;受信スタート ;ここにパドルの読み込み処理を入れる ;---------パドル入力処理------------------------- KEYINT ;パドル ポートを入力 BTFSC PORTB,4 ;dot? Dot Yes=0 GOTO KEYIN2 ; BCF MPIOB,4 ;ドットビット4を0に KEYIN2 BTFSC PORTB,5 ;ダッシュか? GOTO KEYIN_END ; BCF MPIOB,5 ; KEYIN_END MOVF MPIOB,W ; XORLW 0FFH ; BTFSS STATUS,Z ;パドル無し? GOTO CW0 ;パドル有り GOTO CW1 ;----------------------------------------------------------- ;キー信号送出時間、初期設定(基本) KEY_SET MOVLW MI10 ;単位10 MOVWF M_DO10 ADDLW MI10 ;単位20 MOVWF M_DO20 ADDLW MI20 ;単位40 MOVWF M_DO40 MOVLW MI30 ;単位30 MOVWF M_DA30 ADDLW MI10 ;単位40 MOVWF M_DA40 ADDLW MI20 ;単位60 MOVWF M_DA60 MOVLW MI40 ;単位40 スペース(文字間+40=70) MOVWF M_SP40 ;----------------------------------------------------------------- ;設定SWによる (ダッシュ長) Dot:Dash 1:3 --> 1:3.4 に伸ばす。 BTFSC PORTB,1 ;IF PORT B 1BIT=Low なら設定 GOTO SWSET_END1 MOVLW MI04 ;4単位プラス ADDWF M_DA30,F ; ADDWF M_DA40,F ; ADDWF M_DA60,F ;DASH (+4) ;-------------------------------------------------------------------- SWSET_END1 ;設定SWによる (文字間長) 文字間 3.0 --> 3.4 に伸ばす。 BTFSC PORTB,2 ;IF PORT B 2bit=Low なら設定 GOTO SWSET_END2 MOVLW MI04 ;4単位プラス ADDWF M_DO40,F ; ADDWF M_DA60,F ;DASH (+4) ;-------------------------------------------------------------------- SWSET_END2: ;------------------------------------ スペース長 セット ;設定SWによる (スペース長 セット) スペース 7.0 --> 6.0 に短縮する。 BTFSC PORTB,3 ;IF PORT B 3bit=Low なら設定 GOTO SWSET_END3 MOVLW MI10 ;10単位マイナス SUBWF M_SP40,F ; SWSET_END3 ;----------------------------------------------------------------- ;その他の、設定 CLRF ELKST ;ステータスバッファー初期化 MOVLW 0FFH MOVWF MPIOB ;B'11111111' CLRF CLCT ; CALL KOUT0 ;キー出力をOFF RETURN ;---------------------------------------------------------------- ;CW DEC PATTERN FOR CW.ASM ;英数字のみに対応 ; 92/06/06 12:14 JE3JLB ; 99/03/20 PICマイコン用に書き換え ;---------------------------------------------------------------- CW_TBL ADDWF PCL,F ;JMP PC+W RETLW B'10000000' ;20H SPACE RETLW B'11111111' ;21H RETLW B'11111111' ;22H RETLW B'01001010' ;23H " RETLW B'11111111' ;24H $ RETLW B'11111111' ;25H % RETLW B'11111111' ;26H & RETLW B'01111010' ;27H ' RETLW B'10110100' ;28H ( RETLW B'10110110' ;29H ) RETLW B'11111111' ;2AH * RETLW B'01010100' ;2BH + RETLW B'11001110' ;2CH , RETLW B'10000110' ;2DH - RETLW B'01010110' ;2EH . RETLW B'10010100' ;2FH / RETLW B'11111100' ;"0" ;30H RETLW B'01111100' ;"1" RETLW B'00111100' ;"2" RETLW B'00011100' ;"3" RETLW B'00001100' ;"4" RETLW B'00000100' ;"5" RETLW B'10000100' ;"6" RETLW B'11000100' ;"7" RETLW B'11100100' ;"8" RETLW B'11110100' ;"9" RETLW B'11111111' ;3AH : RETLW B'11111111' ;3BH ; RETLW B'11111111' ;3CH < RETLW B'10001100' ;3DH = RETLW B'11111111' ;3EH > RETLW B'00110010' ;3FH ? RETLW B'11111111' ;40H @ RETLW B'01100000' ;"A", RETLW B'10001000' ;"B", RETLW B'10101000' ;"C", RETLW B'10010000' ;"D", RETLW B'01000000' ;"E", RETLW B'00101000' ;"F", RETLW B'11010000' ;"G", RETLW B'00001000' ;"H", RETLW B'00100000' ;"I", RETLW B'01111000' ;"J", RETLW B'10110000' ;"K", RETLW B'01001000' ;"L", RETLW B'11100000' ;"M", RETLW B'10100000' ;"N", RETLW B'11110000' ;"O", RETLW B'01101000' ;"P", RETLW B'11011000' ;"Q", RETLW B'01010000' ;"R", RETLW B'00010000' ;"S", RETLW B'11000000' ;"T", RETLW B'00110000' ;"U", RETLW B'00011000' ;"V", RETLW B'01110000' ;"W", RETLW B'10011000' ;"X", RETLW B'10111000' ;"Y", RETLW B'11001000' ;"Z", RETLW B'11111111' ;5BH [ RETLW B'11111111' ;5CH \ RETLW B'11111111' ;5DH ] RETLW B'11111111' ;5CH ^ RETLW B'11111111' ;5FH _ RETLW B'11111111' ;60H ` RETLW B'01100000' ;"a", RETLW B'10001000' ;"b", RETLW B'10101000' ;"c", RETLW B'10010000' ;"d", RETLW B'01000000' ;"e", RETLW B'00101000' ;"f", RETLW B'11010000' ;"g", RETLW B'00001000' ;"h", RETLW B'00100000' ;"i", RETLW B'01111000' ;"j", RETLW B'10110000' ;"k", RETLW B'01001000' ;"l", RETLW B'11100000' ;"m", RETLW B'10100000' ;"n", RETLW B'11110000' ;"o", RETLW B'01101000' ;"p", RETLW B'11011000' ;"q", RETLW B'01010000' ;"r", RETLW B'00010000' ;"s", RETLW B'11000000' ;"t", RETLW B'00110000' ;"u", RETLW B'00011000' ;"v", RETLW B'01110000' ;"w", RETLW B'10011000' ;"x", RETLW B'10111000' ;"y", RETLW B'11001000' ;"z", RETLW B'11111111' ;7BH RETLW B'11111111' ;7CH RETLW B'11111111' ;7DH RETLW B'11111111' ;7EH RETLW B'11111111' ;7FH ;;;//////////////////////////////////////////////////////////////////// END_PAT RETLW B'10000000' ;駄目押し的挿入 ; ;----------タイマー(NE555によるキースピードタイミング割込)----- ; EKEND MOVLW 0FFH ;割込リターン処理 MOVWF MPIOB ; SWAPF ST_TEMP,W ;ステータスを戻す MOVWF STATUS ; SWAPF W_TEMP,F ;Wレジを戻す SWAPF W_TEMP,W ; ;;; BSF INTCON,INTE ;割り込みの許可フラグ GOTO INTERRUPT ;RETFIE ;割込許可のリターン ELEKEY BTFSS INTCON,INTF ;RB0/INT? GOTO INTERRUPT ;RETFIE ;NOT -> RETURN IE BCF INTCON,INTF ;RESET INTF ;;; BCF INTCON,INTE ;RB0 割り込みの中止 ;;; BSF INTCON,GIE ;RS232Cの割り込みに備える ; MOVWF W_TEMP ;Wレジ退避 SWAPF STATUS,W ;ステータス取り出し MOVWF ST_TEMP ;ステータス退避 ;Check elekey status ;ELKST エレキーステータス 1で有り BTFSC ELKST,0 ;Dot モードか GOTO SCD ;Yes,=1 BTFSC ELKST,1 ;Dash モードか GOTO LCD ;Yes,=1 BTFSS MPIOB,4 ;dot comming? DOT=B4 0 GOTO SMODE ;Yes,=0 BTFSS MPIOB,5 ;dash comming? DASH=B5 0 GOTO LMODE ;Yes,=0 ;RS−232Cの処理 MOVF RS_ING,W ;CP 00H RS_ING -> W BTFSC STATUS,Z ;RS 処理中か? ZERO = No GOTO RSCHRIN ; BTFSC RS_ING,7 ; GOTO RS_SPA_2 ;スペース 期間 BTFSC RS_ING,0 ; GOTO RS_DOT_2 ;DOT MARK 0 ~ 10 BTFSC RS_ING,1 GOTO RS_DOT_2 ;DOT SPACE 10 ~ 20 BTFSS RS_ING,2 GOTO RSINGBIT2 ;IF 0 DOT SPACE 20 ~ 40 MOVLW 080H SUBWF RS_NOW,W ;終了フラグ 1000 0000 bit BTFSC STATUS,Z GOTO RS_IB_1 ; MOVLW 00H SUBWF RS_NOW,W ;終了フラグ 0000 0000 bit BTFSC STATUS,Z GOTO RS_IB_1 BCF STATUS,C ;キャリーOFF RLF RS_NOW,F BTFSC STATUS,C GOTO RS_DAS GOTO RS_DOT RS_IB_1 BTFSS RS_EC1 ;CMP エスケ−プ フラグ GOTO RS_DOT_2 CLRF RS_ING ; BCF RS_EC1 ; CLRF CLCT ;RESET CLOCK COUNTER GOTO ELEKEY_E RSINGBIT2 BTFSC RS_ING,4 ; GOTO RS_DAS_2 ;DASH MARK 0 ~ 30 BTFSC RS_ING,5 ; GOTO RS_DAS_2 ;DASH SPACE 30 ~ 40 BTFSS RS_ING,6 ; GOTO RSINGBIT3 ;DASH SPACE 40 ~ 60 MOVLW 080H SUBWF RS_NOW,W ;終了フラグ 1000 0000 bit BTFSC STATUS,Z GOTO RS_IB_2 MOVLW 00H SUBWF RS_NOW,W ;終了フラグ 0000 0000 bit BTFSC STATUS,Z GOTO RS_IB_2 BCF STATUS,C ;キャリーOFF RLF RS_NOW,F BTFSC STATUS,C GOTO RS_DAS GOTO RS_DOT RS_IB_2 BTFSS RS_EC1 ;エスケープ フラグ GOTO RS_DAS_2 ;NO ZERO RSINGBIT3 CLRF RS_ING BCF RS_EC1 ; CLRF CLCT ;RESET CLOCK COUNTER GOTO ELEKEY_E RSCHRIN ;入力文字有りか (1 Byte) MOVF IB_LG,W ;CMP 0 BTFSC STATUS,Z GOTO ELEKEY_E ;ZERO RS 入力文字無し RSCHRIN_2 DECF IB_LG,F ;入力文字数を減算 (1 Byte) MOVF IB_OP,W MOVWF FSR ;ADR POINTER MOVF INDF,W ;FSRを使った間接読みだし (INDF)->W ANDLW 07FH ;00H to 07FH MOVWF RSTMP ; INCF IB_OP,F ;現在のアドレス + 1 MOVLW IB_ED_A ;エンドアドレスをWレジに SUBWF IB_OP,W ;出力(取りだし)のアドレスが BTFSS STATUS,Z ;最終アドレスを超えていないか? GOTO RSCHRIN_21 ;超えていない。GOTO MOVLW IB_ST_A ;超えたので、 MOVWF IB_OP ;スタートアドレスをセット RSCHRIN_21 MOVLW '_' SUBWF RSTMP,W BTFSC STATUS,Z ; GOTO RS_ESC ;COMP ZERO MOVLW ' ' SUBWF RSTMP,W BTFSC STATUS,Z GOTO RS_SPA ;COMP ZERO ;20H〜7FHまでに制限 MOVLW 20H SUBWF RSTMP,W ; W - 20H -->W BTFSS STATUS,C GOTO ELEKEY_E ; is < 20H 'C' CALL CW_TBL ;CHR to CW CODE MOVWF RSTMP ;CODE を一時退避 MOVLW 0FFH SUBWF RSTMP,W BTFSC STATUS,Z ;NOT 0FFH -> SKIP GOTO MUKOU_CODE ;無効コード MOVF RSTMP,W MOVWF RS_NOW MOVLW 080H ; SUBWF RS_NOW,W ;終了フラグ 1000 0000 bit BTFSC STATUS,Z ; GOTO RSBIGN_E ; MOVLW 00H ; SUBWF RS_NOW,W ;終了フラグ 0000 0000 bit BTFSC STATUS,Z ; GOTO RSBIGN_E ; BCF STATUS,C ;キャリーOFF RLF RS_NOW,F ;SLA BTFSC STATUS,C GOTO RS_DAS ;'C' GOTO RS_DOT RSBIGN_E CLRF RS_ING ;(RS_ING)=0 MUKOU_CODE ELEKEY_E GOTO EKEND ;No,then go to end ;----------------------------------------------------------------- RS_ESC: ;エスケープ文字の処理 [_] CLRF CLCT ;CLCT RESET BSF RS_EC1 ; ;_HH _AR _BK etc. BCF RS_B4SP ;直前スペースをクリアー GOTO ELEKEY_E ;----------------------------------------------------------------- RS_SPA ;スペースコード入力時の処理 CLRF CLCT ;CLCT RESET MOVLW 80H MOVWF RS_ING ; CALL KOUT0 ;駄目押し RS_SPA_2 MOVF M_SP40,W ;70 - 30 = 40 SUBWF CLCT,W ; BTFSS STATUS,Z GOTO RS_SPA_9 CLRF RS_ING CLRF CLCT ;CLCT RESET GOTO RS_SPA_E RS_SPA_9 INCF CLCT,F ;COUNTER UP RS_SPA_E GOTO ELEKEY_E ;----------------------------------------------------------------- RS_DOT CLRF CLCT ;CLCT RESET MOVLW B'00000001' MOVWF RS_ING CALL KOUT1 RS_DOT_2 MOVF M_DO10,W ;=10 SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DOT_21 CALL KOUT0 BCF STATUS,C ;キャリーOFF RLF RS_ING,F ;SLA GOTO RS_DOT_9 RS_DOT_21 MOVF M_DO20,W SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DOT_3 BCF STATUS,C RLF RS_ING,F GOTO RS_DOT_9 RS_DOT_3 MOVF M_DO40,W SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DOT_9 CLRF RS_ING CLRF CLCT GOTO RS_DOT_E RS_DOT_9 INCF CLCT,F RS_DOT_E GOTO ELEKEY_E ;----------------------------------------------------------------- RS_DAS CLRF CLCT ;CLCT RESET MOVLW B'00010000' MOVWF RS_ING CALL KOUT1 RS_DAS_2 MOVF M_DA30,W SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DAS_21 CALL KOUT0 BCF STATUS,C ;キャリーOFF RLF RS_ING,F ;SLA GOTO RS_DAS_9 RS_DAS_21 MOVF M_DA40,W SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DAS_3 BCF STATUS,C RLF RS_ING,F GOTO RS_DAS_9 RS_DAS_3 MOVF M_DA60,W SUBWF CLCT,W BTFSS STATUS,Z GOTO RS_DAS_9 CLRF RS_ING CLRF CLCT GOTO RS_DAS_E RS_DAS_9 INCF CLCT,F RS_DAS_E GOTO ELEKEY_E ;----------------------------------------------------------------- ;--------SCD ------ドット出力中 SCD ;キーSWチェック BTFSC MPIOB,5 ;ダッシュ? GOTO SCD1 ;DOT BSF NK_LCD ;次のキーステータスをセット SCD1 MOVF M_DO10,W SUBWF CLCT,W ; BTFSS STATUS,Z ;ZERO? FLAG=1 THEN SKIP GOTO SCD2 ;NO ZERO ;ZERO=TURU BCF ELKST,2 ;reset ELKST CALL KOUT0 ;OUT OFF SCD2 MOVF M_DO20,W ; SUBWF CLCT,W ; BTFSS STATUS,Z ; GOTO SCD3 ; ;RESET ELKST BCF ELKST,1 ;LCD BCF ELKST,0 ;SCD BSF ELKST,3 ;SPACE CLRF CLCT ;CLCT CLEAR ;CHECK NEXT KEY STATUS BTFSC NK_LCD ;LCD? GOTO LMODE ;YES LMODE GOTO EKEND ; SCD3 INCF CLCT,F ;CLCT + 1 GOTO EKEND ; ;--------LCD -----------ダッシュ出力中 LCD ;キーSWチェック BTFSC MPIOB,4 ;ドット? GOTO LCD1 ;dash BSF NK_SCD ;次のキーステータスをセット LCD1 MOVF M_DA30,W SUBWF CLCT,W ; BTFSS STATUS,Z ;ZERO? FLAG=1 THEN SKIP GOTO LCD2 ;NO ZERO ;ZERO=TURU BCF ELKST,2 ;reset ELKST CALL KOUT0 ;OUT OFF LCD2 MOVF M_DA40,W ; SUBWF CLCT,W ; BTFSS STATUS,Z ; GOTO LCD3 ; ;RESET ELKST BCF ELKST,1 ;LCD BCF ELKST,0 ;SCD BSF ELKST,3 ;SPACE CLRF CLCT ;CLCT CLEAR ;CHECK NEXT KEY STATUS BTFSC NK_SCD ;SCD? GOTO SMODE ;YES SMODE GOTO EKEND ; LCD3 INCF CLCT,F ;CLCT + 1 GOTO EKEND ; ;---------set SCD mode---------------------------ドット入力有り SMODE ;set ELKST BSF ELKST,0 ;SCD BSF ELKST,2 ;mark CALL KOUT1 ;OUT KEY_SW CLRF CLCT ;reset clock counter MOVLW 0CFH ; ANDWF ELKST,F ;reset NKST_FLG GOTO EKEND ; ;---------set LCD mode---------------------------ダッシュ入力有り LMODE ;set ELKST BSF ELKST,1 ;LCD BSF ELKST,2 ;mark CALL KOUT1 ;OUT KEY_SW CLRF CLCT ;reset clock counter MOVLW 0CFH ; ANDWF ELKST,F ;reset NKST_FLG GOTO EKEND ; ;---------Monitor speaker on/off------------------キー出力 SUB. KOUT1 BCF STATUS,RP0 ;Set Page 0 MOVLW 80H ;Bit 7 ON Bit 6 OFF MOVWF PORTB RETURN KOUT0 BCF STATUS,RP0 ;Set Page 0 MOVLW 40H ;Bit 7 OFF Bit 6 ON MOVWF PORTB RETURN ;****************************************************************** ;ここより TIME10 までは、後閑氏の記述。(一部拡張) ;************** RS232C PROCESS ********************************** ;**** Preset Baud Rate **** ;************ Define constant for TIMER0 **** ; BaudRate PulseWidth Counter prescale TMR0(BITTMR) width ; 300 3333.33usec 8333 64(5) 130(7E) 3328usec ; 1200 833.33 2083 16(3) 130(7E)[7C] 832 ; 2400 416.67 1041 8(2) 128(80) 409 ; 4800 208.33 521 4(1) 124(84) 198 ; 9600 104.17 260 2(0) 122(86)[6A] 99 ; This TMR0 RATE is used for BAUDRATE parameter as prescaler. ;9600BPS IS BAUDRATE=0 BITTMR=86H BITTMR1=6AH ;1200BPS IS BAUDRATE=3 BITTMR=7EH BITTMR1=7CH ;1200BPSのBITTMR1の常数は、正確では有りません。1999.3.28 JE3JLB ; ; ;BAUDRATE:boud rate 300 to 9600 at 10MHz clock. ; 5=300bps 3=1200bps 2=2400bps 1=4800bps 0=9600bps ; BAUDRATE SET 3 ;preset to 9600bps BITTMR SET 07EH ;TMR0 DATA -122 BITTMR1 SET 07CH ;TMR0 DATA -150 ; ;**************************************** ; Interrupt process module ;**************************************** ;**** register restore and return RESTORE SWAPF SREG,W ;get saved status MOVWF STATUS SWAPF WREG,F ;get saved wreg SWAPF WREG,W RETFIE INTERRUPT BTFSS INTCON,T0IF ;TMR0's interrupt? RETFIE ;not, NEXT INT BCF INTCON,T0IF ;reset T0IF bit ;**** save W register & status register MOVWF WREG ;save w reg SWAPF STATUS,W ;status to wreg MOVWF SREG ;save status BTFSC TXBUSY ;In send mode GOTO TXNEXT ;send next bit BTFSC RXBUSY ;In receive mode GOTO RXNEXT ;receive next bit GOTO STARTBIT ;must be start bit ;************************************ ; Transmission process module ;************************************ PUTCHAR BSF TXBUSY ;set busy bit MOVLW 8 ;bit count MOVWF BITCNT ;reset bit counter MOVLW 1 MOVWF EXTRA ;set stopbit flag CALL TXSTART ;start send dumy bit BCF INTCON,T0IF ;reset flag BSF INTCON,T0IE ;permit TMR0 interrupt RETFIE ;**** Send start bit **** TXSTART CLRF TMR0 ;reset timer BSF STATUS,RP0 ;page 1 CLRWDT MOVLW BAUDRATE ;set prescaler MOVWF OPTION_REG BCF STATUS,RP0 ;page 0 BCF PORTA,3 ;send start bit MOVLW BITTMR MOVWF TMR0 ;start timer RETURN ;****** Interrupt process for Send next bit ***** TXNEXT MOVLW BITTMR ;timer restart MOVWF TMR0 MOVF BITCNT,W ;end test BTFSC STATUS,Z GOTO STOPBIT ;send stop bit NEXTTXBIT DECF BITCNT,F ;BITCNT-1 BSF STATUS,C ;C on RRF TXREG,F ;shift send data BTFSS STATUS,C ;bit test BCF PORTA,3 ;0 out BTFSC STATUS,C BSF PORTA,3 ;1 out GOTO RESTORE ;return ;**** Send Stop bit **** STOPBIT MOVF EXTRA,W BTFSC STATUS,Z ;end test GOTO DONE ;goto end DECF EXTRA,F ;end of stop BSF PORTA,3 ;send 1 for stop bit GOTO RESTORE ;return ;*** all end of send **** DONE BCF INTCON,T0IE ;Disable interrupt BCF TXBUSY ;reset busy flag GOTO RESTORE ;return ;************************************************************** ;************************************* ; Receiving process module ;************************************* GETCHAR BSF RECV ;wait bit on MOVLW 9 MOVWF BITCNT ;set bit counter CLRF RXREG ;clear buffer BCF ERROR ;clear error bit ;**** Start bit wait **** CLRF TMR0 ;timer reset BSF STATUS,RP0 ;page 1 CLRWDT ;clear WDT MOVLW 038H ;set to external WDT MOVWF OPTION_REG BCF STATUS,RP0 ;page 0 MOVLW 0FFH MOVWF TMR0 ;set timer for start bit BCF INTCON,T0IF BSF INTCON,T0IE ;enable TMR0 interrupt RETFIE ;wait interrupt ;**** Start bit process **** STARTBIT CLRWDT ;timer reset CALL TIME10 ;Delay 10usec BTFSC PORTA,4 ;retry GOTO NOISE ;not start bit BSF RXBUSY ;set busy ; CLRF TMR0 ;reset timer for next bit BSF STATUS,RP0 ;page 1 MOVLW BAUDRATE ; MOVWF OPTION_REG BCF STATUS,RP0 ;page 0 MOVLW BITTMR1 ;set bit width over 1.1bit MOVWF TMR0 GOTO RESTORE ;return ;*** missing start bit **** NOISE MOVLW 0FFH ;retry MOVWF TMR0 GOTO RESTORE ;return ;**** receive next bit **** RXNEXT BSF STATUS,RP0 ;page 1 CLRWDT ;reset timer MOVLW BAUDRATE MOVWF OPTION_REG BCF STATUS,RP0 ;page 0 MOVLW BITTMR MOVWF TMR0 ;restart timer DECFSZ BITCNT,F ;counter-1 GOTO NEXTRXBIT ;*** stop bit process *** BTFSS PORTA,4 ;stop bit check BSF ERROR ;not stop CALL RECEIVEPROCESS ;挿入位置を変更 BCF INTCON,T0IE ;inhibit interrupt BCF RXBUSY ;reset busy flag BCF RECV ;set receive complete ; ;**** If pararell process, insert call at this position **** GOTO RESTORE ;**** next bit process *** NEXTRXBIT BCF STATUS,C ;prepare bit for shift BTFSC PORTA,4 ;data=0 or 1? BSF STATUS,C ;1 case RRF RXREG,F ;set data to RXREG GOTO RESTORE ;***** 10usec delay routine TIME10 ;10usec MOVLW 7H MOVWF CNT2 T_LP2 DECFSZ CNT2,F ;2+3*7-1=22 GOTO T_LP2 RETURN ;22+1=23 ;****************** This is the end of RS232C modules ********************* ;****************************************************** ; ポート Initialize ルーチン ;****************************************************** ;----------------------------------------------------------------------------- PORT_INI ;修正 BSF STATUS,RP0 ;Set page 1 MOVLW 3FH ;only RB0,1,2,3,4,5 input MOVWF TRISB ;PortB set all output BCF OPTION_REG,NOT_RBPU ;プルアップをセット MOVLW 012H ;RA1,4 input MOVWF TRISA ;PortA set BCF OPTION_REG,INTEDG ;INT 立ち下がり BCF STATUS,RP0 ;Set Page 0 BSF PORTA,3 ;RS232 TX SET TO H BCF PORTA,0 ;CTS=ON BCF INTCON,RBIE ;INT OFF RB4 to 7 RETURN ;---------------------------------------------------------------------------- ;****************************************** ;---------RS−232C入力処理-------------------------- RECEIVEPROCESS BTFSS ERROR ;エラー判断 GOTO RECVP2 ; BSF PORTA,2 BCF ERROR ;エラービットを0にして復帰 RETURN ; RECVP2 ;; MOVF RXREG,W MOVF IB_LG,W ; SUBLW IB_L - 5 ;入力文字数手前 5CHR BTFSC STATUS,C ;OVER SKIP GOTO RP2 BSF PORTA,0 ;CTS=OFF RP2 MOVLW ' ' ;SPACE SUBWF RXREG,W ; BTFSS STATUS,Z ; GOTO INTTEST_92 ;NZ BTFSC RS_B4SP ;一つ前の文字がスペースか GOTO INTTEST_E ;Z BSF RS_B4SP ;前スペースにフラグを立てる GOTO INTTEST_93 ; INTTEST_92 BCF RS_B4SP ;前スペースにフラグをクリアー INTTEST_93 MOVF IB_IP,W ;入力ポインターで格納 MOVWF FSR ; MOVF RXREG,W MOVWF INDF ;DATA 相対アドレス INCF IB_IP,F ;+1 MOVLW IB_ED_A ;エンドアドレスをWレジに SUBWF IB_IP,W ;入力(格納)のアドレスが BTFSS STATUS,Z ;最終アドレスを超えていないか? GOTO INTTEST_21 ;超えていない。GOTO MOVLW IB_ST_A ;超えたので、 MOVWF IB_IP ;スタートアドレスをセット INTTEST_21 INCF IB_LG,F ;入力数カウンター+1 INTTEST_E RETURN ;B4 RETI ;---------------------------------------------------------- END