;
; 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
;************************************************* **************************************
;* 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 / µF 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=PIC16F883
#include P16F883.inc ; ; 20.000 MHz
__CONFIG _CONFIG1, _CP_OFF & _BOR_OFF & _HS_OSC & _WRT_OFF & _WDT_OFF & _PWRTE_ON & _CPD_OFF & _LVP_OFF
__CONFIG _CONFIG2, _WRT_OFF & _BOR40V
; # 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 the controller, gain = 330, low byte
U330_H; voltage output the controller, gain = 330 byte
U33_L; voltage output the controller, gain = 33, low byte
U33_H; voltage output 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 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 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 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 Cx
nop;???
bsf PORTC, Cap_Charge; off. Izar.
, Measures the voltage output 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 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 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 the table
call CharLCD
incf Count2, F
movf Count2, W
decfsz Count1, F
goto get_s
return
;------------------------------------------------- ---------
; Withdrawal 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 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 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; 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