;*********************************************************************** ; 汎用8桁セグメント発光ダイオード制御 ;  4桁、6桁、8桁の表示桁数指定が可能 ;  表示テストモードを有しスイッチで指定すると開始する ;  データはシリアルで3バイトのバイナリデータ入力 ;*********************************************************************** LIST P=PIC16F873 INCLUDE "P16F873.INC" ;**************************** ; Define Constant or Work ;**************************** DIGIT12 EQU 021H ;Dispaly Data 1,2桁目 DIGIT34 EQU 022H ;Display Data 3,4桁目 DIGIT56 EQU 023H ;Dispaly Data 5,6桁目 DIGIT78 EQU 024H ;Dispaly Data 7,8桁目 CNT1 EQU 025H ;Timer Counter for CLOCK CNT2 EQU 026H ;Timer Counter for 10usec CNT3 EQU 027H ;Timer Counter for 5msec CNT4 EQU 028H ;Timer Counter for 1sec DAT_CNT EQU 029H ; COLUM EQU 02AH ;Display Digit Position TEMP EQU 02BH ;Tempolary Save Area SHIFT EQU 02CH ; NUMBER EQU 02DH ;Test Display Data BLANK EQU 02EH ;BLANK flag BYTE0 EQU 02FH ;受信データ3バイト目 BYTE1 EQU 030H ;受信データ2バイト目 BYTE2 EQU 031H ;受信データ1バイト目 WORK1 EQU 032H WORK2 EQU 033H ORG 0 ;******************************** ; Main Routine ;******************************** MAIN CLRF DIGIT12 CLRF DIGIT34 CLRF DIGIT56 CLRF DIGIT78 ;**** PORT A & B Initialize Routine  ********** CLRF ADCON0 ;STOP A/D CONV BSF STATUS,RP0 ;Page1へ MOVLW 07H MOVWF ADCON1 ;SET TO ALL DIGITAL MOVLW 0FFH MOVWF TRISA ;Port Aはすべて入力 CLRF TRISC ;PORT Cはすべて出力 MOVLW 1 MOVWF TRISB ;Port BはPB0のみ入力、他は出力 BCF STATUS,RP0 ;Page 0に戻る ;********* メインルーチン  ************* MAINLP BTFSS PORTA,0 ;テストモード判定 GOTO TEST_MODE ;テストモードへ BSF BLANK,0 ;BLANKフラグをセット ; BTFSS PORTA,3 ;8桁モードか? GOTO SKIP78 MOVLW 080H ;桁データ MOVWF COLUM MOVF DIGIT78,W ;7,8桁取り出し CALL DISP ;表示 SKIP78 BTFSS PORTA,2 ;6桁モードか? GOTO SKIP56 MOVLW 020H ;桁データ MOVWF COLUM MOVF DIGIT56,W ;5,6桁取り出し CALL DISP SKIP56 MOVLW 08H ;桁データ MOVWF COLUM MOVF DIGIT34,W ;3,4桁目取り出し CALL DISP ;表示 ; MOVLW 02H ;桁データ MOVWF COLUM MOVF DIGIT12,W ;1,2桁目取り出し CALL DISP ;表示 GOTO MAINLP ;Loop ;***************************************** ; 表示出力サブルーチン 1桁当たり約3Tmsec ; 入力は2桁のBCDコード ; データ受信チェックもタイマ内で同時に実行 ; PORTC:桁制御 ; PORTB:セグメント制御 ;***************************************** DISP MOVWF TEMP ;表示データ保存 SWAPF TEMP,W ;上位下位入れ替え ANDLW 0FH ;上位取り出し CALL GET_7SEG ;セグメントデータに変換 MOVWF PORTB ;ポートBへ出力 MOVF COLUM,W ;桁位置取り出し MOVWF PORTC ;桁出力 BCF STATUS,C ;Carry reset RRF COLUM,F ;次の桁へシフト CALL TIME2M ;Wait 5msec CLRF PORTC ;桁表示クリア MOVF TEMP,W ;下位取り出し ANDLW 0FH ; CALL GET_7SEG ;セグメントへ変換 MOVWF PORTB ;出力 MOVF COLUM,W ;桁制御 MOVWF PORTC CALL TIME2M CLRF PORTC ;桁クリア RETURN ;************************************* ; 3バイトバイナリの8桁BCDへの変換 ; マイクロチップ社のアプリケーションノートより ;************************************* BCD BCF STATUS,C ;キャリーリセット MOVLW 018H ;シフトカウンタ初期化 MOVWF SHIFT ;3バイト分32回の指定 CLRF DIGIT12 ;BCDデータエリア初期化 CLRF DIGIT34 CLRF DIGIT56 CLRF DIGIT78 ;**** 変換ループ処理 ********** LOOP RLF BYTE0,F ;shift BYTE to DIGIT RLF BYTE1,F RLF BYTE2,F RLF DIGIT12,F RLF DIGIT34,F RLF DIGIT56,F RLF DIGIT78,F DECFSZ SHIFT,F ;終了か? GOTO ADJST ;BCD調整処理へ RETURN ;***** BCD調整処理 ***** ADJST MOVF DIGIT12,W ;DIGIT12 adjust TO BCD CALL ADJBCD MOVWF DIGIT12 MOVF DIGIT34,W ;DIGIT34 adjust to BCD CALL ADJBCD MOVWF DIGIT34 MOVF DIGIT56,W ;DIGIT56 adjust to BCD CALL ADJBCD MOVWF DIGIT56 MOVF DIGIT78,W ;DIGIT78 adjust to BCD CALL ADJBCD MOVWF DIGIT78 GOTO LOOP ;**** 1桁BCD調整処理 **** ADJBCD MOVWF WORK1 ;save MOVLW 3 ;W+3 ADDWF WORK1,W MOVWF WORK2 BTFSC WORK2,3 ;Test W+3>7 MOVWF WORK1 ;>7 then W+3 else W MOVLW 030H ;W+30 ADDWF WORK1,W MOVWF WORK2 BTFSC WORK2,7 ;Test W+30>7* MOVWF WORK1 ;>70 then W+30 else W MOVF WORK1,W RETURN ;************************************************* ; BCDからセグメントへの変換 ; 0ビット目は未使用 ; ブランクチェックをしてブランクに変換する ;************************************************* GET_7SEG BTFSS BLANK,0 ;BLANKフラグのチェック GOTO NOTBLNK ;数字表示へ ANDLW 0FH ;0でないか? BTFSC STATUS,Z ;0 check RETLW 0 ;まだ0ならブランクを強制セット BCF BLANK,0 ;0でなければBLANKフラグリセット NOTBLNK ANDLW 0FH ;下位のみ取り出し ADDWF PCL,F ;Add to PC reg RETLW B'11111100' ;Code 0 RETLW B'01100000' ;Code 1 RETLW B'11011010' ;Code 2 RETLW B'11110010' ;Code 3 RETLW B'01100110' ;Code 4 RETLW B'10110110' ;Code 5 RETLW B'00111110' ;Code 6 RETLW B'11100000' ;Code 7 RETLW B'11111110' ;Code 8 RETLW B'11100110' ;Code 9 RETLW B'00000000' ;Code A RETLW B'00000000' ;Code B RETLW B'00000000' ;Code C RETLW B'00000000' ;Code D RETLW B'00000000' ;Code E RETLW B'00000000' ;Code F ;***************************************************** ; テスト表示サブルーチン ; テストは1秒ごとに0から9までのデータを全桁表示する ; テストはセンススイッチの1ビット目onでスタート ;***************************************************** TEST_MODE CLRF NUMBER ;表示データ初期化 CLRF BLANK ;RESET BLANKING FLAG TEST_LP1 MOVLW 03BH ;1秒タイマカウンタセット MOVWF CNT4 ;Store MOVF NUMBER,W ;表示データを全桁にセット MOVWF DIGIT78 SWAPF DIGIT78,F ADDWF DIGIT78,F ;99,88,... Set MOVF DIGIT78,W MOVWF DIGIT56 MOVWF DIGIT34 MOVWF DIGIT12 TEST_LP2 MOVLW 080H ;桁データ MOVWF COLUM MOVF DIGIT78,W ;7,8桁取り出し CALL DISP ;表示 MOVLW 020H ;桁データ MOVWF COLUM MOVF DIGIT56,W ;5,6桁取り出し CALL DISP MOVLW 08H ;桁データ MOVWF COLUM MOVF DIGIT34,W ;3,4桁目取り出し CALL DISP ;表示 MOVLW 02H ;桁データ MOVWF COLUM MOVF DIGIT12,W ;1,2桁目取り出し CALL DISP ;表示 ;******* 繰り返し DECFSZ CNT4,F ;約1秒の繰り返し終了か? GOTO TEST_LP2 ;******* 終了判定 BTFSC PORTA,0 GOTO MAIN ;テスト終了 INCF NUMBER,F ;number End? MOVF NUMBER,W SUBLW 0AH ;9まで表示したか BTFSS STATUS,Z ; GOTO TEST_LP1 ;次の数字表示へ表示 GOTO TEST_MODE ;0の表示へ戻る ;****************************************************************** ; シリアルデータ受信サブルーチン ; 3バイトのバイナリデータを受信する ; データは高位バイトの高位ビットから受信する ;****************************************************************** RXD CALL TIME10 ;50us Skew CALL TIME10 CALL TIME10 CALL TIME10 CALL TIME10 CALL TIME10 BTFSC PORTB,0 ;Start Bit Retest RETURN ;Error Skip MOVLW 18H ;24Bits Counter MOVWF DAT_CNT DAT_LP1 CALL TM100 ;249 RLF BYTE0,F ;全ビット左シフト RLF BYTE1,F ;キャリー経由全ビット左シフト RLF BYTE2,F ;  〃 BSF BYTE0,0 ;最下位に1をセット BTFSS PORTB,0 ;入力データが1か? BCF BYTE0,0 ;最下位を0に再セット NOP ;dumy NOP DECFSZ DAT_CNT,F ;24ビット受信完了か GOTO DAT_LP1 ;(249+11)*0.4usec=104usec CALL TM100 ;Stop bit skip CALL TM100 ;Skew CALL BCD ;CONVERT TO BCD RETURN ;************************************** ; Timer Routine ; TIME10 :10usec ; TM100 :100usec ; TIM100 :100usec AND RECEIVE CHECK ; TIME2M :2msec ;************************************** TM100 MOVLW 08H MOVWF CNT1 TM_LP1 CALL TIME10 ;27 DECFSZ CNT1,F ;2+30*8-1=241 GOTO TM_LP1 RETURN ;245*0.4usec=98usec TIME10 MOVLW 5H ; MOVWF CNT2 ; TIM_LP2 NOP DECFSZ CNT2,F ;2+4x5-1=21 GOTO TIM_LP2 RETURN ;21+4=25 ;***** DISPLAY DELAY AND RECEIVE CHECK **** TIM100 MOVLW 08H MOVWF CNT1 ; TIM_LP1 CALL TIME10 ;25 BTFSS PORTA,0 ;within test mode? GOTO TIMSKIP BTFSS PORTB,0 ;CHECK START BIT CALL RXD ;DATA RECEIVE TIMSKIP DECFSZ CNT1,F ;2+32*8-1=257 GOTO TIM_LP1 RETURN ;257+2=259 259*0.4usec=104usec TIME2M MOVLW 014H ;About 2msec MOVWF CNT3 ; TIM_LP3 CALL TIM100 ; DECFSZ CNT3,F ;2+255*20-1=5101 GOTO TIM_LP3 RETURN ;5103*0.4=2msec END