;*********************************************************** ; LCD DB7〜DB4 pin => PIC's RB4〜RB7 ; LCD DB3〜DB0 pin => GND ; LCD RS,R/W,E pin => PIC's RA2,RA1,RA0 ;*********************************************************** LIST P=PIC16F628 INCLUDE P16F628.INC __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _WDT_OFF & _LVP_OFF ;*********************************************************** ; Definition of valuables ;*********************************************************** COUNT EQU 20H COUNT1 EQU 21H COUNT2 EQU 22H COUNT3 EQU 23H COUNT4 EQU 24H DPDT EQU 25H HOUR1 EQU 26H HOUR2 EQU 27H MIN1 EQU 28H MIN2 EQU 29H SEC1 EQU 2AH SEC2 EQU 2BH wHOUR1 EQU 2CH wHOUR2 EQU 2DH wMIN1 EQU 2EH wMIN2 EQU 2FH TEMP EQU 30h POINT EQU 31h JOB EQU 6fh RS SET 0 RW SET 6 E SET 7 BUSY_F SET 7 IDAT SET 5 ODAT SET 3 CLK SET 4 CPLD_RW SET 1 CLR SET 2 ORG 0 goto INIT ORG 4 goto LPRCV ;*********************************************************** ; I/O pins Initialize ;*********************************************************** INIT BcF STATUS,RP1 movlw 07h movwf CMCON BSF STATUS,RP0 CLRF TRISA bsf TRISA,5 CLRF TRISB bsf TRISB,1 bcf OPTION_REG,T0CS movlw b'00100000' movwf PIE1 ;割り込み設定 MOVLW B'00100100' ; 8BIT,送信許可,非同期,高速 MOVWF TXSTA ; TXSTA レジスタの設定 MOVLW 19H ; ボーレート 9600bps (4MHz:高速設定時) MOVWF SPBRG ; SPBRG レジスタの設定 BCF STATUS,RP0 MOVLW B'10010000' ; シリアル,8BIT,継続受信許可 MOVWF RCSTA ; RCSTA レジスタの設定 movlw b'11000000' movwf INTCON CLRF PORTA CLRF PORTB BSF STATUS,IRP ; 間接アドレス設定 MOVLW 032H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタの初期化 clrf JOB ;===============LCD preare===================== CALL LCD_INI ;LCD Initialize CALL LCD_BUSY_4 MOVLW B'00001100' CALL LCD_CMD_4 CALL LCD_BUSY_4 ;Cursor 初期位置; movlw b'00000011' CALL LCD_CMD_4 MOVLW 00H MOVWF wHOUR1 MOVLW 00H MOVWF wHOUR2 MOVLW 00H MOVWF wMIN1 MOVLW 00H MOVWF wMIN2 CALL WRITE_TIME ;*********************************************************** ; MAIN program ;*********************************************************** MAIN CALL LCD_BUSY_4 MOVLW B'00001100' CALL LCD_CMD_4 CALL LCD_BUSY_4 ;Cursor 初期位置; movlw b'00000011' CALL LCD_CMD_4 CALL LCD_BUSY_4 movlw 'N' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'i' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'x' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'i' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'e' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw ' ' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'C' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'l' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'o' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'c' CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw 'k' CALL LCD_DATA_4 call PUT_NOW movfw JOB addlw 0 btfss STATUS,Z call WRITE_TIME GOTO MAIN PUT_NOW call READ_TIME call LCD_BUSY_4 movlw b'10010100' call LCD_CMD_4 CALL LCD_BUSY_4 movfw HOUR1 addlw 30h CALL LCD_DATA_4 CALL LCD_BUSY_4 movfw HOUR2 addlw 30h CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw ':' CALL LCD_DATA_4 CALL LCD_BUSY_4 movfw MIN1 addlw 30h CALL LCD_DATA_4 CALL LCD_BUSY_4 movfw MIN2 addlw 30h CALL LCD_DATA_4 CALL LCD_BUSY_4 movlw ':' CALL LCD_DATA_4 CALL LCD_BUSY_4 movfw SEC1 addlw 30h CALL LCD_DATA_4 CALL LCD_BUSY_4 movfw SEC2 addlw 30h CALL LCD_DATA_4 return ;--------------------------------------------rs232c routine----------------------------- LPRCV BTFSS PIR1,RCIF ; USART 受信割り込みフラグビットのチェック GOTO LPRCV ; PIR1 レジスタの RCIF が「0」だったら ; LPRCV ラベル間をループする ; ****** エラーチェック ****** BTFSC RCSTA,FERR ; フレーミングエラーのチェック(1:エラー,0:正常) GOTO FRAME ; フレーミングエラー時 FRAME のラベルへ ; ジャンプする BTFSC RCSTA,OERR ; オーバーランエラーのチェック(1:エラー,0:正常) GOTO OVER ; オーバーランエラー時 OVER のラベルへジャンプする ; ****** 受信データの格納 ****** MOVF RCREG,W ; RCREGレジスタから受信データを読み込む MOVWF INDF ; バッファに格納 SUBLW 0DH ; 受信データから「CR」コードを引く BTFSC STATUS,Z ; 演算結果がゼロかチェック(受信データは「CR」?) GOTO SEND ; 受信データが「CR」のとき SENDのラベルへジャンプする movf INDF,W call TX CHKBF ; ****** バッファが一杯かどうかチェック ****** INCF FSR,F ; ポインタ +1 BTFSS STATUS,Z ; STATUSレジスタのZフラグビットが1だったら次をスキップ GOTO LPRCV ; バッファに余裕あり LPRCVのラベルへ戻り受信を続ける GOTO SEND ; バッファが一杯   SEND のラベルへジャンプする ; ****** エラー時の処理 ****** FRAME ; <フレーミングエラー時の処理> MOVF RCREG,W ; ダミーの入力とFERRフラグをリセット(RCREGをリードするとクリア) MOVLW '#' ; 「?」の文字コードをWregにロードする CALL TX MOVWF INDF ; バッファに格納(「?」の文字を格納) BTFSS RCSTA,OERR ; オーバーランエラーのチェック(1:エラー,0:正常) GOTO CHKBF ; 正常であれば CHKBF のラベルへジャンプする ; OVER ; <オーバーランエラー時の処理> BCF RCSTA,CREN ; OERRのリセット(ビットCREN のクリアによりクリアする) BSF RCSTA,CREN ; 連続受信を許可する MOVLW '!' ; 「?」の文字コードをWregにロードする CALL TX MOVWF INDF ; バッファに格納(「?」の文字を格納) GOTO CHKBF ; CHKBF のラベルへジャンプする SEND ; ****** データの送信ルーチン ****** MOVLW 032H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタをリセットする movlw 0ah call TX LPSD MOVF INDF,W ; バッファに格納されているデータをWregにロードする CALL TX ; 送信サブルーチンへ MOVF INDF,W ; バッファに格納されているデータをWregに再ロードする SUBLW 0DH ; データから「CR」コードを引く BTFSC STATUS,Z ; 演算結果がゼロかチェック(データは終了コード「CR」?) GOTO TEXT ; データが「CR」のとき TEXTのラベルへジャンプする ; ****** バッファにデータが残っているかチェック ****** INCF FSR,F ; ポインタ +1 BTFSS STATUS,Z ; STATUSレジスタのZフラグビットが1だったら次をスキップ GOTO LPSD ; バッファに残っている LPSDのラベルへ戻り送信を続ける GOTO TEXT ; バッファが空である  TEXT のラベルへジャンプする TEXT ; ****** テキストデータの送信ルーチン ****** CLRF POINT ; テーブルポインタのリセット LPTEX ; MOVF POINT,W ; テーブルポインタの値をWregへロードする(OFFSET) CALL TABLE ; テキストデータの読み込みサブルーチンへ ADDLW 0 ; Wregレジスタに0を加算する BTFSC STATUS,Z ; 演算結果がゼロかチェック(テキストデータは「0」?) goto endint ; テキストデータが終了を示す「0」のとき MAINへジャンプ CALL TX ; テキストデータを出力するため送信サブルーチンへ INCF POINT,F ; テーブルポインタ +1 GOTO LPTEX ; LPTEX のラベルへ戻り繰り返す TABLE ; ****** テキストデータテーブル ****** ADDWF PCL,F ; PC+OFFSET DT "time is set[",0,0,0,0,0,0,0,0 ; TABLEの定義(PC+OFFSET相当のデータを持って戻る) endint BSF STATUS,IRP ; 間接アドレス設定 MOVLW 032H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタの初期化 movf INDF,W movwf wHOUR1 call TX incf FSR,F movf INDF,W movwf wHOUR2 call TX incf FSR,F movlw ':' call TX movf INDF,W movwf wMIN1 call TX incf FSR,F movf INDF,W movwf wMIN2 call TX movlw ']' call TX movlw 0dh call TX movlw 0ah call TX movlw 30h subwf wHOUR1,F movlw 30h subwf wHOUR2,F movlw 30h subwf wMIN1,F movlw 30h subwf wMIN2,F incf JOB,F movfw wHOUR1 call TX movfw wHOUR2 call TX movfw wMIN1 call TX movfw wMIN2 call TX BSF STATUS,IRP ; 間接アドレス設定 MOVLW 032H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタの初期化 retfie ;*********************************************************** ; 送信サブルーチン ; 送信可能かのチェックは送信レジスタが空であることで確認 ; (つまり、TRMT=1で可能と判定する) ; (注)TXATAのあるバンクに注意 ;*********************************************************** TX MOVWF TEMP ; 送信するデータを変数(TEMP)に格納 BSF STATUS,RP0 ; Bank 1 へ切替 LPTX ; BTFSS TXSTA,TRMT ; 送信可能であるかチェック(1:可能, 0:禁止) GOTO LPTX ; 禁止であれば LPTX のラベル間を繰り返す ; BCF STATUS,RP0 ; Bank 0 へ戻す MOVF TEMP,W ; 変数(TEMP)に格納していた送信データをWregにロード MOVWF TXREG ; 送信データはTXREGレジスタを通してシリアル出力される RETURN ; メインルーチンへ戻る ;-------------------------------------------Communication with CPLD routine----------------- ;*********************************************************** ; Read Time ;*********************************************************** READ_TIME bcf PORTA,CPLD_RW clrf HOUR1 clrf HOUR2 clrf MIN1 clrf MIN2 clrf SEC1 clrf SEC2 bsf PORTA,CLR call CLK_STEP bcf PORTA,CLR call CLK_STEP btfsc PORTA,IDAT bsf HOUR1,3 call CLK_STEP btfsc PORTA,IDAT bsf HOUR1,2 call CLK_STEP btfsc PORTA,IDAT bsf HOUR1,1 call CLK_STEP btfsc PORTA,IDAT bsf HOUR1,0 call CLK_STEP btfsc PORTA,IDAT bsf HOUR2,3 call CLK_STEP btfsc PORTA,IDAT bsf HOUR2,2 call CLK_STEP btfsc PORTA,IDAT bsf HOUR2,1 call CLK_STEP btfsc PORTA,IDAT bsf HOUR2,0 call CLK_STEP btfsc PORTA,IDAT bsf MIN1,3 call CLK_STEP btfsc PORTA,IDAT bsf MIN1,2 call CLK_STEP btfsc PORTA,IDAT bsf MIN1,1 call CLK_STEP btfsc PORTA,IDAT bsf MIN1,0 call CLK_STEP btfsc PORTA,IDAT bsf MIN2,3 call CLK_STEP btfsc PORTA,IDAT bsf MIN2,2 call CLK_STEP btfsc PORTA,IDAT bsf MIN2,1 call CLK_STEP btfsc PORTA,IDAT bsf MIN2,0 call CLK_STEP btfsc PORTA,IDAT bsf SEC1,3 call CLK_STEP btfsc PORTA,IDAT bsf SEC1,2 call CLK_STEP btfsc PORTA,IDAT bsf SEC1,1 call CLK_STEP btfsc PORTA,IDAT bsf SEC1,0 call CLK_STEP btfsc PORTA,IDAT bsf SEC2,3 call CLK_STEP btfsc PORTA,IDAT bsf SEC2,2 call CLK_STEP btfsc PORTA,IDAT bsf SEC2,1 call CLK_STEP btfsc PORTA,IDAT bsf SEC2,0 return CLK_STEP BSF PORTA,CLK NOP NOP BCF PORTA,CLK return ;*********************************************************** ; write Time ;*********************************************************** WRITE_TIME clrf JOB bcf PORTA,CPLD_RW bsf PORTA,CLR call CLK_STEP bcf PORTA,CLR call CLK_STEP bcf PORTA,ODAT call RW_STEP bcf PORTA,ODAT btfsc wHOUR1,2 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR1,1 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR1,0 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR2,3 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR2,2 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR2,1 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wHOUR2,0 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN1,3 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN1,2 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN1,1 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN1,0 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN2,3 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN2,2 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN2,1 bsf PORTA,ODAT call RW_STEP call CLK_STEP bcf PORTA,ODAT btfsc wMIN2,0 bsf PORTA,ODAT call RW_STEP bcf PORTA,CPLD_RW return RW_STEP BSF PORTA,CPLD_RW NOP NOP BCF PORTA,CPLD_RW return ;----------------------------------------------------------------------LCD Routines ;*********************************************************** ; Initialize Sub routine ;*********************************************************** LCD_INI MOVLW b'00011000' MOVWF PORTA CALL TIME10M MOVLW B'00110000' CALL LCD_CMD CALL TIME10M MOVLW B'00110000' CALL LCD_CMD CALL TIME10M MOVLW B'00110000' CALL LCD_CMD CALL TIME10M MOVLW B'00100000' CALL LCD_CMD CALL LCD_BUSY_4 MOVLW B'00101000' CALL LCD_CMD_4 CALL LCD_BUSY_4 MOVLW B'00001000' CALL LCD_CMD_4 CALL LCD_BUSY_4 MOVLW B'00000001' CALL LCD_CMD_4 CALL LCD_BUSY_4 MOVLW B'00000110' CALL LCD_CMD_4 RETURN ;*********************************************************** ; Command Sub routines ;*********************************************************** LCD_CMD_4 MOVWF DPDT ; データを一時保存 ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_CMD ; データ出力(コマンドコードの上位4ビット相当) SWAPF DPDT,W ; 一時保存データの上位下位入れ替え ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_CMD ; データ出力(コマンドコードの下位4ビット相当) RETURN LCD_CMD MOVWF PORTB BCF PORTA,RW BCF PORTA,RS BSF PORTA,E NOP BCF PORTA,E RETURN ;*********************************************************** ; DATA Output Sub routine ;*********************************************************** LCD_DATA_4 MOVWF DPDT ; データを一時保存 ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_DATA ; データ出力(文字コードの上位4ビット相当) SWAPF DPDT,W ; 一時保存データの上位下位入れ替え ANDLW 0F0H ; 下位4ビットをマスクする CALL LCD_DATA ; データ出力(文字コードの下位4ビット相当) RETURN LCD_DATA MOVWF PORTB BCF PORTA,RW BSF PORTA,RS BSF PORTA,E NOP BCF PORTA,E RETURN ;*********************************************************** ; BUSY CHECK Sub routines ;*********************************************************** LCD_BUSY_4 BSF STATUS,RP0 BSF TRISB,7 BSF TRISB,6 BSF TRISB,5 BSF TRISB,4 BCF STATUS,RP0 BCF PORTA,RS BSF PORTA,RW BSF PORTA,E MOVF PORTB,W BCF PORTA,E MOVWF DPDT BSF PORTA,E MOVF PORTB,W BCF PORTA,E BTFSC DPDT,BUSY_F GOTO LCD_BUSY_4 BCF PORTA,RW BSF STATUS,RP0 BCF TRISB,7 BCF TRISB,6 BCF TRISB,5 BCF TRISB,4 BCF STATUS,RP0 RETURN ;*********************************************************** ; Timer Sub routines ;*********************************************************** TIME100 MOVLW 0AH MOVWF COUNT NOP NOP LOOP DECFSZ COUNT,F GOTO LOOP RETURN TIME10M MOVLW 04H MOVWF COUNT1 NOP NOP LOOP1 CALL TIME100 DECFSZ COUNT1,F GOTO LOOP1 RETURN TIME1S MOVLW 40H MOVWF COUNT2 MOVLW 24H MOVWF COUNT3 MOVLW 03H MOVWF COUNT4 NOP LOOP2 CALL TIME10M DECFSZ COUNT2,F GOTO LOOP2 LOOP3 CALL TIME100 DECFSZ COUNT3,F GOTO LOOP2 LOOP4 DECFSZ COUNT4,F GOTO LOOP4 RETURN end