'-------------------------------------------------------------- 2005-12-14 ----- ' Digital Read Out Version3 '------------------------------------------------------------------------------- program DRO '---- (single LED) device definitions --------------- symbol LED_TRIS = TRISB symbol LED_PORT = PORTB symbol LED_BIT = 0 '---- (7segment LED) device definitions ------------ symbol LED_DEV1_TRIS = TRISB symbol LED_DEV2_TRIS = TRISB symbol LED_DEV3_TRIS = TRISB symbol LED_DEV4_TRIS = TRISB symbol LED_DEV5_TRIS = TRISB symbol LED_DEV1_PORT = PORTB symbol LED_DEV2_PORT = PORTB symbol LED_DEV3_PORT = PORTB symbol LED_DEV4_PORT = PORTB symbol LED_DEV5_PORT = PORTB symbol LED_DEV1_BIT = 1 symbol LED_DEV2_BIT = 2 symbol LED_DEV3_BIT = 3 symbol LED_DEV4_BIT = 6 symbol LED_DEV5_BIT = 7 symbol LED_SEG_TRIS = TRISC symbol LED_SEG_PORT = PORTC '---- (Digital Scale Unit) device definitions ------ symbol DSU_CLOCK_TRIS = TRISB symbol DSU_CLOCK_PORT = PORTB symbol DSU_CLOCK_BIT = 4 symbol DSU_DATA_TRIS = TRISB symbol DSU_DATA_PORT = PORTB symbol DSU_DATA_BIT = 5 '---- (Internal Switch) device definitions --------- symbol INT_KEY1_TRIS = TRISA symbol INT_KEY2_TRIS = TRISA symbol INT_KEY3_TRIS = TRISA symbol INT_KEY1_PORT = PORTA symbol INT_KEY2_PORT = PORTA symbol INT_KEY3_PORT = PORTA symbol INT_KEY1_BIT = 2 symbol INT_KEY2_BIT = 3 symbol INT_KEY3_BIT = 4 symbol KEY_SET = 1 symbol KEY_CANSEL = 2 symbol KEY_MEMORY = 3 '---- (External Switch) device definitions --------- symbol EXT_KEY_ENABLE_TRIS = TRISA symbol EXT_KEY_ENABLE_PORT = PORTA symbol EXT_KEY_ENABLE_BIT = 5 symbol EXT_KEY_CLOCK_TRIS = TRISA symbol EXT_KEY_CLOCK_PORT = PORTA symbol EXT_KEY_CLOCK_BIT = 0 symbol EXT_KEY_DATA_TRIS = TRISA symbol EXT_KEY_DATA_PORT = PORTA symbol EXT_KEY_DATA_BIT = 1 '---- symbol definisions ---------------------------- symbol POWER_ON_BIT = 0 symbol DSU_SIGNAL_BIT = 1 '---- symbol definisions ---------------------------- symbol PORT_OUTPUT = 0 symbol PORT_INPUT = 1 symbol HIGH = 1 symbol LOW = 0 symbol ENABLE = 1 symbol DISABLE = 0 symbol CHANGED = 1 symbol NOT_CHANGED = 0 symbol YES = 1 symbol NO = 0 symbol PLUS = $00 symbol MINUS = $FF '---- 7segment LED const definitions ---------------- const Digit_N = $00 ' Blank const Digit_0 = $3F ' Number 0 const Digit_1 = $06 ' Number 1 const Digit_2 = $5B ' Number 2 const Digit_3 = $4F ' Number 3 const Digit_4 = $66 ' Number 4 const Digit_5 = $6D ' Number 5 const Digit_6 = $7D ' Number 6 const Digit_7 = $07 ' Number 7 const Digit_8 = $7F ' Number 8 const Digit_9 = $6F ' Number 9 const Digit_E = $79 ' char 'E' const Digit_H = $76 ' char 'H' const Digit_L = $39 ' left parenthesis const Digit_R = $0F ' right parenthesis const Digit_DP = $80 ' decimal point '---- Key code definitions --------------------------- const CODE_SET = "S" const CODE_CAN = "C" const CODE_MEM = "M" '---- アセンブラから参照される Global variable definitions --------------------- dim dsu_data1 as byte absolute $20 ' DSUからの24ビットデータ 最下位バイト dim dsu_data2 as byte absolute $21 ' DSUからの24ビットデータ 中 位バイト dim dsu_data3 as byte absolute $22 ' DSUからの24ビットデータ 最上位バイト dim dsu_count as byte absolute $23 ' DSUからの24ビットデータ 最下位バイト dim dsu_raw as longint absolute $24 ' DSU RAW data dim dummy as byte dim dsu_stat as byte dim led_val1 as byte dim led_val2 as byte dim led_val3 as byte dim led_val4 as byte dim led_val5 as byte dim led_pos as byte '=============================================================================== ' Interrupt 割り込みルーチン '=============================================================================== sub procedure interrupt if INTCON.T0IF = 1 then LED_DEV1_PORT = 0 select case led_pos case 1 LED_DEV5_PORT.LED_DEV5_BIT = LOW LED_SEG_PORT = led_val1 LED_DEV1_PORT.LED_DEV1_BIT = HIGH led_pos = led_pos + 1 case 2 LED_DEV1_PORT.LED_DEV1_BIT = LOW LED_SEG_PORT = led_val2 LED_DEV2_PORT.LED_DEV2_BIT = HIGH led_pos = led_pos + 1 case 3 LED_DEV2_PORT.LED_DEV2_BIT = LOW LED_SEG_PORT = led_val3 LED_DEV3_PORT.LED_DEV3_BIT = HIGH led_pos = led_pos + 1 case 4 LED_DEV3_PORT.LED_DEV3_BIT = LOW LED_SEG_PORT = led_val4 LED_DEV4_PORT.LED_DEV4_BIT = HIGH led_pos = led_pos + 1 case 5 LED_DEV4_PORT.LED_DEV4_BIT = LOW LED_SEG_PORT = led_val5 LED_DEV5_PORT.LED_DEV5_BIT = HIGH led_pos = 1 end select TMR0 = 100 INTCON.T0IF = 0 ' Clear interrupt flag goto END_INT end if if PIR1.TMR2IF = 1 then T2CON.TMR2ON = 0 ' STOP TMR2 PIR1.TMR2IF = 0 ' Clear TMR2 interrupt flag dummy = PORTB INTCON.RBIF = 0 ' Clear PORTB interrupt flag INTCON.RBIE = 1 ' Enable PORTB interrupt goto END_INT end if if INTCON.RBIF = 1 then LED_PORT.LED_BIT = HIGH ' LED ON LED_PORT.LED_BIT = LOW ' LED OFF LED_PORT.LED_BIT = HIGH ' LED ON LED_PORT.LED_BIT = LOW ' LED OFF LED_PORT.LED_BIT = HIGH ' LED ON while( DSU_CLOCK_PORT.DSU_CLOCK_BIT = HIGH ) wend asm bcf STATUS,RP0 ' バンク0に切り替え bcf STATUS,RP1 '------- receive 1st byte ---------------------- movlw 8 movwf main_global_dsu_count ' Detect Clock Low -> High CLOCK_LOOP_L: rrf main_global_dsu_data1,1 ' この命令1回目は空回り LTOH_L: btfss DSU_CLOCK_PORT,DSU_CLOCK_BIT ' Low の間Loop = Highを見つけたら次に goto LTOH_L ' set DATA btfsc DSU_DATA_PORT,DSU_DATA_BIT goto SET_HIGH_L goto SET_LOW_L SET_HIGH_L: bsf main_global_dsu_data1,7 goto HTOL_L SET_LOW_L: bcf main_global_dsu_data1,7 ' Detect Clock High -> Low HTOL_L: btfsc DSU_CLOCK_PORT,DSU_CLOCK_BIT ' High の間Loop = Lowを見つけたら次に goto HTOL_L decfsz main_global_dsu_count,F goto CLOCK_LOOP_L '------- receive 2nd byte ---------------------- movlw 8 movwf main_global_dsu_count ' Detect Clock Low -> High CLOCK_LOOP_M: rrf main_global_dsu_data2,1 ' この命令1回目は空回り LTOH_M: btfss DSU_CLOCK_PORT,DSU_CLOCK_BIT ' Low の間Loop = Highを見つけたら次に goto LTOH_M ' set DATA btfsc DSU_DATA_PORT,DSU_DATA_BIT goto SET_HIGH_M goto SET_LOW_M SET_HIGH_M: bsf main_global_dsu_data2,7 goto HTOL_M SET_LOW_M: bcf main_global_dsu_data2,7 ' Detect Clock High -> Low HTOL_M: btfsc DSU_CLOCK_PORT,DSU_CLOCK_BIT ' High の間Loop = Lowを見つけたら次に goto HTOL_M decfsz main_global_dsu_count,F goto CLOCK_LOOP_M '------- receive 3rd byte ---------------------- movlw 8 movwf main_global_dsu_count ' Detect Clock Low -> High CLOCK_LOOP_H: rrf main_global_dsu_data3,1 ' この命令1回目は空回り LTOH_H: btfss DSU_CLOCK_PORT,DSU_CLOCK_BIT ' Low の間Loop = Highを見つけたら次に goto LTOH_H ' set DATA btfsc DSU_DATA_PORT,DSU_DATA_BIT goto SET_HIGH_H goto SET_LOW_H SET_HIGH_H: bsf main_global_dsu_data3,7 goto HTOL_H SET_LOW_H: bcf main_global_dsu_data3,7 ' Detect Clock High -> Low HTOL_H: btfsc DSU_CLOCK_PORT,DSU_CLOCK_BIT ' High の間Loop = Lowを見つけたら次に goto HTOL_H decfsz main_global_dsu_count,F goto CLOCK_LOOP_H '------------------------------------------------ rrf main_global_dsu_data3,F rrf main_global_dsu_data2,F rrf main_global_dsu_data1,F rrf main_global_dsu_data3,F rrf main_global_dsu_data2,F rrf main_global_dsu_data1,F rrf main_global_dsu_data3,F rrf main_global_dsu_data2,F rrf main_global_dsu_data1,F end asm if dsu_data3.4 = 1 then dsu_data3 = dsu_data3 or %11100000 else dsu_data3 = dsu_data3 and %00011111 end if dsu_stat.DSU_SIGNAL_BIT = CHANGED LED_PORT.LED_BIT = LOW ' LED OFF INTCON.RBIE = 0 ' Disable PORTB interrupt dummy = PORTB INTCON.RBIF = 0 ' Clear PORTB interrupt flag TMR2 = 100 PIR1.TMR2IF = 0 ' Clear TMR2 interrupt flag T2CON.TMR2ON = 1 ' START TMR2 end if END_INT: end sub '=============================================================================== ' decode ascii-char -> 7segment-LED '=============================================================================== sub function led7seg_decode( dim ascii_char as byte ) as byte select case ascii_char case "-" result = Digit_N case " " result = Digit_N case "0" result = Digit_0 case "1" result = Digit_1 case "2" result = Digit_2 case "3" result = Digit_3 case "4" result = Digit_4 case "5" result = Digit_5 case "6" result = Digit_6 case "7" result = Digit_7 case "8" result = Digit_8 case "9" result = Digit_9 case else result = Digit_E end select end sub sub procedure eewlong( dim addr as byte, dim dv as longint ) eeprom_write( addr+0, Lo( dv ) ) eeprom_write( addr+1, hi( dv ) ) eeprom_write( addr+2, higher( dv ) ) eeprom_write( addr+3, highest( dv ) ) end sub '******************************************************************************* ' Program main '******************************************************************************* main: dim led_txt as string[11] dim dsu_cal as longint dim dsu_ini as longint dim dsu_disp as longint dim dsu_div as longint dim dsu_sign as byte '' dim work_byte as byte led_txt = " " dsu_cal = 0 dsu_ini = 0 dsu_disp = 0 dsu_div = 0 ' dummy1 = 0 ' 変数初期化 dsu_data1 = 0 dsu_data2 = 0 dsu_data3 = 0 dsu_data1 = 0 dsu_count = 0 dsu_raw = 0 dsu_stat.DSU_SIGNAL_BIT = NOT_CHANGED dsu_stat.POWER_ON_BIT = YES led_val1 = Digit_0 led_val2 = Digit_0 led_val3 = Digit_0 led_val4 = Digit_0 led_val5 = Digit_0 led_pos = 1 '---- debug ------------------------ eeprom_write( 0, $00 ) eeprom_write( 1, $80 ) eeprom_write( 2, $00 ) eeprom_write( 3, $00 ) eeprom_write( 4, $00 ) eeprom_write( 5, $00 ) '----------------------------------- delay_ms(20) ' minimum 20ms delay after eeprom_write if eeprom_read( $00 ) = $00 then dsu_cal = dsu_cal or eeprom_read( $04 ) dsu_cal = dsu_cal << 8 dsu_cal = dsu_cal or eeprom_read( $03 ) dsu_cal = dsu_cal << 8 dsu_cal = dsu_cal or eeprom_read( $02 ) dsu_cal = dsu_cal << 8 dsu_cal = dsu_cal or eeprom_read( $01 ) dsu_sign = eeprom_read( $05 ) end if '---- initialize ------------------------- LED_TRIS.LED_BIT = PORT_OUTPUT LED_PORT.LED_BIT = HIGH ' LED ON delay_ms(1000) '---- port A digital INPUT-OUTPUT -------- ADCON1 = %00000110 '---- disable port B pull-up ------------- OPTION_REG.NOT_RBPU = 1 '---- DSU port initialize (set INPUT) ---- DSU_CLOCK_TRIS.DSU_CLOCK_BIT = PORT_INPUT ' Digital Scale Unit CLOCK DSU_DATA_TRIS.DSU_DATA_BIT = PORT_INPUT ' Digital Scale Unit DATA '---- 7segment LED port initialize (set OUTPUT) ---- LED_DEV1_TRIS.LED_DEV1_BIT = PORT_OUTPUT ' 7 SEGMENT LED 1 LED_DEV2_TRIS.LED_DEV2_BIT = PORT_OUTPUT ' 7 SEGMENT LED 2 LED_DEV3_TRIS.LED_DEV3_BIT = PORT_OUTPUT ' 7 SEGMENT LED 3 LED_DEV4_TRIS.LED_DEV4_BIT = PORT_OUTPUT ' 7 SEGMENT LED 4 LED_DEV5_TRIS.LED_DEV5_BIT = PORT_OUTPUT ' 7 SEGMENT LED 5 LED_SEG_TRIS = PORT_OUTPUT ' 7 SEGMENT LED SEGMENT '---- Internal switch initialize (set INPUT) ------- INT_KEY1_TRIS.INT_KEY1_BIT = PORT_INPUT INT_KEY2_TRIS.INT_KEY2_BIT = PORT_INPUT INT_KEY3_TRIS.INT_KEY3_BIT = PORT_INPUT '------------------------------------------------------------------------------ ' 電源を入れたタイミングが悪くてデジタルスケールユニットから信号が来ている途中から ' 割り込みがかからないようにするためのWAIT処理 '------------------------------------------------------------------------------ while( DSU_CLOCK_PORT.DSU_CLOCK_BIT = HIGH ) wend delay_ms(3) ' 1つの信号の送信時間は0.8msなので ' 1ms待てば十分だが十分な時間の3ms待つ LED_PORT.LED_BIT = LOW ' LED OFF INTCON.INTE = 0 ' Disable PORTB0 interrupt INTCON.RBIE = 1 ' Enable PORTB4-7 interrupts '---- TMR0 initialize -------------------- OPTION_REG.PS2 = 1 ' PreScaler 1:32 OPTION_REG.PS1 = 0 ' PreScaler 1:32 OPTION_REG.PS0 = 0 ' PreScaler 1:32 OPTION_REG.PSA = 0 ' PreScaler assign TMR0 INTCON.T0IE = 1 ' Enable interrupt INTCON.T0IF = 0 ' Clear interrupt flag TMR0 = 100 OPTION_REG.T0CS = 0 ' Start Timer0 '---- TMR2 initialize -------------------- T2CON.TOUTPS3 = 0 ' PostScaler 1:4 T2CON.TOUTPS2 = 1 ' PostScaler 1:4 T2CON.TOUTPS1 = 0 ' PostScaler 1:4 T2CON.TOUTPS0 = 0 ' PostScaler 1:4 T2CON.T2CKPS1 = 1 ' PreScaler 1:16 T2CON.T2CKPS0 = 1 ' PreScaler 1:16 PIE1.TMR2IE = 1 ' Enable interrupt PIR1.TMR2IF = 0 ' Clear interrupt flag INTCON.PEIE = 1 ' Enable Peripheral interrupt dummy = PORTB INTCON.RBIF = 0 ' Clear PORTB interrupt flag INTCON.GIE = 1 ' Enable interrupts while( TRUE ) if dsu_stat.DSU_SIGNAL_BIT = CHANGED then asm bcf STATUS,RP0 ' SET bank 0 bcf STATUS,RP1 movf main_global_dsu_data1,W movwf main_global_dsu_raw_1 movf main_global_dsu_data2,W movwf main_global_dsu_raw_2 movf main_global_dsu_data3,W movwf main_global_dsu_raw_3 clrf main_global_dsu_raw_4 btfsc main_global_dsu_data3,7 comf main_global_dsu_raw_4,F end asm if dsu_stat.POWER_ON_BIT = YES then dsu_ini = dsu_raw dsu_stat.POWER_ON_BIT = NO end if dsu_disp = dsu_raw - dsu_ini dsu_div = dsu_disp div dsu_cal ' if INT_KEY1_PORT.INT_KEY1_BIT = LOW then ' eewlong( $10, dsu_disp ) ' eewlong( $20, dsu_d1 ) ' eewlong( $30, dsu_d2 ) ' while(true) ' wend ' end if if dsu_sign = PLUS then dsu_disp = dsu_disp - dsu_div else dsu_disp = dsu_disp + dsu_div end if LongintToStr( dsu_disp, led_txt ) led_val1 = led7seg_decode( led_txt[10] ) led_val2 = led7seg_decode( led_txt[9] ) led_val3 = led7seg_decode( led_txt[8] ) led_val4 = led7seg_decode( led_txt[7] ) led_val5 = led7seg_decode( led_txt[6] ) led_val3 = led_val3 or Digit_DP if dsu_disp < 0 then led_val1 = led_val1 or Digit_DP end if dsu_stat.DSU_SIGNAL_BIT = NOT_CHANGED end if wend end.