1. ## Some ASM Help Please

I am trying to use an all new PIC16F18426 for a personal project. I built a bench power supply, but the resolution on the LCD readout for Volts & Amps needed more resolution. The PIC16F18426 offers 12-bit ADC. However, since PBP3 cannot yet work with this new PIC, I'm trying my hand at ASM with MPLABX.

The challenge I'm facing in the software is converting the ADC values to decimal and isolating the digits to print to the LCD. The Basic code works like a charm on a PIC16F1824:

Code:
```Get_Ch1:                                    ;Get Channel 1 Values
DO
DO
IF (V1 = V1p) AND (A1 = A1p) THEN
RETURN
ENDIF
Volt1 = ((V1 + V1p) * 10) / 53
GOSUB Print_V1
V1p = V1
IF (A1 + A1p) > (V1 + V1p) THEN
Amp1 = (A1 + A1p) - (V1 + V1p)
ELSE
Amp1 = 0
ENDIF
GOSUB Print_A1
A1p = A1
RETURN

Print_A1:                                   ;Amp1 Changed, Send to LCD, Line 2
RS = 0
LCD = \$C0
GOSUB Send
RS = 1
pause 1
for b0 = 0 to 7
lookup b0, ["1-Amps: "], b1
LCD = b1
gosub Send
next b0
ARRAYWRITE Amp1a, [#Amp1]
IF Amp1 < 100 THEN
Amp1a[2] = Amp1a[1]
Amp1a[1] = Amp1a[0]
Amp1a[0] = " "
ENDIF
IF Amp1 < 10 THEN
Amp1a[2] = Amp1a[1]
Amp1a[1] = " "
Amp1a[0] = " "
ENDIF
FOR b0 = 0 TO 2
LCD = Amp1a[b0]
GOSUB Send
NEXT b0
FOR b0 = 0 TO 3
LOOKUP b0, [" mA "], b1
LCD = b1
GOSUB Send
NEXT b0
RETURN```

The Assembly Code generated for Print_A1 is as follows:

Code:
```Print_A1:                                       ;Amp1 Changed, Send to LCD, Line 2
LABEL?L    _Print_A1
MOVE?CT    000h, _RS            ;RS = 0
MOVE?CB    0C0h, _LCD            ;LCD = \$C0
GOSUB?L    _Send                ;GOSUB Send
MOVE?CT    001h, _RS            ;RS = 1
PAUSE?C    001h                ;pause 1
MOVE?CB    000h, _b0            ;for b0 = 0 to 7
LABEL?L    L00031
CMPGT?BCL    _b0, 007h, L00032
LOOKUP?BCLB    _b0, 008h, L00001, _b1    ;lookup b0, ["1-Amps: "], b1
LURET?C    031h
LURET?C    02Dh
LURET?C    041h
LURET?C    06Dh
LURET?C    070h
LURET?C    073h
LURET?C    03Ah
LURET?C    020h

LABEL?L    L00001
MOVE?BB    _b1, _LCD            ;LCD = b1
GOSUB?L    _Send                ;gosub Send
NEXT?BCL    _b0, 001h, L00031    ;next b0
LABEL?L    L00032
ARRAYWRITENAME?B    _Amp1a        ;ARRAYWRITE Amp1a, [#Amp1]
ARRAYWRITECOUNT?C    000h
ARRAYWRITENUM?W    _Amp1
ARRAYWRITEDEC?
CMPGE?WCL    _Amp1, 064h, L00033    ;IF Amp1 < 100 THEN
MOVE?BB    _Amp1a + 00001h, _Amp1a + 00002h ;Amp1a[2] = Amp1a[1]
MOVE?BB    _Amp1a, _Amp1a + 00001h        ;Amp1a[1] = Amp1a[0]
MOVE?CB    020h, _Amp1a            ;Amp1a[0] = " "
LABEL?L    L00033                ;ENDIF
CMPGE?WCL    _Amp1, 00Ah, L00035    ;IF Amp1 < 10 THEN
MOVE?BB    _Amp1a + 00001h, _Amp1a + 00002h Amp1a[2] = Amp1a[1]
MOVE?CB    020h, _Amp1a + 00001h        ;Amp1a[1] = " "
MOVE?CB    020h, _Amp1a            ;Amp1a[0] = " "
LABEL?L    L00035                ;ENDIF
MOVE?CB    000h, _b0            ;FOR b0 = 0 TO 2
LABEL?L    L00037
CMPGT?BCL    _b0, 002h, L00038
AOUT?BBB    _Amp1a, _b0, _LCD    ;LCD = Amp1a[b0]
GOSUB?L    _Send                ;GOSUB Send
NEXT?BCL    _b0, 001h, L00037    ;NEXT b0
LABEL?L    L00038                ;FOR b0 = 0 TO 3
MOVE?CB    000h, _b0
LABEL?L    L00039
CMPGT?BCL    _b0, 003h, L00040
LOOKUP?BCLB    _b0, 004h, L00002, _b1    ;LOOKUP b0, [" mA "], b1
LURET?C    020h
LURET?C    06Dh
LURET?C    041h
LURET?C    020h

LABEL?L    L00002
MOVE?BB    _b1, _LCD            ;LCD = b1
GOSUB?L    _Send                ;GOSUB Send
NEXT?BCL    _b0, 001h, L00039    ;NEXT b0
LABEL?L    L00040
RETURN?                    ;RETURN```

