;******************************************************************************************* ; ; トランジスタ技術 9月号特集 ; 「5自由度アーム付き自走ロボットの製作」 ; センサー・モジュールのプログラム ; FITDESIGN A.Hata ;******************************************************************************************* ; V1.00 2006/06/30 初回リリース ; ;******************************************************************************************* LIST P=16F877A,ST=OFF,R=DEC,N=125 INCLUDE P16F877A.INC ERRORLEVEL -207 ERRORLEVEL -302 ; バンク切り替えワーニング ERRORLEVEL -306 ; ページ切り替えワーニング __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC ;******************************************************************************************* ; 定数の定義 ;******************************************************************************************* PING EQU H'01' READ EQU H'02' WRITE EQU H'03' RESET EQU H'06' ; MODEL_L EQU H'00' MODEL_H EQU H'A0' VER_FARM EQU H'01' ID_INI EQU H'10' BAUD_INI EQU 7 RDT_INI EQU 10 DIO_INI EQU H'FF' AVE_NUM_INI EQU 1 SAM_INT_INI EQU 0 CH_INT_INI EQU 10 ; ;******************************************************************************************* ; I/O宣言 ;******************************************************************************************* ; EQU 0 ; RA0 ; EQU 1 ; RA1 ; EQU 2 ; RA2 ; EQU 3 ; RA3 ; EQU 4 ; RA4 ; EQU 5 ; RA5 ; ; EQU 0 ; RB0 ; EQU 1 ; RB1 ; EQU 2 ; RB2 ; EQU 3 ; RB3 ; EQU 4 ; RB4 ; EQU 5 ; RB5 ; EQU 6 ; RB6 ; EQU 7 ; RB7 ; TX_RX EQU 0 ; RC0 High TX , Low RX LED EQU 1 ; RC1 Green LED ; EQU 2 ; RC2 ; EQU 3 ; RC3 ; EQU 4 ; RC4 ; EQU 5 ; RC5 ; EQU 6 ; RC6 ; EQU 7 ; RC7 ; ; EQU 0 ; RD0 ; EQU 1 ; RD1 ; EQU 2 ; RD2 ; EQU 3 ; RD3 ; EQU 4 ; RD4 ; EQU 5 ; RD5 ; EQU 6 ; RD6 ; EQU 7 ; RD7 ; ; EQU 0 ; RE0 ; EQU 1 ; RE1 ; EQU 2 ; RE2 ; ;**************************************************************** ; Bits ;**************************************************************** ;MSB EQU 7 LSB EQU 0 ;NAN EQU 0 ; ;**************************************************************** ; DEFINE ;**************************************************************** ;#define _Z STATUS,Z #define _C STATUS,C ; ;**************************************************************** ; EEPROM初期データ ;**************************************************************** ORG 0x2100 ; DE 0x00 ; Model Number L DE 0xA0 ; Model Number H DE 0x01 ; Version of Firmware DE 0x10 ; ID DE 7 ; Baud Rate(25000bps) DE 10 ; Return Delay Time(×10usec) ORG 0x2140 ; DE B'11111111' ; Digital I/O Set DE 1 ; Averaging Number DE 0 ; Sampling Interval DE 10 ; Channel Interval ;******************************************************************************************* ; レジスタ ;******************************************************************************************* ; ;=============================================================== ; BANK0 ;=============================================================== SEND_TEMP EQU 0x20 ; REC_ERR EQU 0x21 ; REC_DATA EQU 0x22 ; Receive Data By USART W_CNT0 EQU 0x23 ; W_CNT1 EQU 0x24 ; R_LENGTH EQU 0x25 ; Receive Data Length ER_STATUS EQU 0x26 ; Error Status SUM_DATA EQU 0x27 ; Sum Check Data TEMP0 EQU 0x28 TEMP1 EQU 0x29 TEMP2 EQU 0x2A BC_FLAG EQU 0x2B ; Broadcast Flag T_COUNT EQU 0x2C ; TX Count READ_FLAG EQU 0x2D RD_LENGTH EQU 0x2E ; Read Data Length RD_ADR EQU 0x2F ; Read Data Adress ; R_DATA0 EQU 0x30 ; Receive Data(INSTRUCTION) R_DATA1 EQU 0x31 R_DATA2 EQU 0x32 R_DATA3 EQU 0x33 R_DATA4 EQU 0x34 R_DATA5 EQU 0x35 R_DATA6 EQU 0x36 R_DATA7 EQU 0x37 ; T_DATA0 EQU 0x3A ; TX Data T_DATA1 EQU 0x3B T_DATA2 EQU 0x3C T_DATA3 EQU 0x3D T_DATA4 EQU 0x3E T_DATA5 EQU 0x3F T_DATA6 EQU 0x40 T_DATA7 EQU 0x41 T_DATA8 EQU 0x42 T_DATA9 EQU 0x43 T_DATA10 EQU 0x44 T_DATA11 EQU 0x45 T_DATA12 EQU 0x46 T_DATA13 EQU 0x47 T_DATA14 EQU 0x48 T_DATA15 EQU 0x49 T_DATA16 EQU 0x4A T_DATA17 EQU 0x4B T_DATA18 EQU 0x4C T_DATA19 EQU 0x4D T_DATA20 EQU 0x4E T_DATA21 EQU 0x4F ; DIGITAL_IO EQU 0x50 AN0_L EQU 0x51 AN0_H EQU 0x52 AN1_L EQU 0x53 AN1_H EQU 0x54 AN2_L EQU 0x55 AN2_H EQU 0x56 AN3_L EQU 0x57 AN3_H EQU 0x58 AN4_L EQU 0x59 AN4_H EQU 0x5A AN5_L EQU 0x5B AN5_H EQU 0x5C AN6_L EQU 0x5D AN6_H EQU 0x5E AN7_L EQU 0x5F AN7_H EQU 0x60 ; W_CNT2 EQU 0x61 TEMP3 EQU 0x62 TEMP4 EQU 0X63 WR_ADR EQU 0x64 ; Write Address ; AD_TEMPL EQU 0x6C AD_TEMPH EQU 0x6D AD_TEMPU EQU 0x6E TEMP EQU 0x6F ID EQU 0x70 ; ID BAUD EQU 0x71 ; Baud Rate RD_TIME EQU 0x72 ; Return Delay Time AVE_NUM EQU 0x73 ; Averaging Number SAMP_INTVL EQU 0x74 ; Sampling Interval CH_INTVL EQU 0x75 ; Channel Interval EE_ADR EQU 0x76 ; EEPROM Address EE_DATA EQU 0x77 ; EEPROM Data AARGB0 EQU 0x78 AARGB1 EQU 0x79 AARGB2 EQU 0x7A BARGB0 EQU 0x7B BARGB1 EQU 0x7C REMB0 EQU 0x7D REMB1 EQU 0x7E LOOPCOUNT EQU 0x7F ; ;**************************************************************** ; リセットベクター ;**************************************************************** ORG 0x0000 ; GOTO INITIALIZE ; ; ;**************************************************************** ; 割り込みベクター ;**************************************************************** ORG 0x0004 ; RETFIE ; GIE=1 ; ;**************************************************************** ; メイン ;**************************************************************** INITIALIZE BSF STATUS,RP0 ; BANK1にセット MOVLW B'00000111' ; Bit7を 0(ポートBプルアップ)にする MOVWF OPTION_REG ; OPTION_REGレジスタをセット MOVLW B'11111111' ; 各ポートの入出力を設定する MOVWF TRISA ; ポートAの設定 MOVLW B'11111111' ; MOVWF TRISB ; ポートBの設定 MOVLW B'10111100' ; 各ポートの入出力を設定する MOVWF TRISC ; ポートCの設定 MOVLW B'11111111' ; MOVWF TRISD ; ポートDの設定 MOVLW B'00000111' ; 各ポートの入出力を設定する MOVWF TRISE ; ポートEの設定 MOVLW H'FF' ; 全てデジタルI/O MOVWF CMCON ; CMCONレジスタをセット MOVLW B'10000000' ; 全てアナログ入力。右寄せ。 MOVWF ADCON1 ; ADCON1レジスタをセット MOVLW H'24' ; MOVWF TXSTA ; TXSTA レジスタをセット BCF STATUS,RP0 ; BANK0にセット MOVLW H'90' ; MOVWF RCSTA ; RCSTAレジスタをセット MOVLW B'10000000' ; AN0,1/32 tad MOVWF ADCON0 MOVLW B'00110001' ; MOVWF T1CON ; TMR1 プリスケーラ 1/8 にセット BCF PORTC,TX_RX ; 受信セット ;---------------------- ; EEPROM の読み出しとセット ;---------------------- MOVLW H'03' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W MOVWF ID ; MOVLW H'04' MOVWF EE_ADR CALL EE_READ DECF EE_DATA,W MOVWF TEMP1 BCF STATUS,C RRF TEMP1,W BSF STATUS,RP0 MOVWF SPBRG BCF STATUS,RP0 MOVWF BAUD ; MOVLW H'05' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W MOVWF RD_TIME ; MOVLW H'40' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W BSF STATUS,RP0 MOVWF TRISD BCF STATUS,RP0 ; MOVLW H'41' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W MOVWF AVE_NUM ; MOVLW H'42' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W MOVWF SAMP_INTVL ; MOVLW H'43' MOVWF EE_ADR CALL EE_READ MOVF EE_DATA,W MOVWF CH_INTVL ; BSF PORTC,LED ; POWER ON 表示 CALL W_25 CALL W_25 CALL W_25 CALL W_25 BCF PORTC,LED ;**************************************************************** ; メイン処理 ;**************************************************************** MAIN CLRF BC_FLAG CLRF ER_STATUS CALL RX BTFSC REC_ERR,0 GOTO ER_OUT BTFSC REC_ERR,1 GOTO MAIN MOVLW H'FF' SUBWF REC_DATA,W BTFSS STATUS,Z GOTO MAIN CALL RX BTFSC REC_ERR,0 GOTO ER_OUT BTFSC REC_ERR,1 GOTO MAIN MOVLW H'FF' SUBWF REC_DATA,W BTFSS STATUS,Z GOTO MAIN CALL RX BTFSC REC_ERR,0 GOTO ER_OUT BTFSC REC_ERR,1 GOTO MAIN MOVF ID,W SUBWF REC_DATA,W BTFSC STATUS,Z ; ID Check GOTO GET_LENGTH BCF BC_FLAG,0 MOVLW H'FE' SUBWF REC_DATA,W BTFSS STATUS,Z ; BC ID Check GOTO MAIN BSF BC_FLAG,0 GET_LENGTH CALL RX BTFSC REC_ERR,0 GOTO ER_OUT BTFSC REC_ERR,1 GOTO MAIN MOVF REC_DATA,W MOVWF R_LENGTH SUBLW 8 BTFSS STATUS,C GOTO MAIN RX_DATA MOVF R_LENGTH,W MOVWF TEMP1 MOVLW (R_DATA0-1) MOVWF FSR ; RX_DATA_LOOP INCF FSR,F CALL RX BTFSC REC_ERR,0 GOTO ER_OUT BTFSC REC_ERR,1 GOTO MAIN MOVF REC_DATA,W MOVWF INDF DECFSZ TEMP1,F CALL RX_DATA_LOOP ; CALL SUM_CHECK SUBLW 1 BTFSS STATUS,Z GOTO INSTRUCTION_CHECK BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,4 ; Set Checksum Error CALL TX_ANS GOTO MAIN ; INSTRUCTION_CHECK MOVF R_DATA0,W SUBLW PING BTFSC STATUS,Z GOTO PING_PROCESS MOVF R_DATA0,W SUBLW READ BTFSC STATUS,Z GOTO READ_PROCESS MOVF R_DATA0,W SUBLW WRITE BTFSC STATUS,Z GOTO WRITE_PROCESS MOVF R_DATA0,W SUBLW RESET BTFSC STATUS,Z GOTO RESET_PROCESS BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,6 ; Set Instruction Error CALL TX_ANS GOTO MAIN ;---------------------- ; PING命令の処理 ;---------------------- PING_PROCESS ; PING CALL TX_ANS GOTO MAIN ;---------------------- ; READ_DATA命令の処理 ;---------------------- READ_PROCESS ; READ_DATA MOVF R_DATA1,W MOVWF RD_ADR CALL HA_CHECK SUBLW 1 BTFSS STATUS,Z GOTO $+6 BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,0 ; Head Adress Error CALL TX_ANS GOTO MAIN ; MOVF R_DATA2,W MOVWF RD_LENGTH CALL RDL_CHECK SUBLW 1 BTFSS STATUS,Z GOTO $+6 BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,1 ; Read Length Erorr CALL TX_ANS GOTO MAIN ; CLRF T_COUNT DECF RD_ADR,F READ_LOOP INCF RD_ADR,F CALL RD_ADR_CHECK ; Read Address Check BTFSS READ_FLAG,0 GOTO $+3 CALL EEP_READ ; Read EEPROM Area GOTO READ_COUNT ; BTFSS READ_FLAG,1 GOTO $+3 CALL IO_READ ; Read Digital I/O GOTO READ_COUNT ; BTFSC READ_FLAG,2 CALL AD_READ ; Read A-D READ_COUNT MOVF RD_LENGTH,W BTFSC STATUS,Z GOTO $+4 INCF T_COUNT,F DECFSZ RD_LENGTH,F GOTO READ_LOOP ; BTFSC BC_FLAG,0 GOTO MAIN MOVF ER_STATUS,W MOVWF T_DATA0 INCF T_COUNT,F CALL RD_TX GOTO MAIN ;---------------------- ; WRITE_DATA命令の処理 ;---------------------- WRITE_PROCESS ; WRITE_DATA MOVLW 4 SUBWF R_LENGTH,W BTFSC STATUS,C GOTO $+6 BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,6 ; Set Instruction Error CALL TX_ANS GOTO MAIN ; MOVF R_DATA1,W MOVWF WR_ADR CALL WHA_CHECK SUBLW 1 BTFSS STATUS,Z GOTO $+6 BTFSC BC_FLAG,0 GOTO MAIN BSF ER_STATUS,0 ; Head Adress Error CALL TX_ANS GOTO MAIN ; MOVF WR_ADR,W SUBLW H'50' BTFSS STATUS,Z ; Write Address Check GOTO $+7 MOVF R_DATA2,W ; Write Digital I/O MOVWF PORTD BTFSC BC_FLAG,0 GOTO MAIN CALL TX_ANS GOTO MAIN ; MOVLW 3 SUBWF R_LENGTH,F MOVLW (R_DATA2-1) MOVWF FSR DECF WR_ADR,F WRITE_LOOP INCF FSR,F INCF WR_ADR,F CALL WR_ACTION MOVF WR_ADR,W MOVWF EE_ADR MOVF INDF,W MOVWF EE_DATA CALL EE_WRITE DECFSZ R_LENGTH,F GOTO WRITE_LOOP BTFSC BC_FLAG,0 GOTO MAIN CALL TX_ANS GOTO MAIN ;---------------------- ; RESET命令の処理 ;---------------------- RESET_PROCESS ; RESET CALL RESET_VAL BTFSC BC_FLAG,0 GOTO MAIN CALL TX_ANS GOTO MAIN ; ;---------------------- ; 受信エラーの処理 ;---------------------- ER_OUT MOVF RCREG,W ; dumy read CLRF RCSTA MOVLW 090H MOVWF RCSTA ; error status reset GOTO MAIN ;**************************************************************** ; サブルーチン ;**************************************************************** ;---------------------- ; サムチェック ; OKで0を返す。NGで1を返す。 ;---------------------- SUM_CHECK CLRF SUM_DATA DECF R_LENGTH,W MOVWF TEMP0 MOVF ID,W BTFSC BC_FLAG,0 MOVLW H'FE' ADDWF SUM_DATA,F MOVF R_LENGTH,W ADDWF SUM_DATA,F ; MOVLW (R_DATA0-1) MOVWF FSR SUM_LOOP INCF FSR,F MOVF INDF,W ADDWF SUM_DATA,F DECFSZ TEMP0,F GOTO SUM_LOOP COMF SUM_DATA,F INCF FSR,F MOVF INDF,W SUBWF SUM_DATA,W BTFSS STATUS,Z RETLW 1 ; Check NG RETLW 0 ; Check OK ; ;---------------------- ; サムチェックデータの生成 ;---------------------- MAKE_SUM MOVF T_COUNT,W MOVWF TEMP2 INCF T_COUNT,W ADDWF ID,W MOVWF SUM_DATA MOVLW (T_DATA0-1) MOVWF FSR INCF FSR,F MOVF INDF,W ADDWF SUM_DATA,F DECFSZ TEMP2,F GOTO $-4 COMF SUM_DATA,F RETURN ; ;---------------------- ; READ命令以外の返信パケット送信 ;---------------------- TX_ANS BSF PORTC,LED MOVF RD_TIME,W BTFSC STATUS,Z GOTO $+5 MOVWF TEMP4 CALL W_P010 DECFSZ TEMP4,F GOTO $-2 MOVLW 1 MOVWF T_COUNT MOVF ER_STATUS,W MOVWF T_DATA0 CALL MAKE_SUM BSF PORTC,TX_RX ; 送信セット MOVLW H'FF' MOVWF SEND_TEMP CALL TX MOVLW H'FF' MOVWF SEND_TEMP CALL TX MOVF ID,W MOVWF SEND_TEMP CALL TX MOVLW H'02' MOVWF SEND_TEMP CALL TX MOVF ER_STATUS,W ; MOVLW 0 MOVWF SEND_TEMP CALL TX MOVF SUM_DATA,W ; MOVLW H'FC' MOVWF SEND_TEMP CALL TX BSF STATUS,RP0 ;switch to Bank1 BTFSS TXSTA,TRMT ;ready check GOTO $-1 BCF STATUS,RP0 ;return to BCF PORTC,TX_RX ; 受信セット NOP NOP BCF PORTC,LED RETURN ; ;---------------------- ; 読み出し先頭アドレスのチェック ; 不正なアドレスだったら1を返す ;---------------------- HA_CHECK MOVF RD_ADR,W SUBLW H'05' BTFSC STATUS,C RETLW 0 MOVF RD_ADR,W SUBLW H'3F' BTFSC STATUS,C RETLW 1 MOVF RD_ADR,W SUBLW H'43' BTFSC STATUS,C RETLW 0 MOVF RD_ADR,W SUBLW H'4F' BTFSC STATUS,C RETLW 1 MOVF RD_ADR,W SUBLW H'60' BTFSC STATUS,C RETLW 0 RETLW 1 ; ;---------------------- ; 書き込み先頭アドレスのチェック ; 不正なアドレスだったら1を返す ;---------------------- WHA_CHECK MOVF WR_ADR,W SUBLW H'02' BTFSC STATUS,C RETLW 1 MOVF WR_ADR,W SUBLW H'05' BTFSC STATUS,C RETLW 0 MOVF WR_ADR,W SUBLW H'3F' BTFSC STATUS,C RETLW 1 MOVF WR_ADR,W SUBLW H'43' BTFSC STATUS,C RETLW 0 MOVF WR_ADR,W SUBLW H'4F' BTFSC STATUS,C RETLW 1 MOVF WR_ADR,W SUBLW H'50' BTFSS STATUS,Z RETLW 1 RETLW 0 ; ;---------------------- ; READ命令のデータ長チェック ; 20以下で0を返す。21以上で1を返す。 ;---------------------- RDL_CHECK MOVF RD_LENGTH,W SUBLW 20 BTFSC STATUS,C RETLW 0 RETLW 1 ; ;---------------------- ; 読み出しアドレスをチェックしてフラッグを立てる。 ;---------------------- RD_ADR_CHECK CLRF READ_FLAG MOVF RD_ADR,W SUBLW H'43' BTFSC STATUS,C GOTO EEP_SET MOVF RD_ADR,W SUBLW H'50' BTFSC STATUS,Z GOTO IO_SET BTFSC RD_ADR,0 GOTO AD_SET GOTO NG_SET EEP_SET BSF READ_FLAG,0 RETURN IO_SET BSF READ_FLAG,1 RETURN AD_SET BSF READ_FLAG,2 RETURN NG_SET BSF READ_FLAG,3 RETURN ; ;---------------------- ; AD 変換処理 ;---------------------- AD_READ BSF PORTC,LED MOVF RD_ADR,W MOVWF TEMP0 MOVLW H'51' SUBWF TEMP0,F BTFSS STATUS,Z GOTO $+3 MOVLW B'10000001' ; AN0 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10001001' ; AN1 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10010001' ; AN2 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10011001' ; AN3 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10100001' ; AN4 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10101001' ; AN5 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10110001' ; AN6 GOTO CH_SET DECF TEMP0,F DECFSZ TEMP0,F GOTO $+3 MOVLW B'10111001' ; AN7 GOTO CH_SET BSF ER_STATUS,2 ; リードアドレス不正 GOTO AD_END CH_SET MOVWF ADCON0 ; MOVF CH_INTVL,W BTFSC STATUS,Z GOTO AD_GO MOVWF TEMP0 CALL W_P010 DECFSZ TEMP0,F GOTO $-2 AD_GO CLRF AD_TEMPL CLRF AD_TEMPH CLRF AD_TEMPU MOVF AVE_NUM,W MOVWF TEMP1 SUBLW 1 BTFSS STATUS,C GOTO AD_LOOP BSF ADCON0,GO BTFSC ADCON0,NOT_DONE GOTO $-1 BSF STATUS,RP0 MOVF ADRESL,W BCF STATUS,RP0 MOVWF AD_TEMPL MOVF ADRESH,W MOVWF AD_TEMPH GOTO STORE_RESULT AD_LOOP BSF ADCON0,GO BTFSC ADCON0,NOT_DONE GOTO $-1 BSF STATUS,RP0 MOVF ADRESL,W BCF STATUS,RP0 ADDWF AD_TEMPL,F BTFSS STATUS,C GOTO $+4 INCFSZ AD_TEMPH,F GOTO $+2 INCF AD_TEMPU,F MOVF ADRESH,W ADDWF AD_TEMPH,F BTFSC STATUS,C INCF AD_TEMPU,F ; MOVF SAMP_INTVL,W BTFSC STATUS,Z GOTO $+5 MOVWF TEMP2 CALL W_P010 DECFSZ TEMP2,F GOTO $-2 ; DECFSZ TEMP1,F GOTO AD_LOOP AD_AVE_CULC MOVF AD_TEMPL,W MOVWF AARGB2 MOVF AD_TEMPH,W MOVWF AARGB1 MOVF AD_TEMPU,W MOVWF AARGB0 CLRF BARGB0 MOVF AVE_NUM,W MOVWF BARGB1 CALL FXD2416U MOVF AARGB2,W MOVWF AD_TEMPL MOVF AARGB1,W MOVWF AD_TEMPH STORE_RESULT MOVF T_COUNT,W ADDLW T_DATA1 MOVWF FSR MOVF AD_TEMPL,W MOVWF INDF INCF FSR,F MOVF AD_TEMPH,W MOVWF INDF AD_END INCF RD_ADR,F DECFSZ RD_LENGTH,F GOTO $+2 BSF ER_STATUS,2 ; リードデータ長不正 INCF T_COUNT,F BCF PORTC,LED RETURN ; ;---------------------- ; デジタルI/O を読んで送信用レジスタにセット ;---------------------- IO_READ MOVF T_COUNT,W ADDLW T_DATA1 MOVWF FSR MOVF PORTD,W MOVWF INDF RETURN ; ;---------------------- ; EEPROM エリアのレジスタ読み出し ;---------------------- EEP_READ MOVF RD_ADR,W MOVWF EE_ADR CALL EE_READ MOVF T_COUNT,W ADDLW T_DATA1 MOVWF FSR MOVF EE_DATA,W MOVWF INDF RETURN ; ;---------------------- ; READ命令に対する返信パケットの送信 ;---------------------- RD_TX BSF PORTC,LED MOVF RD_TIME,W BTFSC STATUS,Z GOTO $+5 MOVWF TEMP4 CALL W_P010 DECFSZ TEMP4,F GOTO $-2 CALL MAKE_SUM BSF PORTC,TX_RX ; 送信セット MOVLW H'FF' MOVWF SEND_TEMP CALL TX MOVLW H'FF' MOVWF SEND_TEMP CALL TX MOVF ID,W MOVWF SEND_TEMP CALL TX INCF T_COUNT,W MOVWF SEND_TEMP CALL TX MOVLW (T_DATA0-1) MOVWF FSR RD_TX_LOOP INCF FSR,F MOVF INDF,W MOVWF SEND_TEMP CALL TX DECFSZ T_COUNT,F GOTO RD_TX_LOOP MOVF SUM_DATA,W MOVWF SEND_TEMP CALL TX BSF STATUS,RP0 ;switch to Bank1 BTFSS TXSTA,TRMT ;ready check GOTO $-1 BCF STATUS,RP0 ;return to BCF PORTC,TX_RX ; 受信セット NOP NOP BCF PORTC,LED RETURN ; ;---------------------- ; 各レジスタ毎の書き込み命令に対する処理 ;---------------------- WR_ACTION MOVF WR_ADR,W SUBLW H'03' BTFSC STATUS,Z GOTO WR_ID ; MOVF WR_ADR,W SUBLW H'04' BTFSC STATUS,Z GOTO WR_BAUD ; MOVF WR_ADR,W SUBLW H'05' BTFSC STATUS,Z GOTO WR_RDT ; MOVF WR_ADR,W SUBLW H'40' BTFSC STATUS,Z GOTO WR_DIO ; MOVF WR_ADR,W SUBLW H'41' BTFSC STATUS,Z GOTO WR_AVE_NUM ; MOVF WR_ADR,W SUBLW H'42' BTFSC STATUS,Z GOTO WR_SAM_INT ; MOVF WR_ADR,W SUBLW H'43' BTFSC STATUS,Z GOTO WR_CH_INT BSF ER_STATUS,3 ; Write Adress Error RETURN ; WR_ID MOVF INDF,W MOVWF ID RETURN ; WR_BAUD DECF INDF,W MOVWF TEMP1 BCF STATUS,C RRF TEMP1,W BSF STATUS,RP0 MOVWF SPBRG BCF STATUS,RP0 MOVWF BAUD RETURN ; WR_RDT MOVF INDF,W MOVWF RD_TIME RETURN ; WR_DIO MOVF INDF,W BSF STATUS,RP0 MOVWF TRISD BCF STATUS,RP0 RETURN ; WR_AVE_NUM MOVF INDF,W MOVWF AVE_NUM RETURN ; WR_SAM_INT MOVF INDF,W MOVWF SAMP_INTVL RETURN ; WR_CH_INT MOVF INDF,W MOVWF CH_INTVL RETURN ; ;---------------------- ; レジスタを初期値に戻す ;---------------------- RESET_VAL MOVLW ID_INI MOVWF EE_DATA MOVWF ID MOVLW H'03' MOVWF EE_ADR CALL EE_WRITE ; MOVLW BAUD_INI MOVWF EE_DATA MOVWF TEMP1 DECF TEMP1,F BCF STATUS,C RRF TEMP1,W BSF STATUS,RP0 MOVWF SPBRG BCF STATUS,RP0 MOVLW H'04' MOVWF EE_ADR CALL EE_WRITE ; MOVLW RDT_INI MOVWF EE_DATA MOVWF RD_TIME MOVLW H'05' MOVWF EE_ADR CALL EE_WRITE ; MOVLW DIO_INI MOVWF EE_DATA BSF STATUS,RP0 MOVWF TRISD BCF STATUS,RP0 MOVLW H'40' MOVWF EE_ADR CALL EE_WRITE ; MOVLW AVE_NUM_INI MOVWF EE_DATA MOVWF AVE_NUM MOVLW H'41' MOVWF EE_ADR CALL EE_WRITE ; MOVLW SAM_INT_INI MOVWF EE_DATA MOVWF SAMP_INTVL MOVLW H'42' MOVWF EE_ADR CALL EE_WRITE ; MOVLW CH_INT_INI MOVWF EE_DATA MOVWF CH_INTVL MOVLW H'43' MOVWF EE_ADR CALL EE_WRITE RETURN ; ;---------------------- ; データの受信 ; 100msec間受信が無かったらREC_ERRのbit1を立ててリターンする。 ; framing errorまたはoverrun error検出でREC_ERRのbit0を立ててリターンする。 ;---------------------- RX CLRF REC_ERR MOVLW HIGH (65536-50000) MOVWF TMR1H MOVLW LOW (65536-50000) MOVWF TMR1L BCF PIR1,TMR1IF RX_LOOP BTFSS PIR1,TMR1IF GOTO $+3 BSF REC_ERR,1 ;Time Over Error RETURN BTFSS PIR1,RCIF ;check receive end frag GOTO RX_LOOP BTFSC RCSTA,FERR ;framing error? BSF REC_ERR,0 ;error BTFSC RCSTA,OERR ;overrun error? BSF REC_ERR,0 ;error MOVF RCREG,W ;get data & reset RCIF MOVWF REC_DATA ;save data RETURN ;---------------------- ; データの送信 ;---------------------- ; TX MOVWF SEND_TEMP ;data save BSF STATUS,RP0 ;switch to Bank1 TX_LOOP BTFSS TXSTA,TRMT ;ready check GOTO TX_LOOP BCF STATUS,RP0 ;return to Bank0 MOVF SEND_TEMP,W ;get data MOVWF TXREG ;start send RETURN ;---------------------- ; EEPROM の書き込み ;---------------------- EE_WRITE BCF STATUS,RP0 BCF STATUS,RP1 MOVF EE_ADR,W BSF STATUS,RP1 MOVWF EEADR BCF STATUS,RP1 MOVF EE_DATA,W BSF STATUS,RP1 MOVWF EEDATA BSF STATUS,RP0 BCF EECON1,EEPGD BCF EECON1,WRERR BCF STATUS,C BTFSS INTCON,GIE GOTO $+3 BSF STATUS,C BCF INTCON,GIE BSF EECON1,WREN MOVLW H'55' MOVWF EECON2 MOVLW H'AA' MOVWF EECON2 BSF EECON1,WR BCF EECON1,WREN BTFSC STATUS,C BSF INTCON,GIE EE_WRITE_LOOP BTFSC EECON1,WR GOTO EE_WRITE_LOOP BCF STATUS,RP0 BCF STATUS,RP1 RETURN ;---------------------- ; EEPROM の読み出し ;---------------------- EE_READ BCF STATUS,RP0 BCF STATUS,RP1 MOVF EE_ADR,W BSF STATUS,RP1 MOVWF EEADR BSF STATUS,RP0 BCF EECON1,EEPGD BSF EECON1,RD BCF STATUS,RP0 MOVF EEDATA,W BCF STATUS,RP1 MOVWF EE_DATA RETURN ;---------------------- ; ウェイト時間 (at 16MHz CLOCK) ;---------------------- W_25 MOVLW 250 ; 25ms GOTO W_T W_10 ; 10ms MOVLW 100 GOTO W_T W_5 ; 5ms MOVLW 50 GOTO W_T W_2 ; 2ms MOVLW 20 GOTO W_T W_1 ; 1ms MOVLW 10 GOTO W_T W_P500 ; 500us MOVLW 5 GOTO W_T W_P300 ; 300us MOVLW 3 GOTO W_T W_P200 ; 200us MOVLW 2 GOTO W_T ; W_T MOVWF W_CNT0 W_P100 ;100uS MOVLW 133 MOVWF W_CNT1 W_P003 ;0.75uS DECFSZ W_CNT1,F ;0.25uS,(0.5uS) GOTO W_P003 ;0.5uS DECFSZ W_CNT0,F GOTO W_P100 RETURN ; W_P010 ; 9.25uS MOVLW 10 MOVWF W_CNT2 DECFSZ W_CNT2,F GOTO $-1 NOP NOP RETURN ; ;********************************************************************************************** ; 24/16Bit 計算のマクロ ;********************************************************************************************** UDIV2416L macro ; Max Timing: 16+6*22+21+21+6*22+21+21+6*22+21+8 = 525 clks ; Min Timing: 16+6*21+20+20+6*21+20+20+6*21+20+3 = 497 clks ; PM: 14+31+27+31+27+31+8 = 169 DM: 8 CLRF TEMP RLF AARGB0,W RLF REMB1,F MOVF BARGB1,W SUBWF REMB1,F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F RLF AARGB0,F MOVLW 7 MOVWF LOOPCOUNT LOOPU2416A RLF AARGB0,W RLF REMB1,F RLF REMB0,F RLF TEMP,F MOVF BARGB1,W BTFSS AARGB0,LSB GOTO UADD46LA SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F GOTO UOK46LA UADD46LA ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F CLRW BTFSC _C MOVLW 1 ADDWF TEMP,F UOK46LA RLF AARGB0, F DECFSZ LOOPCOUNT,F GOTO LOOPU2416A RLF AARGB1,W RLF REMB1,F RLF REMB0,F RLF TEMP,F MOVF BARGB1,W BTFSS AARGB0,LSB GOTO UADD46L8 SUBWF REMB1,F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F GOTO UOK46L8 UADD46L8 ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F CLRW BTFSC _C MOVLW 1 ADDWF TEMP,F UOK46L8 RLF AARGB1,F MOVLW 7 MOVWF LOOPCOUNT LOOPU2416B RLF AARGB1,W RLF REMB1,F RLF REMB0,F RLF TEMP,F MOVF BARGB1,W BTFSS AARGB1,LSB GOTO UADD46LB SUBWF REMB1,F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F GOTO UOK46LB UADD46LB ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F CLRW BTFSC _C MOVLW 1 ADDWF TEMP,F UOK46LB RLF AARGB1,F DECFSZ LOOPCOUNT,F GOTO LOOPU2416B RLF AARGB2,W RLF REMB1,F RLF REMB0,F RLF TEMP,F MOVF BARGB1,W BTFSS AARGB1,LSB GOTO UADD46L16 SUBWF REMB1,F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F GOTO UOK46L16 UADD46L16 ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F CLRW BTFSC _C MOVLW 1 ADDWF TEMP,F UOK46L16 RLF AARGB2,F MOVLW 7 MOVWF LOOPCOUNT LOOPU2416C RLF AARGB2,W RLF REMB1,F RLF REMB0,F RLF TEMP,F MOVF BARGB1,W BTFSS AARGB2,LSB GOTO UADD46LC SUBWF REMB1,F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0,F CLRW BTFSS _C MOVLW 1 SUBWF TEMP,F GOTO UOK46LC UADD46LC ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F CLRW BTFSC _C MOVLW 1 ADDWF TEMP,F UOK46LC RLF AARGB2,F DECFSZ LOOPCOUNT,F GOTO LOOPU2416C BTFSC AARGB2,LSB GOTO UOK46L MOVF BARGB1,W ADDWF REMB1,F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0,F UOK46L endm ; ;********************************************************************************************** ; 24/16Bit 計算 ;********************************************************************************************** ; 24/16 Bit Unsigned Fixed Point Divide 24/16 -> 24.16 ; Input: 24 bit unsigned fixed point dividend in AARGB0, AARGB1,AARGB2 ; 16 bit unsigned fixed point divisor in BARGB0, BARGB1 ; Use: CALL FXD2416U ; Output: 24 bit unsigned fixed point quotient in AARGB0, AARGB1,AARGB2 ; 16 bit unsigned fixed point remainder in REMB0, REMB1 ; Result: AARG, REM <-- AARG / BARG ; Max Timing: 2+525+2 = 529 clks ; Max Timing: 2+497+2 = 501 clks ; PM: 2+169+1 = 172 DM: 8 ;********************************************************************************************** FXD2416U CLRF REMB0 CLRF REMB1 UDIV2416L RETLW 0x00 ; END