;************************************************************************* ; Copyright 2004 Hata Akihiro ; ;  第2章 センサの活用 ;------------------------------------------------------------------------- ;プログラムの説明 ;<動作> ; A-Dコンバータ(MP3204)で計測したデータをホストPCへ ; 転送する。 ; 計測周期 1sec, 0.1sec ; ゼロポジション  1/2,1/4 ; 出力値  −1.024V 〜 3.072V (ポジション1/4の時) ;      −2.048V 〜 2.048V (ポジション1/2の時) ; ;<出力データ> ; <+ or ->X.XXXV        (周期0.1s時) ; <+ or ->X.XXXV,<+ or ->X.XXXV (周期1s時) ; X.XXXは電圧換算値 ; ;<通信条件> ; SPEED 9600 bps ; DATA 8bit ; Parity Non ; Stop bit 1 ; Hand Shake Non ;------------------------------------------------------------------------- ; 2004/06/20 V1.00 初回リリース ; ; ; ; ;------------------------------------------------------------------------- ; CONFIGRATION FUSE ; WDT:Disable OSC:XT Code Protect:OFF Power up timer:ON ; OSCILLATOR ; 4MHz ;************************************************************************* ; LIST P=PIC16F628A, R=DEC ;Target Processor INCLUDE P16F628A.INC ; __CONFIG _BODEN_OFF & _WDT_OFF & _XT_OSC & _CP_OFF & _PWRTE_ON & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF & _DATA_CP_OFF __idlocs H'0100' ;V1.00 2004/06/20 ; ;------------------------------------------------------------------------- ; DEFINE I/O Port ;------------------------------------------------------------------------- ; PortA ; RA0 input ; RA1 input ; RA2 input ; RA3 input ; RA4 input ; RA5 input ; ; PortB ; RB0 input ; RB1 RS-232C RX input ; RB2 RS-232C TX output ; RB3 TEMP/GAGE input (L:GAGE) ; RB4 /CS output ; RB5 Dout input ; RB6 Din output ; RB7 CLK output ; ZERO EQU 0 ; ZERO Position 1:1/4 , 0:1/2 SAMPLE EQU 3 ; Sample Interval 1:1sec , 0:0.1sec CS EQU 4 DOUT EQU 5 DIN EQU 6 CLK EQU 7 ;------------------------------------------------------------------------- ; Variables ;------------------------------------------------------------------------- ; AD_CH1 EQU H'C0' AD_CH2 EQU H'C8' ; ;------------------------------------------------------------------------- ; Registers ;------------------------------------------------------------------------- ; ST_TEMP EQU H'20' ; Status Reg. Temp. for Interupt W_TEMP EQU H'21' ; Work Reg. Temp. for Interupt REC_ERR EQU H'22' ; FLAG for RX Error SEND_TEMP EQU H'23' ; TEMP Reg. for TX W_CNT0 EQU H'24' ; COUNTER for Wait W_CNT1 EQU H'25' ; COUNTER for Wait RA_OUT EQU H'26' ; PORTA OUT Reg. RB_OUT EQU H'27' ; PORTB OUT Reg. TEMP0 EQU H'28' ; Temporary Reg. TEMP1 EQU H'29' ; Temporary Reg. TEMP2 EQU H'2A' ; Temporary Reg. REC_DATA EQU H'2B' ; Receive Data TX_FLAG EQU H'2C' ; TX Data FLAG INT_CNT EQU H'2D' ; Interupt Counter AD1_DATA_L EQU H'2E' ; AD CH1 Data L byte AD1_DATA_H EQU H'2F' ; AD CH1 Data H byte AD2_DATA_L EQU H'30' ; AD CH2 Data L byte AD2_DATA_H EQU H'31' ; AD CH2 Data H byte AD_TEMP_L EQU H'32' ; AD TEMP Data L byte AD_TEMP_H EQU H'33' ; AD TEMP Data H byte AD_DATA_L EQU H'34' ; AD Data L byte AD_DATA_H EQU H'35' ; AD Data H byte AD_CNT EQU H'36' ; AD Counter AD_BIT_CNT EQU H'37' ; AD bit Counter AD_CONTROL EQU H'38' ; AD Control Data ASC1 EQU H'39' ; ASCII Data LSB ASC2 EQU H'3A' ; ASC3 EQU H'3B' ; ASC4 EQU H'3C' ; ASC5 EQU H'3D' ; ASCII Data MSB BIN_L EQU H'3E' ; Binary Data L byte BIN_H EQU H'3F' ; Binary Data H byte BCD_L EQU H'40' ; BCD Data L byte BCD_H EQU H'41' ; BCD Data H byte BCD_U EQU H'42' ; BCD Data Upper byte POLARITY EQU H'43' ; Porality Data AD_CON_TEMP EQU H'44' ; TEMP_H EQU H'45' TEMP_L EQU H'46' AD_CH_TEMP EQU H'47' SAMPLE_TEMP EQU H'48' ;------------------------------------------------------------------------- ; Program code ;------------------------------------------------------------------------- ; ORG H'00' ; Power ON GOTO START ; ; ORG H'04' ; Go Interupt GOTO INTERUPT ;------------------------------------------------------------------------- ; Initialize ;------------------------------------------------------------------------- START MOVLW 0x20 ; BANK0 Data Clear MOVWF FSR REG_CLEAR CLRF INDF INCF FSR,F MOVF FSR,W XORLW 0x7F BTFSS STATUS,Z GOTO REG_CLEAR ; BSF STATUS,RP0 ; BANK1にセット MOVLW B'00000111' ; Bit7を 0(ポートBプルアップ)にする MOVWF OPTION_REG ; OPTION_REGレジスタをセット MOVLW B'11111111' ; 各ポートの入出力を設定する MOVWF TRISA ; ポートAの設定 MOVLW B'00101011' ; MOVWF TRISB ; ポートBの設定 MOVLW H'24' ; MOVWF TXSTA ; TXSTA レジスタをセット MOVLW 25 ; ボーレート 9600bps の値 MOVWF SPBRG ; SPBRGレジスタをセット CLRF PIE1 ; PIE1レジスタをクリア BSF PIE1,2 ; CCP1 割り込みを許可 BCF STATUS,RP0 ; BANK0にセット MOVLW H'FF' ; 全てデジタルI/O MOVWF CMCON ; CMCONレジスタをセット MOVLW H'90' ; MOVWF RCSTA ; RCSTAレジスタをセット MOVLW B'00110000' ; プリスケーラ1/8 MOVWF T1CON ; T1CONをセット MOVLW B'00001011' ; コンペアモード MOVWF CCP1CON ; CCP1CONをセット BTFSC PORTB,SAMPLE ; SAMPLEスイッチをチェック GOTO $+6 MOVLW LOW 12500 ; CCPレジスタ値を0.1sec割り込みにセット MOVWF CCPR1L MOVLW HIGH 12500 MOVWF CCPR1H GOTO $+5 MOVLW LOW 62500 ; CCPレジスタ値を0.5sec割り込みにセット MOVWF CCPR1L MOVLW HIGH 62500 MOVWF CCPR1H ;---------------------- ; OUTPUT Initialize ;---------------------- MOVLW B'00000000' MOVWF RA_OUT MOVLW B'00010000' MOVWF RB_OUT MOVF RA_OUT,W MOVWF PORTA MOVF RB_OUT,W MOVWF PORTB ;---------------------- ; Registor Initialize ;---------------------- ;---------------------- ; Interupt Setting ;---------------------- MOVLW B'01000000' MOVWF INTCON ;******************************************************* ; MAIN PROGRAM ;******************************************************* MAIN BSF T1CON,0 BSF INTCON,GIE ; 割り込み許可 MAIN_LOOP MOVF PORTB,W ; SAMPLE スイッチの変化チェック ANDLW B'00001000' XORWF SAMPLE_TEMP,W BTFSC STATUS,Z GOTO MAIN_LOOP CALL W_25 MOVF PORTB,W ANDLW B'00001000' XORWF SAMPLE_TEMP,W BTFSC STATUS,Z GOTO MAIN_LOOP ; 変化検出 BTFSC PORTB,SAMPLE ; SAMPLE スイッチのチェック GOTO $+7 MOVLW LOW 12500 ; CCPレジスタ値を0.1sec割り込みにセット MOVWF CCPR1L MOVLW HIGH 12500 MOVWF CCPR1H BCF SAMPLE_TEMP,0 GOTO MAIN_LOOP MOVLW LOW 62500 ; CCPレジスタ値を0.5sec割り込みにセット MOVWF CCPR1L MOVLW HIGH 62500 MOVWF CCPR1H BSF SAMPLE_TEMP,0 GOTO MAIN_LOOP ; ;******************************************************* ; Subroutines ;******************************************************* ;---------------------- ; AD READ (AD Convertsion 256 times Average) ;---------------------- AD_READ_256 CLRF TEMP_L CLRF TEMP_H MOVLW 16 MOVWF TEMP1 AD256_LOOP MOVF AD_CH_TEMP,W MOVWF AD_CON_TEMP CALL AD_READ_16 MOVF AD_TEMP_L,W ADDWF TEMP_L,F BTFSC STATUS,C INCF TEMP_H,F MOVF AD_TEMP_H,W ADDWF TEMP_H,F CALL DL570U DECFSZ TEMP1,F GOTO AD256_LOOP MOVLW 4 MOVWF TEMP0 BCF STATUS,C RRF TEMP_H,F RRF TEMP_L,F DECFSZ TEMP0,F GOTO $-4 RETURN ;---------------------- ; AD READ (AD Convertsion 16 times Average) ;---------------------- AD_READ_16 CLRF AD_TEMP_L ; AD値保管レジスタのクリア Lバイト CLRF AD_TEMP_H ; AD値保管レジスタのクリア Hバイト MOVLW 16 MOVWF AD_CNT ; ADの回数16をAD_CNTにセット AD16_LOOP MOVF AD_CON_TEMP,W MOVWF AD_CONTROL ; ADコントロール・データをセット CALL AD_READ ; AD変換ルーチンを呼び出し MOVF AD_DATA_L,W ; AD変換値をAD値保管レジスタに加算 ADDWF AD_TEMP_L,F ; BTFSC STATUS,C ; INCF AD_TEMP_H,F ; MOVF AD_DATA_H,W ; ADDWF AD_TEMP_H,F ; CALL DL570U ; 570usecのウェイト DECFSZ AD_CNT,F ; GOTO AD16_LOOP ; 16回ループする MOVLW 4 MOVWF TEMP0 ; データシフト回数4をTEMP0にセット BCF STATUS,C RRF AD_TEMP_H,F ; AD値保管レジスタ Hを右へシフト RRF AD_TEMP_L,F ; AD値保管レジスタ Lを右へシフト DECFSZ TEMP0,F GOTO $-4 ; 4回ループする RETURN ; 戻る ;------------ ; AD Convert 1 time ;------------ AD_READ BCF RB_OUT,CS MOVF RB_OUT,W MOVWF PORTB MOVLW 5 MOVWF AD_BIT_CNT AD_LOOP RLF AD_CONTROL,F BSF RB_OUT,DIN BTFSS STATUS,C BCF RB_OUT,DIN MOVF RB_OUT,W MOVWF PORTB CALL DL10U BSF RB_OUT,CLK MOVF RB_OUT,W MOVWF PORTB CALL DL10U BCF RB_OUT,CLK MOVF RB_OUT,W MOVWF PORTB DECFSZ AD_BIT_CNT,F GOTO AD_LOOP MOVLW 14 MOVWF AD_BIT_CNT AD_LOOP2 CALL DL10U BSF RB_OUT,CLK MOVF RB_OUT,W MOVWF PORTB BSF STATUS,C BTFSC PORTB,DOUT BCF STATUS,C RLF AD_DATA_L,F RLF AD_DATA_H,F CALL DL10U DECFSZ AD_BIT_CNT,F GOTO $+11 BSF RB_OUT,CS MOVF RB_OUT,W MOVWF PORTB CALL DL10U BCF RB_OUT,CLK MOVF RB_OUT,W MOVWF PORTB MOVLW B'00001111' ANDWF AD_DATA_H,F RETURN BCF RB_OUT,CLK MOVF RB_OUT,W MOVWF PORTB GOTO AD_LOOP2 ;------------- ; Delay 10usec ;------------- DL10U GOTO $+1 GOTO $+1 GOTO $+1 RETURN ;------------- ; Delay 570usec ;------------- DL570U MOVLW 186 MOVWF W_CNT0 DL570U_LOOP DECFSZ W_CNT0,F GOTO DL570U_LOOP RETURN ;-------------------------------- ; 2BYTE BINARY TO 3BYTE BCD ;-------------------------------- BIN2_BCD3 CLRF BCD_L CLRF BCD_H CLRF BCD_U COMF BIN_L,F COMF BIN_H,F ADD_10000 MOVLW 010H ADDWF BIN_L,F BTFSS STATUS,C GOTO $+4 MOVLW 28H ADDWF BIN_H,F GOTO $+3 MOVLW 27H ADDWF BIN_H,F BTFSC STATUS,C GOTO SUB_10000 INCF BCD_U,F GOTO ADD_10000 SUB_10000 MOVLW 010H SUBWF BIN_L,F BTFSS STATUS,C DECF BIN_H,F MOVLW 27H SUBWF BIN_H,F MOVF BCD_U,W ANDLW 0FH IORLW 30H MOVWF ASC5 ADD_1000 MOVLW 0E8H ADDWF BIN_L,F BTFSS STATUS,C GOTO $+4 MOVLW 04H ADDWF BIN_H,F GOTO $+3 MOVLW 03H ADDWF BIN_H,F BTFSC STATUS,C GOTO SUB_1000 INCF BCD_H,F GOTO ADD_1000 SUB_1000 MOVLW 0E8H SUBWF BIN_L,F BTFSS STATUS,C DECF BIN_H,F MOVLW 03H SUBWF BIN_H,F MOVF BCD_H,W ANDLW 0FH IORLW 30H MOVWF ASC4 SWAPF BCD_H,F ADD_100 MOVLW 064H ADDWF BIN_L,F BTFSS STATUS,C GOTO $+4 INCFSZ BIN_H,F GOTO $+2 GOTO SUB_100 INCF BCD_H,F GOTO ADD_100 SUB_100 MOVLW 064H SUBWF BIN_L,F BTFSS STATUS,C DECF BIN_H,F MOVF BCD_H,W ANDLW 0FH IORLW 30H MOVWF ASC3 ADD_10 MOVLW 0AH ADDWF BIN_L,F BTFSS STATUS,C GOTO $+4 INCFSZ BIN_H,F GOTO $+2 GOTO SUB_10 INCF BCD_L,F GOTO ADD_10 SUB_10 MOVLW 00AH SUBWF BIN_L,F BTFSS STATUS,C DECF BIN_H,F MOVF BCD_L,W ANDLW 0FH IORLW 30H MOVWF ASC2 ADD_1 SWAPF BCD_L,F COMF BIN_L,W ADDWF BCD_L,F MOVF BCD_L,W ANDLW 0FH IORLW 30H MOVWF ASC1 RETURN ;---------------------- ; Measuer Data Transmit ;---------------------- ; TX_DATA MOVF POLARITY,W CALL TX MOVF ASC4,W CALL TX MOVLW A'.' CALL TX MOVF ASC3,W CALL TX MOVF ASC2,W CALL TX MOVF ASC1,W CALL TX MOVLW A'V' CALL TX RETURN ;---------------------- ; Data Recieve ;---------------------- ; RX CLRF REC_ERR BTFSS PIR1,RCIF ;check receive end frag GOTO RX 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 ; ;---------------------- ; Data Transmit ;---------------------- ; 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 ; ;---------------------- ; Wait Time count (at 4MHz 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 32 MOVWF W_CNT1 W_P003 ;3uS DECFSZ W_CNT1,F ;1uS,(2uS) GOTO W_P003 ;1uS DECFSZ W_CNT0,F GOTO W_P100 RETURN ; ;******************************************************* ; INTERUPT ;******************************************************* INTERUPT ;**** save W register & status register MOVWF W_TEMP ;save w reg SWAPF STATUS,W ;status to wreg MOVWF ST_TEMP ;save status ; BTFSS PIR1,CCP1IF ;CCP1 Interupt? GOTO INT_END BCF PIR1,CCP1IF ;Clear Flag BTFSC PORTB,SAMPLE GOTO SAM_1S MOVLW AD_CH1 ; AD CH1のコントロールデータ MOVWF AD_CON_TEMP ; 保管レジスタに入れる CALL AD_READ_16 ; 16回AD変換ルーチンの呼び出し MOVF AD_TEMP_L,W ; MOVWF AD1_DATA_L ; MOVF AD_TEMP_H,W ; MOVWF AD1_DATA_H ; 16回ADの平均データをAD1_DATAレジスタに移す MOVLW LOW 1024 ; 1/4オフセット値のLバイトをセット BTFSS PORTB,ZERO ; オフセットスイッチを検査 MOVLW LOW 2048 ; 1/2オフセット値のLバイトをセット SUBWF AD1_DATA_L,F ; オフセット値のLバイトをADデータから減算 BTFSS STATUS,C ; キャリービットの検査 DECF AD1_DATA_H,F MOVLW HIGH 1024 ; 1/4オフセット値のHバイトをセット BTFSS PORTB,ZERO ; オフセットスイッチを検査 MOVLW HIGH 2048 ; 1/2オフセット値のHバイトをセット SUBWF AD1_DATA_H,F ; オフセット値のHバイトをADデータから減算 BTFSS STATUS,C ; キャリービットの検査 GOTO $+4 MOVLW A'+' ; 極性データ + をセット MOVWF POLARITY ; POLARITYレジスタに入れる GOTO $+9 MOVLW A'-' ; 極性データ - をセット MOVWF POLARITY ; POLARITYレジスタに入れる COMF AD1_DATA_L,F ; 極性が−の場合はADデータの補数−1にする COMF AD1_DATA_H,F ; MOVLW 1 ; ADDWF AD1_DATA_L,F ; BTFSC STATUS,C ; INCF AD1_DATA_H,F ; MOVF AD1_DATA_L,W ; ADデータをBIN_L,Hレジスタに移す MOVWF BIN_L ; MOVF AD1_DATA_H,W ; MOVWF BIN_H ; CALL BIN2_BCD3 ; ADデータ(バイナリ)をASCIIに変換する CALL TX_DATA ; ADデータをUSART で送信する MOVLW H'0D' ; CRコードをセット CALL TX ; USART で送信する GOTO INT_END ; 割り込み処理終了 SAM_1S INCF INT_CNT,F BTFSS INT_CNT,0 GOTO $+9 MOVLW AD_CH2 ; AD CH2 MOVWF AD_CH_TEMP CALL AD_READ_256 MOVF TEMP_L,W MOVWF AD2_DATA_L MOVF TEMP_H,W MOVWF AD2_DATA_H GOTO INT_END MOVLW AD_CH1 ; AD CH1 MOVWF AD_CH_TEMP CALL AD_READ_256 MOVF TEMP_L,W MOVWF AD1_DATA_L MOVF TEMP_H,W MOVWF AD1_DATA_H MOVLW LOW 1024 ; AD CH1 Result - ZERO BIAS BTFSS PORTB,ZERO MOVLW LOW 2048 SUBWF AD1_DATA_L,F BTFSS STATUS,C DECF AD1_DATA_H,F MOVLW HIGH 1024 ; 1/4 BTFSS PORTB,ZERO MOVLW HIGH 2048 ; 1/2 SUBWF AD1_DATA_H,F BTFSS STATUS,C GOTO $+4 MOVLW A'+' ; Set + MOVWF POLARITY GOTO $+9 MOVLW A'-' ; Set - MOVWF POLARITY COMF AD1_DATA_L,F COMF AD1_DATA_H,F MOVLW 1 ADDWF AD1_DATA_L,F BTFSC STATUS,C INCF AD1_DATA_H,F MOVF AD1_DATA_L,W MOVWF BIN_L MOVF AD1_DATA_H,W MOVWF BIN_H CALL BIN2_BCD3 ; Convert ASCII CALL TX_DATA MOVLW A',' CALL TX MOVLW A'+' ; Set + MOVWF POLARITY MOVF AD2_DATA_L,W MOVWF BIN_L MOVF AD2_DATA_H,W MOVWF BIN_H CALL BIN2_BCD3 ; Convert ASCII CALL TX_DATA MOVLW H'0D' ; CR Code CALL TX INT_END ;**** register restore and return SWAPF ST_TEMP,W ;get saved status MOVWF STATUS SWAPF W_TEMP,F ;get saved wreg SWAPF W_TEMP,W RETFIE ; END