I tried copy/pasting the above code into MPLABX & pretty much all of it generated errors. I've tried numerous approaches but none have worked. Any ideas how to isolate decimal digits (1000s, 100s, 10s, 1s) from a larger value?

2. ## Re: Some ASM Help Please

Oh, the PIC16F18426 uses the mid-range instruction set, so there are no DAW or CMPFSEQ type commands.

3. ## Re: Some ASM Help Please

That isn't ASM instruction. It is ASM macro, from PBP library.
Alos arraywrite, etc... All instruction with ? are from PBP lib's.

4. ## Re: Some ASM Help Please

Something to go on.

5. ## Re: Some ASM Help Please

You must dig little dipper in PBP librarys. Look for PBPPICxx.mac and PBPPICxx.LIB files for macro definition.
If I was in your place, I would start from controlling PIN, then LCD basic communication, to display char, then to math involved in digit extraction...
EDIT:
PBP libs are great resource for learning ASM.... Lot of work and testing are organized and described in one place....
I learned ASM from PBP lib, and PIC datasheet. Now all interrupts my are written in ASM.
Last edited by pedja089; - 13th May 2018 at 18:43.

6. ## Re: Some ASM Help Please

Thanks, predja089. Spent the day fighting with it, but I have something that works. I tried typing it into PBP3 & looking at the ASM, but that didn't get me there. Now I'm able to take an ADC-12 read (0 >> 4095) and convert it into 4 decimal digits:

Code:
```	MOVF	ADRESH,W
MOVWF	b0
MOVF	b1
CALL	DoMath
MOVLW	0x30
MOVWF	Volts11
MOVLW	0x30
MOVWF	Volts12
MOVLW	0x30
MOVWF	Volts13
MOVLW	0x30
MOVWF	Volts14
CALL	Display
RETURN

DoMath:
BANKSEL Dig1
CLRF    Dig1
CLRF    Dig2
CLRF    Dig3
CLRF    Dig4
BCF	    STATUS, C
BCF	    STATUS, DC
Math2:			    ;Find the 1000,s Digit
MOVLW   0x03
SUBWF   b1, W
BTFSS   STATUS,C
BRA	    Math3
MOVLW   0xE8
SUBWF   b0, W
BTFSS   STATUS,C
BRA	    Math2a
MOVLW   0x03
SUBWF   b1, F
MOVLW   0xE8
SUBWF   b0, F
INCF    Dig1
BRA	    Math2
Math2a:
MOVLW   0x04
SUBWF   b1,W
BTFSS   STATUS,C
GOTO    Math3
MOVLW   0x04
SUBWF   b1,F
MOVLW   0x18
INCF    Dig1
BRA	    Math2
Math3:			    ;Find the 100,s Digit
MOVLW   0x64
SUBWF   b0, W
BTFSS   STATUS,C
BRA	    Math4
MOVLW   0x64
SUBWF   b0, F
INCF    Dig2
BRA	    Math3
Math4:			    ;Account for V1H Carry/Borrow
DECF    b1, W
BTFSS   STATUS,Z
GOTO    Math5
DECF    b1,F
MOVLW   0x9C
INCF    Dig2
BRA	    Math3
Math5:			    ;Find the 10,s Digit
MOVLW   0x0A
SUBWF   b0, W
BTFSS   STATUS,C
BRA	    Math6
MOVLW   0x0A
SUBWF   b0, F
INCF    Dig3
BRA	    Math5
Math6:
MOVF    b0,W
MOVWF   Dig4
RETURN```