; 16F876_logicanalyzer.asm 2005/10/26 16:14:30 ; !!! RA4はオープンドレイン !!! RB7 data_bus input A_Mag3 RC7 RX(RS232C) input PCインターフェース ; RB6 data_bus input A_Mag2 RC6 TX(RS232C) output PCインターフェース ; RA5 ENDCNT input H 測定終了 RB5 data_bus input A_Mag1 RC5 CTLAD1 output 制御アドレス1 ; RA4 CTLSTB output L ストローブ RB4 data_bus input A_Mag0 RC4 CTLAD0 output 制御アドレス0 ; RA3 anaWE output L アナログWE RB3 data_bus input RC3 CTLDT3 output 制御信号3 ; RA2 log_LED output L ロジアナ表示 RB2 data_bus input RC2 CTLDT2 output 制御信号2 ; RA1 ana_LED output L アナログ表示 RB1 data_bus input RC1 CTLDT1 output 制御信号1 ; RA0 anain analog アナログ入力 RB0 data_bus input RC0 CTLDT0 output 制御信号0 ; TRISA b'00100001' TRISB b'11111111' TRISC b'10000000' ; CTLAD CTLDTx3 CTLDTx2 CTLDTx1 CTLDTx0 ; 3 comp ref_data 3--0 ; 2 トリガ信号(D3〜D0)選択 H/L=H/Lレベル H/L=edge/lebel ; 1 H/L=comp/bit CLK選択 2--0 (0:10Mhz 1:5MHz 2:2MHz 3:1MHz 4:500KHz 5:200KHz 6:100KHz 7:50KHz) ; 0 L=GATE開 H=測定開始 H=RAMアドレスカウンタクリア L=RAM出力イネーブル ; RX_COM 上位4bit ; 下位4bit 3 2 1 0 ; 0 L=GATE開 H=測定開始 H=RAMアドレスカウンタクリア L=RAM出力イネーブル ; 1 H/L=comp/bit CLK選択 2--0 (0:10Mhz 1:5MHz 2:2MHz 3:1MHz 4:500KHz 5:200KHz 6:100KHz 7:50KHz) ; 2 トリガ信号(D3〜D0)選択 H/L=H/Lレベル H/L=edge/lebel ; 3 comp ref_data 3--0 ; 4 測定開始 ; 5 アドレス付き測定開始 05,stop(0000〜7FFF) ex. 0501FF ; 6 読込 ; 7 アドレス付き読込 07,stop(0000〜7FFF) ex. 0701FF ; 8 制御信号 送信 ; 9 動作モード 0001:アナログ 0000:ロジアナ ; A 予備 ; B 予備 ; C 予備 ; D 予備 ; E 測定中止 ; F 使用禁止 ; RX_COM 応答 ; 0〜5,9 ACK(6) ; 6〜7 STX(2),アドレス上位,下位,ロジアナデータ(,アナログデータ)・・・80H ex. 020000A505・・・80 ; 変化のあったデータのみ、アドレスをつけて送信する 終了フラグは80H ; 8 STX(2),制御信号1,制御信号2,制御信号3,動作モード,ETX(3) ex. 0201A2731903 ; E アナログ時 グSTX(2),中止アドレス上位,下位,ETX(3) ex. 0203F803 ; ロジアナ時 NAC(15H) ; アナログ レンジ ; RB7--RB4 RA2,RA1がLowの時RBを入力する 切替が発生した場合、下のコードを送信する ; A_Mag4 EF ±0.5V ; A_Mag3 DF ±2.5V ; A_Mag2 BF ±5V ; A_Mag1 7F ±10V ; A_Mag0 FF ±25V list p=PIC16F876 #include __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _DEBUG_OFF & _HS_OSC & _LVP_OFF & _PWRTE_ON & _WDT_OFF & _WRT_ENABLE_ON CBLOCK 20H RXCTLDT ; 受信した制御信号 AD_mode ; 2^0:動作モード L/H=ロジアナ/アナログ CTL3DATA ; 制御信号3バッファ 上位4bit "0011" CTL2DATA ; 制御信号2バッファ 上位4bit "0010" CTL1DATA ; 制御信号1バッファ 上位4bit "0001" CTL0DATA ; 制御信号0バッファ 上位4bit "0000" readaddl ; 読込中アドレス readaddu stopaddl ; 測定 or 読込終了アドレス 0000〜 7FFF stopaddu refdat ; 前回ロジアナデータ(基準) newdat ; 今回ロジアナデータ refanl ; 前回アナログデータ(基準) newanl ; 今回アナログデータ A_Mag ; アナログ レンジ cntxxm ; カウンタ for xxmsec work ; 汎用 W_temp STATUS_temp ENDC #define CTLSTB PORTA,4 ; ストローブ #define anaWE PORTA,3 ; アナログWE #define log_LED PORTA,2 ; ロジアナLED #define ana_LED PORTA,1 ; アナログLED COMMOUT MACRO COMBUFF ; 制御信号出力 movwf PORTC movwf COMBUFF bcf CTLSTB nop bsf CTLSTB nop ENDM org 0 BANKSEL ADCON1 ; bank1 goto start nop ; -------------------------interrupt routine-------------------------------- org 4 movwf W_temp ; save W movf STATUS,W movwf STATUS_temp ; save STATUS BANKSEL ADCON1 ; bank1 movlw d'21' ; set timer value 256-47μs/0.2μs = 21 btfss OPTION_REG,3 ; skip if prescalerなし clrw ; set timer value 256-13.1072ms/51.2μs = 0 BANKSEL ADCON0 ; bank0 movwf TMR0 ; TMR0 = 13.1072ms or 47μs bcf INTCON,T0IF ; clear timer int flag movf cntxxm,F btfss STATUS,Z ; skip if xxmsec up decf cntxxm,F movf STATUS_temp,W movwf STATUS ; restore STATUS swapf W_temp,F swapf W_temp,W ; restore W retfie ; -------------------------main routine-------------------------------- start movlw b'00001110' ; 左詰め AN0:アナログ RA5-RA1:デジタル movwf ADCON1 movlw b'01010111' ; pullup on TMR0CLK=osc/4=5MHz movwf OPTION_REG ; prescaler=1/256 51.2μsec movlw b'00100001' movwf TRISA movlw b'11111111' movwf TRISB movlw b'10000000' movwf TRISC movlw b'00100100' ; 許可 非同期 高速 movwf TXSTA movlw d'64' ; 20MHz 64 at 19200bps movwf SPBRG BANKSEL ADCON0 ; bank0 movlw b'10000000' ; fosc/32 turn off A/D movwf ADCON0 movlw b'10010000' ; シリアル 連続 movwf RCSTA movlw b'11111111' movwf PORTA ; LED off ストローブ off movwf PORTB movwf PORTC movlw RXCTLDT movwf FSR start1 clrf INDF ; clear memory incf FSR,F movlw STATUS_temp+1 subwf FSR,W btfss STATUS,Z goto start1 movlw b'00001011' ; GATE閉 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA movlw b'00010000' ; bit/サンプリング周波数=10MHz COMMOUT CTL1DATA movlw b'00100011' ; トリガ:D0 立ち上がり COMMOUT CTL2DATA movlw b'00110000' ; dummy(comp ref_data) COMMOUT CTL3DATA clrw ; set timer value 256-13.1072ms/51.2μs = 0 movwf TMR0 ; TMR0 = 13.1072ms movlw b'10100000' ; 割込み許可 GIE=1,T0IE=1 movwf INTCON movf RCREG,W ; 受信フラグクリア(誤受信防止) main movf cntxxm,F btfss STATUS,Z ; skip if 300msec up goto main1 movlw d'23' movwf cntxxm ; set 300msec(13.1072msec×23) bcf log_LED ; log_LED on bcf ana_LED ; ana_LED on nop nop movf PORTB,W ; アナログ レンジ読込 bsf log_LED ; log_LED off bsf ana_LED ; ana_LED off movwf work subwf A_Mag,W btfsc STATUS,Z ; skip if 切替 goto main1 movf work,W movwf A_Mag ; アナログ レンジ送信 call txdt main1 btfss PIR1,RCIF ; skip if USART 受信割り込み goto main btfsc RCSTA,FERR ; skip if not フレーミングエラー(1:エラー,0:正常) goto main2 btfsc RCSTA,OERR ; skip if not オーバーランエラー(1:エラー,0:正常) goto main2 bcf INTCON,7 ; 割込み全禁止 GIE=0 movf RCREG,W ; RCREGレジスタから受信データを読み込む movwf RXCTLDT call analys BANKSEL ADCON1 ; bank1 movlw b'01010111' ; pullup on TMR0CLK=osc/4=5MHz movwf OPTION_REG ; prescaler=1/256 51.2μsec BANKSEL ADCON0 ; bank0 bsf INTCON,7 ; interrupt enable GIE=1 goto main main2 movf RCREG,W ; フレーミングエラーフラグのクリア bcf RCSTA,CREN ; オーバーランエラーフラグのクリア bsf RCSTA,CREN goto main ; -------------------------------sub routine-------------------------------- ; 制御信号解析 analys movlw $/0x100 movwf PCLATH movf RXCTLDT,W andlw h'0F' addwf PCL,F goto comot0 ; 0 goto comot1 ; 1 goto comot2 ; 2 goto comot3 ; 3 goto measall ; 4 測定開始 goto measadr ; 5 アドレス付き測定開始 上位下位の順 goto readall ; 6 読込 goto readadr ; 7 アドレス付き読込 上位下位の順 goto txctldt ; 8 制御信号 送信 goto exmode ; 9 動作モード return ; A 予備 return ; B 予備 return ; C 予備 return ; D 予備 return ; E 測定中止 アナログ測定中のみ(ここでは受け付けない) return ; F 使用禁止 wat_dat movlw $/0x100 movwf PCLATH movf CTL1DATA,W andlw d'7' addwf PCL,F DT d'1' ; 0 50μs 20KHz DT d'2' ; 1 100μs 10KHz DT d'4' ; 2 200μs 5KHz DT d'10' ; 3 500μs 2KHz DT d'20' ; 4 1ms 1KHz DT d'40' ; 5 2ms 500Hz DT d'100' ; 6 5ms 200Hz DT d'200' ; 7 10ms 100Hz comot0 swapf RXCTLDT,W ; GATE 測定開始 RAMアドレスカウンタクリア RAM出力イネーブル COMMOUT CTL0DATA goto trunca1 comot1 swapf RXCTLDT,W ; comp/bit CLK選択 COMMOUT CTL1DATA goto trunca1 comot2 swapf RXCTLDT,W ; トリガ信号(D3〜D0)選択 H/Lレベル edge/lebel COMMOUT CTL2DATA goto trunca1 comot3 swapf RXCTLDT,W ; comp ref_data COMMOUT CTL3DATA goto trunca1 measall call alladdr ; 全アドレス設定 goto measure measadr call rxaddr ; アドレス受信 measure btfss AD_mode,0 ; skip if アナログモード goto logiana goto analog exmode swapf RXCTLDT,W ; 動作モード設定 andlw d'1' movwf AD_mode goto trunca1 ; ---------------------- ; ロジアナ測定 logiana movlw b'00000011' ; GATE開 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA ; 最初にGATEを開いて、CPLD内の同期微分出力を有効にする bcf log_LED ; log_LED on bsf ana_LED ; ana_LED off movlw b'00000101' ; GATE開 測定 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA logian1 btfss PIR1,RCIF ; skip if USART 受信割り込み goto logian3 btfsc RCSTA,FERR ; skip if not フレーミングエラー(1:エラー,0:正常) goto logian2 btfsc RCSTA,OERR ; skip if not オーバーランエラー(1:エラー,0:正常) goto logian2 movf RCREG,W ; RCREGレジスタから受信データを読み込む sublw h'E' btfss STATUS,Z ; skip if 測定中止 goto logian3 movlw b'00001011' ; GATE閉 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA movlw h'15' ; NAC call txdt return logian2 movf RCREG,W ; フレーミングエラーフラグのクリア bcf RCSTA,CREN ; オーバーランエラーフラグのクリア bsf RCSTA,CREN logian3 btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto logian1 nop btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto logian1 nop btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto logian1 truncat movlw b'00001011' ; GATE閉 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA trunca1 movlw d'6' ; ACK call txdt return ; ---------------------- ; アナログ測定 analog movf stopaddl,W movwf readaddl movf stopaddu,W movwf readaddu incfsz readaddl,F ; skip if オーバーフロー goto analog1 incf readaddu,F analog1 bsf log_LED ; log_LED off bcf ana_LED ; ana_LED on movlw b'10000001' ; select AN0 turn on movwf ADCON0 BANKSEL ADCON1 ; bank1 movlw b'01011111' ; pullup on TMR0CLK=osc/4=5MHz movwf OPTION_REG ; prescalerなし 0.2μsec BANKSEL ADCON0 ; bank0 movlw d'156' ; set timer value 256-20μs/0.2μs = 156 movwf TMR0 ; TMR0 = 20μs bcf INTCON,T0IF ; clear timer int flag movlw d'1' goto analog3 analog2 call wat_dat ; load wait time analog3 movwf cntxxm bsf INTCON,7 ; interrupt enable GIE=1 TOIE=1 analog4 movf cntxxm,F btfss STATUS,Z ; skip if xxmsec up goto analog4 bcf INTCON,7 ; 割込み全禁止 GIE=0 nop call ad_conv decfsz readaddl,F ; skip if 下位-1=0 goto analog5 movf readaddu,F btfss STATUS,Z ; skip if 上位=0 goto analog6 goto analog9 analog5 comf readaddl,W btfsc STATUS,Z ; skip if 下位<>FFH decf readaddu,F ; 上位 カウント analog6 btfss PIR1,RCIF ; skip if USART 受信割り込み goto analog8 btfsc RCSTA,FERR ; skip if not フレーミングエラー(1:エラー,0:正常) goto analog7 btfsc RCSTA,OERR ; skip if not オーバーランエラー(1:エラー,0:正常) goto analog7 movf RCREG,W ; RCREGレジスタから受信データを読み込む sublw h'E' btfss STATUS,Z ; skip if 測定中止 goto analog8 movlw b'00001011' ; GATE閉 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA movlw b'10000000' ; turn off A/D movwf ADCON0 movlw d'2' ; STX call txdt movf readaddl,W ; 中止時のアドレス計算 subwf stopaddl,F btfss STATUS,C ; skip if stopaddl>=readaddl decf stopaddu,F movf readaddu,W subwf stopaddu,F movf stopaddu,W ; 中止時のアドレス送信 call txdt movf stopaddl,W call txdt movlw d'3' ; ETX call txdt return analog7 movf RCREG,W ; フレーミングエラーフラグのクリア bcf RCSTA,CREN ; オーバーランエラーフラグのクリア bsf RCSTA,CREN analog8 btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto analog2 nop btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto analog2 nop btfss PORTA,5 ; skip if 測定終了 誤動作防止 goto analog2 analog9 movlw b'10000000' ; turn off A/D movwf ADCON0 goto truncat ; 停止処理 ; ---------------------- ; A/D変換 ad_conv bsf ADCON0,GO ; A/D start movlw b'00000001' ; GATE開 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA bcf anaWE ; アナログWE出力(デジタルデータ書込み) nop bsf anaWE movlw b'00001001' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA adloop btfsc ADCON0,GO ; skip if A/D done goto adloop BANKSEL ADCON1 ; bank1 clrf TRISB ; PORTB出力設定 BANKSEL ADCON0 ; bank0 movf ADRESH,W ; get A/D data movwf PORTB ; A/D -> RAM nop bcf anaWE ; アナログWE出力(アナログデータ書込み) nop bsf anaWE BANKSEL ADCON1 ; bank1 comf TRISB,F ; PORTB入力設定 BANKSEL ADCON0 ; bank0 return ; ---------------------- ; 32Kbyte読込 readall call alladdr ; 全アドレス設定 goto readdat ; ---------------------- ; アドレス付き読込 readadr call rxaddr ; アドレス受信 ; ---------------------- ; データ読込 & 送信 readdat movlw b'00001011' ; GATE閉 測定停止 RAMアドレスカウンタクリア RAM出力禁止 COMMOUT CTL0DATA btfss AD_mode,0 ; skip if アナログモード goto readdt1 bsf log_LED ; log_LED off bcf ana_LED ; ana_LED on goto readdt2 readdt1 bcf log_LED ; log_LED on bsf ana_LED ; ana_LED off readdt2 movlw d'2' ; STX call txdt movf readaddu,W call txdt ; 読込アドレス上位送信 movf readaddl,W call txdt ; 読込アドレス下位送信 movlw b'00001000' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力 COMMOUT CTL0DATA nop nop movf PORTB,W ; データ読込 movwf refdat ; 初回データ call txdt ; データ送信 movlw b'00001001' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA ; RAMアドレスカウントアップ btfss AD_mode,0 ; skip if アナログモード goto readdt6 nop nop movlw b'00001000' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力 COMMOUT CTL0DATA nop nop movf PORTB,W ; アナログデータ読込 movwf refanl ; 初回デー call txdt ; アナログデータ送信 movlw b'00001001' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA ; RAMアドレスカウントアップ goto readdt6 readdt3 movlw b'00001000' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力 COMMOUT CTL0DATA nop nop movf PORTB,W ; データ読込 movwf newdat movlw b'00001001' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA ; RAMアドレスカウントアップ btfss AD_mode,0 ; skip if アナログモード goto readdt4 nop nop movlw b'00001000' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力 COMMOUT CTL0DATA nop nop movf PORTB,W ; アナログデータ読込 movwf newanl movlw b'00001001' ; GATE閉 測定停止 RAMアドレスカウンタイネーブル RAM出力禁止 COMMOUT CTL0DATA ; RAMアドレスカウントアップ readdt4 movf newdat,W subwf refdat,W btfss STATUS,Z ; skip if 前回データ=今回データ goto readdt5 btfss AD_mode,0 ; skip if アナログモード goto readdt6 movf newanl,W subwf refanl,W btfsc STATUS,Z ; skip if 前回データ<>今回データ goto readdt6 readdt5 movf readaddu,W call txdt ; 読込アドレス上位送信 movf readaddl,W call txdt ; 読込アドレス下位送信 movf newdat,W movwf refdat call txdt ; データ送信 btfss AD_mode,0 ; skip if アナログモード goto readdt6 movf newanl,W movwf refanl call txdt ; アナログデータ送信 readdt6 incfsz readaddl,F ; skip if 下位アドレス オーバーフロー goto readdt7 incf readaddu,F readdt7 ; (readaddu & readaddl)>(stopaddu & stopaddl)になるまで、readdt3間繰返し movf readaddu,W subwf stopaddu,W btfss STATUS,C ; skip if stopaddu>=readaddu goto readdt8 btfss STATUS,Z ; skip if stopaddu=readaddu goto readdt3 movf readaddl,W subwf stopaddl,W btfsc STATUS,C ; skip if stopaddl