;*********************************************************** ; Ver1.0 2003.10.19 KOKURA ; Ver1.3 2003,10.23 入力ピンをPB4,5に変更 ; Ver1.4 2003,10.23 ポートチェンジ割り込みに書き換え ; MPLABでコンパイル可能 ; Configuration Bit →OSC XT (10MHz)、WDT OFF ; AKI-PIC18キャリーボードキットでテスト ;*********************************************************** LIST P=PIC16F84 INCLUDE "P16F84.INC" __CONFIG _HS_OSC & _WDT_OFF ;****************************** ; 変数レジスタ割付定義 ;****************************** #define rs1rxb PORTA, 4 ;RS-232C データ入力用ポート(porta, 4) #define rs1txb PORTA, 3 ;RS-232C データ出力用ポート(porta, 3) ;定数 btime はRS-232C のボーレイトから以下の式で計算できます。 ;btime ={(動作周波数(Hz) ÷ 転送スピード(bps) ÷4)−10}÷3 btime equ 53h ;9600bps 10MHz 時のウエイトタイム 53h = d'83' ;btime equ aah ;9600bps 20MHz 時のウエイトタイム ;btime equ 1fh ;9600bps 4MHz 時のウエイトタイム ;btime equ 28h ;19200bps 10MHz 時のウエイトタイム ;btime equ 0eh ;19200bps 4MHz 時のウエイトタイム STATUS EQU 3 PORTA EQU 5 PORTB EQU 6 TRISA EQU H'85' TRISB EQU H'86' rs EQU H'0C' ;ビットタイムの作業用 flg EQU H'0D' ;受信データ有り無しフラグ cn EQU H'0E' ;8ビットシフトの作業用 rxd EQU H'0F' ;受信データ txd EQU H'10' ;送信データ PIN1 EQU H'13' ;PIN1にch1のパルス幅が入る PIN2 EQU H'14' ;PIN2にch2のパルス幅が入る Ready_Flg EQU H'15' ;Readyフラグ W_TEMP EQU H'16' ;Wレジスタ待避 STATUS_TEMP EQU H'17' ;STATUSレジスタ待避 ;******************************** ; メインプログラム ;******************************** ORG 0 ;Reset Start GOTO MAIN ORG 04H GOTO INTR MAIN BCF INTCON,GIE ;割り込み全禁止 CALL PORT_INI BCF INTCON,RBIF ;ポートチェンジ割り込みフラグリセット BSF INTCON,RBIE ;ポートチェンジ割り込み許可 BSF INTCON,GIE ;割り込み許可 MAIN1 BCF INTCON,GIE ;割り込み禁止 MOVLW 0 MOVWF PIN1 ;カウンター1初期化 MOVWF PIN2 ;カウンター2初期化 MOVWF Ready_Flg ;Readyフラグリセット BSF INTCON,GIE ;割り込み許可 LOOP1 BTFSS Ready_Flg,4 ;RB4のReadyフラグがオンに成るまでループ GOTO LOOP1 LOOP2 BTFSS Ready_Flg,5 ;RB5のReadyフラグがオンに成るまでループ GOTO LOOP2 ; CH1,CH2のカウンター値を読み取り送信 movlw 01h movwf txd call rs1tx MOVF PIN1,W ;PIN1の内容をWレジスタに書き込む movwf txd call rs1tx movlw 04h movwf txd call rs1tx MOVF PIN2,W ;PIN2の内容をWレジスタに書き込む movwf txd call rs1tx goto MAIN1 ;*************************************** ; ポートチェンジ割り込み(RB4-RB7) ;*************************************** ;レジスタ退避 ;注意: Z フラグが影響しないようにSWAPF 命令を使用します。 ;FSR レジスタ、PCLATCH レジスタなども保存が必要な場合があります。 INTR PUSH MOVWF W_TEMP ; Wレジスタ退避 SWAPF STATUS, W ; Swap status to be saved into W MOVWF STATUS_TEMP ; statusを退避 COUNT1 BTFSC Ready_Flg,4 ;RB4のReadyフラグが1ならCOUNT2に GOTO COUNT2 BTFSS PORTB,4 ;RB4がLoならCONT2に GOTO COUNT2 PULSIN11 ;RB4のパルス幅を測定 CALL TIM20 ;20サイクル待ち (19+2)(44+2) INCF PIN1,1 ;PIN1=PIN1+1 (22)(47) BTFSC PORTB,4 ;ONの時は (23)(48) GOTO PULSIN11 ;カウント継続 (25)(50) BSF Ready_Flg,4 ;カウントが終了したらReadyフラグを1にして GOTO COUNT3 ;割り込みから抜ける COUNT2 BTFSC Ready_Flg,5 ;RB5のReadyフラグが1ならCOUNT3に goto COUNT3 BTFSS PORTB,5 ;RB5がLoならCOUNT3に goto COUNT3 PULSIN21 ;RB5のパルス幅を測定 CALL TIM20 ;20サイクル待ち (19+2) INCF PIN2,1 ;PIN1=PIN1+1 (22) BTFSC PORTB,5 ;ONの時は (23) GOTO PULSIN21 ;カウント継続 (25) BSF Ready_Flg,5 ;Readyフラグを1にして COUNT3 MOVF PORTB,F ;ポートBのダミー読み込み ;レジスタを戻す POP SWAPF STATUS_TEMP, W ;退避してたステータスとWレジスタを戻す MOVWF STATUS SWAPF W_TEMP, F SWAPF W_TEMP, W ;割り込みから復帰 BCF INTCON,RBIF ;ポートチェンジ割り込みフラグリセット RETFIE ;************************************ ; 入出力ピンモード初期化サブルーチン ;************************************ PORT_INI BSF STATUS,RP0 ;Set page 1 MOVLW B'11111111' ;RB all input MOVWF TRISB ;PortB set MOVLW B'11110111' ;RA3 output MOVWF TRISA ;PortA set bsf TRISA, 4 ;RS-232C データ入力用ポート(porta, 4) bcf TRISA, 3 ;RS-232C データ出力用ポート(porta, 3) BCF STATUS,RP0 ;Set Page 0 RETURN ;------------- 20サイクルタイマー(実際は19サイクル) TIM20 GOTO $+1 ;2 GOTO $+1 ;+2=4 GOTO $+1 ;+2=6 GOTO $+1 ;+2=8 GOTO $+1 ;+2=10 GOTO $+1 ;+2=12 GOTO $+1 ;+2=14 GOTO $+1 ;+2=16 NOP ;+1=17 RETURN ;+2=19 ;------------- 44サイクルタイマークロックが20MHzの時はこちらを使う TIM40 GOTO $+1 ;2 GOTO $+1 ;+2=4 GOTO $+1 ;+2=6 GOTO $+1 ;+2=8 GOTO $+1 ;+2=10 GOTO $+1 ;+2=12 GOTO $+1 ;+2=14 GOTO $+1 ;+2=16 GOTO $+1 ;+2=18 GOTO $+1 ;+2=20 GOTO $+1 ;+2=22 GOTO $+1 ;+2=24 GOTO $+1 ;+2=26 GOTO $+1 ;+2=28 GOTO $+1 ;+2=30 GOTO $+1 ;+2=32 GOTO $+1 ;+2=34 GOTO $+1 ;+2=36 GOTO $+1 ;+2=38 GOTO $+1 ;+2=40 GOTO $+1 ;+2=42 RETURN ;+2=44 ;******************************************** ;RS-232C 1文字送信サブルーチン ;MAX232C を使用 ;【呼出】送信文字を[txd]にセット ;【戻り】 ;【備考】 ;******************************************** rs1tx bcf rs1txb ;RS-232C データ出力用ポート(porta, 1) ビットクリア movlw btime ;btime → w スタートビット movwf rs ;btime → [rs] rs1tx_1 decfsz rs, F ;if(--[rs] == 0)Skip goto rs1tx_1 movlw 8 ;8 → w movwf cn ;8 → [cn] ビット位置 nop rs1tx_2 rrf txd, F ;(C,[txd])>>1 nop btfss STATUS, C ;if(C == 1)Skip ポートに出力 bcf rs1txb ;RS-232C データ出力用ポート(porta, 1) ビットクリア btfsc STATUS, C ;if(C != 1)Skip ポートに出力 bsf rs1txb ;RS-232C データ出力用ポート(porta, 1) ビットセット movlw btime ;btime → w movwf rs ;btime → [rs] rs1tx_3 decfsz rs, F ;if(--[rs] == 0)Skip goto rs1tx_3 ;1ビットのウエイト decfsz cn, F ;if(--[cn] == 0)Skip goto rs1tx_2 ;8ビット分繰り返し nop nop nop nop nop nop bsf rs1txb ;rs1txb を1に ストップビット movlw btime ;btime → w movwf rs ;btime → [rs] rs1tx_4 decfsz rs, F ;if(--[rs] == 0)Skip goto rs1tx_4 ;1ビットのウエイト return ;1文字送信終了、戻る END