; ; Capacitance meter and ESR electrolytic capacitors ; C / ESR meter ; Author Hinze Oleg , Version 1.01 ; Date 20/04/2007 ; ; The program used snippets meter FLC ; Alexander Buevskogo, Minsk, Belarus ; PIN ASSIGNMENT CONTROLLER PIC16F873A ;************************************************* ************************************** * FOOT * * FUNCTION NAME ;************************************************* ************************************** , 1 * MCLR / Vpp * Reset 2 * RA0/AN0 * output control (gain = 330) 3 * RA1/AN1 * output control (gain = 33) 4 * RA2/AN2/Vref- * KH. Set coeff. / Set "0" , 5 * RA3/AN3/Vref + * , 6 * RA4/T0CKI * KH. + / Test , 7 * RA5/AN4/SS * KH .- , 8 * Vss * GND , 9 * OSC1/CLKIN * Quartz 20 MHz , 10 * OSC2/CLKOUT * Quartz 20 MHz , 11 * RC0/T1OSO/T1CKI * Yield Cl, I = 10mA , 12 * RC1/T1OSI/CCP2 * Rank Cx : 13 * RC2/CCP1 * Comparator top-level charging Cx : 14 * RC3/SCK/SCL * Rin. "-" On the ground , 15 * RC4/SDI/SDA * Rin. "+" On Cx , 16 * RC5/SDO * Rin. "-" On Cx : 17 * RC6/TX/CK * Comparator lower charge level Cx , 18 * RC7/RX/DT * : 19 * Vss * +5 V , 20 * Vdd * GND : 21 * RB0/INT * LCD_D4 : 22 * RB1 * LCD_D5 : 23 * RB2 * LCD_D6 : 24 * RB3/PGM * LCD_D7 , 25 * RB4 * LCD_R / S : 26 * RB5 * LCD_E : 27 * RB6/PGC * , 28 * RB7/PGD * ;************************************************* *************************************** Port_A_Config equ 0xFF ; Port A bit equates Kn_Set equ 2 Kn_Plus equ 4 Kn_Minus equ 5 Port_B_Config equ b'11000000 ' Port_C_Config equ b'11000100 ' ; Port C bit equates Cap_Charge equ 0 Cap_Discharge equ 1 Comp_Up equ 2 In_N_Gnd equ 3 In_P_Cx equ 4 In_N_Cx equ 5 Comp_Low equ 6 ESR_ready equ b'00110011 '; incl. discharge, "+" and "-" control at the Cx ESR_start equ b'00110000 '; incl. charge, "+" and "-" control at the Cx Cap_ready equ b'00011011 '; incl. razdyad "-" control on the ground, "+" on Cx Cap_start equ b'00011000 '; incl. charge, "-" control on the ground, "+" on Cx Cap_start2 equ b'00110000 '; incl. charge, "-" control at Cx, "+" on Cx Max_Count equ .70; the maximum number (1 byte, not more than 256) when TMR0 overflows account ; Step account - 0.2 ms, 65536 * 0.2 = 13107.2 ms - one overflow , Or when I = 10mA 15 counts / uF 65536/15 = 4369 microfarads - one overflow ; Let Cx = max 150000mkF, 150000/4369 = 34 ; Given time charge to the lower boundary of the constant need to redouble ;************************************************* *************************************** list p = PIC16F873a # Include P16F873a.inc;; 20.000 MHz __CONFIG _CP_OFF & _BODEN_OFF & _HS_OSC & _WRT_OFF & _WDT_OFF & _PWRTE_ON & _DEBUG_OFF & _CPD_OFF & _LVP_OFF ; # Define _BAT PORTA, 1, 0 - low bat # Define _RS PORTB, 4 # Define _E PORTB, 5 CBLOCK 0x35; 0x20-0x34 for FLOATING POINT LIBRARY ; Data blocks W_TEMP; preserve the context of interrupted STATUS_TEMP PCLATH_TEMP Dly0; Stores 3 bytes of data for the delay count Dly1; Dly0 is the least significant byte Dly2; while Dly3 is the most significant byte ; Temp Temp1 Temp2 Temp3 Temp4 Count1 Count2 T0 ; Data blocks T2; High Byte T3 T4 T5; Byte AX; High Byte A0 A1 A2; Byte A3 A4 A5 BCD0; Byte BCD1 BCD2 BCD3 BCD4; High Byte U330_L; voltage output from the controller, gain = 330, low byte U330_H; voltage output from the controller, gain = 330 byte U33_L; voltage output from the controller, gain = 33, low byte U33_H; voltage output from the controller, gain = 33, byte TMR1_Count; TMR1 counter overflows TMR0_Count; TMR0 counter overflow Flags EE_ADR; helper cell to work with EEPROM EE_DATA NZ; number of significant digits for output to display NC; number of constants Const_ADR; address constants in the EEPROM ENDC CBLOCK 0xB5 W_TEMP1; preserve the context of interrupted ENDC ;========================= ; MACROS ;========================= bank0 macro bcf STATUS, RP0 endm bank1 macro bsf STATUS, RP0 endm Dly24 MACRO DLY ; Take the delay value argument from the macro, precalculate ; The required three RAM values and load the The RAM values Dly2, Dly1 ; And Dly0. banksel Dly0 movlw DLY & H'FF ' movwf Dly0 movlw DLY>> D'08 '& H'FF' movwf Dly1 movlw DLY>> D'16 '& H'FF' movwf Dly2 ; Bytes are shifted and anded by the assembler to make user ; Calculations easier. endm ;========================== ORG 0x2100; Area EEPROM ; Data; Address in EEPROM ; Correction coefficients for: USR_1 DE 0x00, 0x00, 0x03, 0xE8; 1 - limit 1 ohm USR_10 DE 0x00, 0x00, 0x03, 0xE8; 1 - limit of 10 ohms USR_Cx DE 0x00, 0x00, 0x03, 0xE8; 1 - measurement of capacity ; K_ESR_1 DE 0x7F, 0x00, 0x00, 0x00; 1 - limit 1 ohm ; K_ESR_10 DE 0x7F, 0x00, 0x00, 0x00; 1 - limit of 10 ohms ; K_Cx DE 0x7F, 0x00, 0x00, 0x00; 1 - measurement of capacity ; Numbers in FLOATING POINT LIBRARY format U0_ESR_1 DE 0x85, 0x16, 0x00, 0x00; 75 = 85160000 - "0" at the limit of 1 ohm U0_ESR_10 DE 0x81, 0x60, 0x00, 0x00; 7 = 81600000 - "0" at the limit of 10 ohms ; Factors for the calculations: M_ESR_1 DE 0x75, 0x40, 0x30, 0x0C; 1 / 682 = 7540300C M_ESR_10 DE 0x78, 0x74, 0x89, 0x8D; 1 / 67 = 7874898D M_Cx DE 0x74, 0x2E, 0xC3, 0x3E; 1 / (15 * 100) = 742EC33E sub_Cx DE 0x80, 0x40, 0x00, 0x00; 3 = 80400000 - is subtracted from the readings TMR1 ;========================== org 0x700; posdelnie 256 bytes 1-th page of program memory Table addwf PCL, F omega dt b'00000000 '; sign omega dt b'00001110 ' dt b'00010001 ' dt b'00010001 ' dt b'00010001 ' dt b'00001010 ' dt b'00011011 ' dt b'00000000 ' mu dt b'00000000 ' dt b'00000000 ' dt b'00010010 ' dt b'00010010 ' dt b'00010010 ' dt b'00011110 ' dt b'00010001 ' dt b'00010000 ' _Const Dt "Coeff. For", 0 _ESR Dt "ESR", 0 _Cx Dt "Cx", 0 _Time_out Dt "Cx ---", 0 _1_ohm Dt "1", 1,0 _10_ohm Dt "10", 1,0 _tst_1 dt "1", 1 ,"=", 0 _tst_10 dt "10", 1 ,"=", 0 _write_U0 dt "U0 ---> EEPROM", 0 _ready dt "It is ready!", 0 org 0x00 ;************************************************* ****************************** ; START PROGRAM ;************************************************* ****************************** nop; for MPLAB-ICD2 goto init ;------------------ Interrupt ------------------ org 0x004 movwf W_TEMP; save W swapf STATUS, W; swap STATUS, W clrf STATUS movwf STATUS_TEMP; save status movf PCLATH, W movwf PCLATH_TEMP; save PCLFTH decfsz TMR0_Count goto restore_context bsf Flags, 0; Time Out! goto stop_TMR1 restore_context bcf INTCON, T0IF; clear interrupt flag movf PCLATH_TEMP, W movwf PCLATH swapf STATUS_TEMP, W; fetch status, reswap nibbles movwf STATUS; restore status swapf W_TEMP, F; swap nibbles in preparation swapf W_TEMP, W; for the swap restoration of w retfie; return from interrupt ;----------------------------------------------- init banksel INTCON clrf Flags clrf INTCON clrf PCLATH clrf PORTA clrf PORTB movlw ESR_ready; incl. discharge, "+" and "-" control at the Cx movwf PORTC banksel TRISA movlw Port_A_Config movwf TRISA ; Initialize ADC movlw b'10000100 '; right aligned, Vdd, Vss, AN0, AN1, AN3 movwf ADCON1 movlw Port_B_Config movwf TRISB movlw Port_C_Config movwf TRISC ; Initialize the LCD in 4 bit mode InitLCD call Delay_5_ms call Delay_5_ms call Delay_5_ms; pause of 15 ms after power ON banksel PORTB movlw 3 movwf Count1 movwf PORTB SetLoop bsf _E; to initialize the LCD 3 times sending command 0x30 nop nop nop bcf _E call Delay_5_ms decfsz Count1, f goto SetLoop movlw 2; 4-x-bit movwf PORTB call Send movlw 28; 4-bit, 2 lines, 5x7 call CmdLCD movlw 0C; Enable Display call CmdLCD movlw 6 call CmdLCD call Load_ZG; Load symbols of mu and omega call ClrDSP; Clear screen ;------------------------------------------------- - btfsc PORTA, Kn_Set; goto Main ;------------ Installation mode constants ------------ goto c_1 Const_Loop btfss PORTA, Kn_Plus call IncB btfss PORTA, Kn_Minus call DecB btfsc PORTA, Kn_Set goto Const_Loop btfss Flags, 5; flag change constants goto c_3 call Save_Const; constant change, we must keep c_3 incf NC, F movf NC, W sublw 3, the number of constants btfss STATUS, Z goto $ +2 c_1 clrf NC bcf Flags, 5 Clear the flag change in the constants call ClrDSP; Clear screen movlw LOW _Const call Read_String movlw HIGH $ movwf PCLATH movf NC, W addwf PCL, F; table transition goto const_1_ohm; +0 goto const_10_ohm; +1 goto const_Cx; +2 c_2 call ShowX goto Const_Loop const_1_ohm movlw LOW USR_1 movwf Const_ADR call EEPROM_To_B movlw LOW _1_ohm call Read_String goto c_2 const_10_ohm movlw LOW USR_10 movwf Const_ADR call EEPROM_To_B movlw LOW _10_ohm call Read_String goto c_2 const_Cx movlw LOW USR_Cx movwf Const_ADR call EEPROM_To_B movlw LOW _Cx call Read_String goto c_2 ;------- Initialize ADC module ------ Main ; Banksel ADCON1 ; Movlw b'10000100 '; right aligned, Vdd, Vss, AN0, AN1, AN3 ; Movwf ADCON1 ESR_measure banksel PORTC movlw ESR_start; incl. charge, "+" and "-" control at the Cx movwf PORTC movlw 0x4; 3.6mks Delay (18 cycles) to finish pereh.protsessov - to pick up! call Delay_go bcf PORTC, In_P_Cx; disable SZAP from Cx nop;??? bsf PORTC, Cap_Charge; off. Izar. , Measures the voltage output from dif.usilitelya with Ku = 330 banksel ADCON0 movlw b'10000001 '; Fosc/32, channel 0, A / D incl. movwf ADCON0 call Delay_20_us bsf ADCON0, 2; start analog-digital conversion btfsc ADCON0, 2 goto $ -1; waiting for the end of conversion movf ADRESH, W movwf U330_H banksel ADRESL movf ADRESL, W banksel U330_L movwf U330_L , Measures the voltage output from dif.usilitelya with Ku = 33 banksel ADCON0 movlw b'10001001 '; Fosc/32, channel 1, A / D incl. movwf ADCON0 call Delay_20_us bsf ADCON0, 2; start analog-digital conversion btfsc ADCON0, 2 goto $ -1; waiting for the end of conversion movf ADRESH, W movwf U33_H banksel ADRESL movf ADRESL, W banksel U33_L movwf U33_L ;------------ If ESR> 10 ohms, capacitance measurement does not perform ------------ clrf Flags movlw 0x03 subwf U33_H, W; if evidence ADC> = 0x300 (768) btfss STATUS, Z goto Cx_0; transition to measure the capacitance bsf Flags, 0; platoon flag Time Out goto Cx_3 ;------------ Measurement capacitor ------------ Cx_0 movlw Cap_ready; incl. razdyad "-" control on the ground, "+" on Cx movwf PORTC call TMR0_init; Run TMR0 to prevent deadlocks in the measurement of capacitance call Delay_200_us btfss PORTC, Comp_Low; 1 - Cx is discharged goto $ -2; forward again, 200 microseconds call Delay_200_us; for reliability even delay call TMR1_init movlw 0x03 subwf U330_H, W; if evidence ADC> = 0x300 (768) btfss STATUS, Z; ie ESR> 1 Ohm, capacitance is measured with ESR compensation goto Cx_1 movlw Cap_start2; incl. charge, "-" control at Cx, "+" on Cx movwf PORTC movlw 0x4; 3.6mks Delay (18 cycles) for a charge with the "-" input control call Delay_go bcf PORTC, In_N_Cx; disable the "-" input control of Cx goto Cx_2 Cx_1 movlw Cap_start; incl. charge, "-" control on the ground, "+" on Cx movwf PORTC Cx_2 btfsc PORTC, Comp_Low; 0 - Cx been charged to the lower limit goto $ -1 bsf T1CON, TMR1ON; start the timer tst_charge btfss PORTC, Comp_Up; 0 - Cx charged to the upper boundary goto stop_TMR1 btfsc PIR1, TMR1IF; TMR1 full? call Inc_count goto tst_charge stop_TMR1 clrf T1CON; stop TMR1 clrf INTCON; prohibit termination btfsc PIR1, TMR1IF; check the last time on the timer overflow call Inc_count; was overrun Cx_3 movlw Cap_ready; incl. razdyad "-" control on the ground, "+" on Cx movwf PORTC ;------------------------------------------------- ------- ; Outputs results to display ; Call CursorHome call ClrDSP ; Timeout btfss Flags, 0 goto Disp_Cx movlw LOW _Time_out call Read_String goto Disp_ESR ;------------------------------------------------- ------- clrf FPFLAGS bsf FPFLAGS, RND; flag rounding in calculations Disp_Cx movlw LOW _Cx call Read_String clrf AEXP movf TMR1_Count, W movwf AARGB0 movf TMR1H, W movwf AARGB1 movf TMR1L, W movwf AARGB2 btfsc PORTA, Kn_Plus goto Calc_Cx call BCD; If the button is pressed, plus, the test output movlw BCD4; timer without treatment call Disp_Full goto Disp_ESR Calc_Cx call FLO2424; Integer to float conversion movlw low sub_Cx call EEPROM_To_B call FPS24; A = A-3 movlw low M_Cx call EEPROM_To_B call FPM24; A = A * M_Cx movlw low USR_Cx call X_To_B call INT2424; Output: 24 bit two's complement integer right ; Justified in AARGB0, AARGB1, AARGB2 clrf AEXP call BCD bsf Flags, 1; not display leading zeros movlw 3 movwf NZ; number of significant digits, the rest will be 0 bsf Flags, 3, to include verification means. discharges at the derivation movlw BCD3 call DispBCD movlw BCD3; readings increased by 10 times, call DispBCD; there are hundreds of thousands of uF movlw BCD2; tens of thousands of uF call DispBCD movlw BCD2; thousands of uF call DispBCD And if the front were only zeros, the separator does not derive btfsc Flags, 1 goto next_1 movlw ","; thousands separator call CharLCD next_1 movlw BCD1; hundreds of uF call DispBCD btfsc Flags, 1; to hundreds nebylo digits, bsf Flags, 2, will display tenths of a microfarad movlw BCD1; tens of uF call DispBCD bcf Flags, 1, check = 0 is not needed, we deduce everything movlw BCD0; unit uF call DispBCD btfss Flags, 2; need a decimal point output goto next_2; no bcf Flags, 2, yes call DispDot; decimal point movlw BCD0; tenth microfarad call DispBCD next_2 call DispSP movlw 2; code mu call CharLCD movlw "F" call CharLCD ;---------------------------- Disp_ESR btfss PORTA, Kn_Plus goto tst_ESR bcf Flags, 4, reset the flag for more than 10 ohms movlw 0x03 subwf U330_H, W; if evidence ADC> = 0x300 (768) btfsc STATUS, Z; verify the second channel (10 ohm) goto chk_10 ; Channel 1 Ohm call ClrA movf U330_H, W; amplifier gain = 330, limit 1 ohm movwf AARGB0 movf U330_L, W movwf AARGB1 call FLO1624; to 24 bit floating point movlw low U0_ESR_1 call EEPROM_To_B call FPS24; A = A-U0 - subtract the zero offset movlw low M_ESR_1 call EEPROM_To_B call FPM24; A = A * M_ESR_1 movlw low USR_1 call X_To_B goto ESR_to_LCD chk_10 movlw 0x03 subwf U33_H, W; if evidence ADC> = 0x300 (768) btfsc STATUS, Z bsf Flags, 4, more than 10 ohms ; Channel 10 Ohm call ClrA movf U33_H, W; amplifier gain = 33, limit 10 ohms movwf AARGB0 movf U33_L, W movwf AARGB1 call FLO1624; to 24 bit floating point movlw low U0_ESR_10 call EEPROM_To_B call FPS24; A = A-U0 - subtract the zero offset movlw low M_ESR_10 call EEPROM_To_B call FPM24; A = A * M_ESR_10 movlw low USR_10 call X_To_B ESR_to_LCD call SecLine movlw LOW _ESR call Read_String btfss Flags, 4,> 10 ohm? goto next_3 movlw ">" call CharLCD goto next_4 next_3 call DispSP next_4 movlw 0x80 andwf AARGB0, W; distinguish the symbol "-" btfsc STATUS, Z goto next_5; result> 0 call ClrA; result <0, we derive some zeros goto next_6 next_5 call INT2424 next_6 bcf Flags, 3; disable scanning means. discharges at the derivation bsf Flags, 1; not display leading zeros clrf AEXP call BCD movlw BCD2 call DispBCD movlw BCD2 call DispBCD; tens of ohms bcf Flags, 1, check = 0 is not needed, we deduce everything movlw BCD1; units of ohms call DispBCD call DispDot movlw BCD1 call DispBCD movlw BCD0 call DispBCD movlw BCD0 call DispBCD call DispSP movlw 1; sign th call CharLCD end_disp banksel PORTC bsf PORTC, Cap_Discharge; incl. discharge Cx call Delay_05_sec banksel PORTC bcf PORTC, Cap_Discharge; off. discharge Cx goto ESR_measure ; For testing - output of the ADC without treatment , Once 2-channel (1 and 10 ohms) tst_ESR call SecLine ; Channel 1 Ohm movlw LOW _tst_1 call Read_String call ClrA movf U330_H, W; amplifier gain = 330, limit 1 ohm movwf AARGB1 movf U330_L, W movwf AARGB2 call BCD movlw BCD1 call Disp_Full ; Channel 10 Ohm movlw LOW _tst_10 call Read_String call ClrA movf U33_H, W; amplifier gain = 33, limit 10 ohms movwf AARGB1 movf U33_L, W movwf AARGB2 call BCD movlw BCD1 call Disp_Full btfsc PORTA, Kn_Set; check button zeroing goto end_disp ; Saving U0 in EEPROM ------------------------ call CursorHome movlw LOW _write_U0 call Read_String ; U0 for l Ohm call ClrA movf U330_H, W; amplifier gain = 330, limit 1 ohm movwf AARGB0 movf U330_L, W movwf AARGB1 call FLO1624; to 24 bit floating point call BEQUA movlw LOW U0_ESR_1 movwf Const_ADR call Save_Const ; U0 for l0 ohms call ClrA movf U33_H, W; amplifier gain = 33, limit 10 ohms movwf AARGB0 movf U33_L, W movwf AARGB1 call FLO1624; to 24 bit floating point call BEQUA movlw LOW U0_ESR_10 movwf Const_ADR call Save_Const call Delay_3_sec call ClrDSP movlw LOW _ready call Read_String call Delay_1_sec goto end_disp ;------------------------- TMR1 ----------------------- - ; Initializing timer TMR1, step accounts = 0.2 ms TMR1_init clrf TMR1L clrf TMR1H bcf PIR1, TMR1IF movlw b'00000000 '; 1:1 Fosc / 4 movwf T1CON clrf TMR1_Count return ;------------------------- TMR1 ----------------------- - ; Zoom TMR1 counter overflows Inc_count bcf PIR1, TMR1IF; clear the timer overflow flag incfsz TMR1_Count, F return bsf Flags, 0; Time out goto stop_TMR1; in the allotted time measurements do not wait until the charge ;------------------------- TMR0 ----------------------- - ; Initializing timer TMR0, step accounts = 0.2 ms TMR0_init movlw Max_Count movwf TMR0_Count; initial value of counter TMR0 overflows clrf TMR0; clear timer movlw OPTION_REG; Work around the OPTION movwf FSR; address OPTION_REG -> FSR movlw b'00000111 '; set up timer. 1:256 presc movwf INDF bcf INTCON, T0IF; clear tmr0 int flag bsf INTCON, T0IE; enable TMR0 int bsf INTCON, GIE; enable global interrupts clrf TMR0; start timer return ;------------------------- Delay ----------------------- - ; Sub pauses Delay_3_sec; Pause 3 sec Dly24 D'937499 '; 3 / (4 / 20000000) / 16 = 937500-1 = 937499 goto DoDly24 Delay_2_sec; Pause 2 sec Dly24 D'624999 '; 2 / (4 / 20000000) / 16 = 625000-1 = 624999 goto DoDly24 Delay_1_sec; Pause 1 sec Dly24 D'312499 '; 1 / (4 / 20000000) / 16 = 312500-1 = 312499 goto DoDly24 Delay_05_sec; Pause 0.5 seconds Dly24 D'156249 '; 0.5 / (4 / 20000000) / 16 = 156250-1 = 156249 goto DoDly24 Delay_5_ms; pause 5 ms Dly24 D'1562 '; 0,005 / (4 / 20000000) / 16 = 1562.5 = 1562 goto DoDly24 Delay_200_us; Pause 200 microseconds Dly24 D'62 '; 0.0002 / (4 / 20000000) / 16 = 62.5 = 62 goto DoDly24 DoDly24; 16 Tcy per loop movlw H'FF '; Start with -1 in W addwf Dly0, F; LSB decrement btfsc STATUS, C; was the carry flag set? clrw; If so, 0 is put in W addwf Dly1, F; Else, we continue. btfsc STATUS, C clrw; 0 in W addwf Dly2, F btfsc STATUS, C clrw; 0 in W iorwf Dly0, W; Inclusive-OR all variables iorwf Dly1, W; together to see if we have reached iorwf Dly2, W; 0 on all of them. btfss STATUS, Z; Test if result of Inclusive-OR's is 0 goto DoDly24 return Delay_20_us movlw 0x1F; Delay 20 ms Delay_go movwf Dly0 decfsz Dly0, F goto $ -1 nop nop return ;---------------------- LCD --------------------- ; Translation pointer to the second character of the second row SecLine movlw 0xC0 ; Load command CmdLCD movwf Temp4 ; Bcf _RS swapf Temp4, W andlw 0x0F movwf PORTB bsf _E nop nop nop bcf _E movf Temp4, W andlw 0x0F movwf PORTB bsf _E nop nop nop bcf _E ; Clrf PORTB call Delay_200_us return ; Recoding to ASCII and output NumLCD andlw 0x0F; mask iorlw 0x30; ASCII ; Output ASCII character CharLCD movwf Temp4 SendLCD swapf Temp4, W andlw 0x0F iorlw b'00010000 '; RS = 1 movwf PORTB bsf _E nop nop nop bcf _E movf Temp4, W andlw 0x0F iorlw b'00010000 '; RS = 1 movwf PORTB Send bsf _E nop nop nop bcf _E clrf PORTB call Delay_200_us return CursorHome movlw 0x02; the initial display goto LongSend ClrDSP movlw 1; Clear Display LongSend call CmdLCD goto Delay_5_ms DispDot movlw "." goto CharLCD Disp0 movlw "0" goto CharLCD DispSP movlw "" goto CharLCD ;------------------------------------------------- ---------- ; Reading rows from the table and output to the LCD Read_String movwf Count1 decf Count1, F; correction of the initial bias movlw HIGH Table movwf PCLATH get_next_s movf Count1, W call Table andlw 0xFF; check for end of line btfsc STATUS, Z return call CharLCD incf Count1, F goto get_next_s ;---------------------- Load CGRAM LCD --------------------- ; Download decoder Load_ZG movlw b'01001000 '; AC in CGRAM = 8 call CmdLCD movlw HIGH Table movwf PCLATH movlw .16; 2 digits by 8 bytes movwf Count1 movlw LOW omega-1 movwf Count2; offset table get_s call Table; get a character from the table call CharLCD incf Count2, F movf Count2, W decfsz Count1, F goto get_s return ;------------------------------------------------- --------- ; Withdrawal from the passed in W block address BCD0 ... 4 , The indicator Disp_Full movwf FSR; cell address for output on LCD next_byte swapf INDF, W call NumLCD movf INDF, W call NumLCD , Check whether we got to BCD0 movlw BCD0 subwf FSR, W btfsc STATUS, Z return decf FSR, F goto next_byte ;---------------------- BCD to LCD --------------------- ; Output level and the preparation for the conclusion next DispBCD movwf FSR NextNibble swapf INDF, F movf INDF, W btfss Flags, 1, 1 - do not display leading zeros goto chk_NZ andlw 0x0F btfsc STATUS, Z return; pass output bcf Flags, 1; this and all figures derive posdeduyuschie chk_NZ btfss Flags, 3, 1 - show only NZ discharges, other - 0 goto NumLCD movf NZ, F btfsc STATUS, Z; counter = 0? goto Disp0; yes, we deduce that 0 decf NZ, F; not, then we deduce that there is call NumLCD return ;---------------------- BCD --------------------- ; Recoding values from binary to decimal BCD movlw 0x20 movwf T1 clrf BCD0 clrf BCD1 clrf BCD2 clrf BCD3 clrf BCD4 BcdLoop rlf AARGB2, F rlf AARGB1, F rlf AARGB0, F rlf AEXP, F rlf BCD0, F rlf BCD1, F rlf BCD2, F rlf BCD3, F rlf BCD4, F decfsz T1, F goto Adjust return Adjust movlw .5 movwf Count2 movlw BCD0 movwf FSR goto ADloop +1 ADloop incf FSR, F call Adjbcd decfsz Count2, F goto ADloop goto BcdLoop Adjbcd movlw 0x03 addwf INDF, W movwf T0 btfsc T0, 3 movwf INDF movlw 0x30 addwf INDF, W movwf T0 btfsc T0, 7 movwf INDF return ;------------------------------------------------- ------ ; Copy "on purpose" block (4 bytes) of data ; Temp1 = recipient's address - indicates the senior block address ; Temp2 = source address - indicates the senior block address ; CEQUA movlw CX; C = A Copy_From_A movwf Temp1; Xw = A movlw AEXP movwf Temp2 goto Copy BEQUA movlw AEXP; B = A Copy_To_B movwf Temp2; B = Xw movlw BEXP goto Copy_B ; AEQUF movlw FX; A = F Copy_To_A movwf Temp2; A = Xw movlw AEXP Copy_B movwf Temp1 Copy movlw 4; volume unit movwf Count1 Copy_Loop movf Temp2, W movwf FSR movf INDF, W movwf Temp3 movf Temp1, W movwf FSR movf Temp3, W movwf INDF decf Temp1, F; moving in the direction of decreasing decf Temp2, F; Address decfsz Count1, F goto Copy_Loop return ;------------------------------------------------- ------ X_To_B call EEPROM_To_B; Load factor X call ASwapB call FLO2424 call FPM24 return ASwapB movlw T5 call Copy_From_A movlw BEXP call Copy_To_A movlw T5 call Copy_To_B return ;------------------------------------------------- ------ ; Clear blocks A and B ClrB movlw BEXP; Cleaning Block B goto ClrA +1 ClrA movlw AEXP; Cleaning Block A movwf FSR movlw 4; volume unit movwf Count1 ClrLoop clrf INDF; cleaning cycle decf FSR, F; reduce the address decfsz Count1, F goto ClrLoop return ;------------------------------------------------- ------ : Reading data from the EEPROM in block B EEPROM_To_B movwf EE_ADR; stores the address of EEPROM cell movlw BEXP movwf FSR movlw 4; volume unit movwf Count1 EE_read_loop call ReadEEPROM banksel BEXP movwf INDF incf EE_ADR, F decf FSR, F decfsz Count1, F goto EE_read_loop return : Reading EEPROM ReadEEPROM movf EE_ADR, W; banksel EEADR; Bank 2 movwf EEADR; EEPROM cell address banksel EECON1; bank3 bcf EECON1, EEPGD; select EEPROM bsf EECON1, RD; initsializrovat reading banksel EEDATA; bank2 movf EEDATA, W; W = EEDATA return ;------------------------------------------------- ------ ; Recording unit BARG in EEPROM ; Address in the EEPROM is given in Const_ADR Save_Const movf Const_ADR, W movwf EE_ADR movlw BEXP movwf FSR movlw 4; volume unit movwf Count1 EE_write_loop movf INDF, W movwf EE_DATA call WriteEEPROM banksel BEXP incf EE_ADR, F decf FSR, F decfsz Count1, F goto EE_write_loop return ; Write EEPROM WriteEEPROM banksel EECON1; bank3 btfsc EECON1, WR goto $ -1 banksel EE_ADR movf EE_ADR, W banksel EEADR; bank2 movwf EEADR banksel EE_DATA movf EE_DATA, W banksel EEDATA; bank2 movwf EEDATA banksel EECON1; bank3 bcf EECON1, EEPGD bsf EECON1, WREN movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR nop bcf EECON1, WREN return ;------------------------------------------------- ------ ; Incrementing polubloka B IncB bsf Flags, 5, set the flag change in the constants incf BARGB2, F btfsc STATUS, Z incf BARGB1, F goto ShowX ; Decrementing polubloka B DecB bsf Flags, 5, set the flag change in the constants movf BARGB2, F btfsc STATUS, Z decf BARGB1, F decf BARGB2, F ShowX movlw BEXP call Copy_To_A call BCD call SecLine movlw BCD1 call DispBCD call DispDot movlw BCD1 call DispBCD movlw BCD0 call DispBCD movlw BCD0 call DispBCD call Delay_05_sec return ;======================================================= ; PIC16 24 BIT FLOATING POINT LIBRARY #define P16_MAP1 0 #define P16_MAP2 1 include "math16.inc" include "fp24.a16" END