PIC16f688 adc slaat stappen over

Beste allemaal,

Ik ben bezig om een met een pic een battery management system te maken. Ik weet dat deze kant en klaar te krijgen zijn. Maar ik wil onder andere de gegevens doorkoppelen naar een SQL database (en ik maak graag dingen zelf :P) dus een gekochte gaat niet werken hier.

Het probleem is dat ik hiervoor een 16f688 gebruik. De adc van de 18f4520 heb ik al tig keer gebruikt zonder problemen. Maar deze chip geeft bijzonder onnauwkeurige waardes. Ik gebruik drie kanalen en ze geven wel alle 3 het zelfde weer, maar de afwijking van de pic tot 2 verschillende multimeters varrieert tussen de 0,05% tot 7-8%. De eerste is volkomen acceptabel, de laatste absoluut niet. Na een hoop gezoek en het oplossen van een aantal problemen (vcc was 5,1v niet 5,0. de schaal loopt van 0-1023. Dus 5,1/1024 stapjes levert ook een afwijking op). Blijkt dat de adc soms hele stappen over slaat. Na het nodige expirimenteerwerk ben ik er achter dat de volgende waardes uit de adc komen:

1,3,7,12,14,15,19,23,24,28,30,31....

Ik lijn het resulaat rechts uit zodat ik het direct in een word kan stoppen.
De resolutie heb ik op 10 bits gezet
De sampletime op 50us (getest tot 1000, maakt geen verschil)

Ik heb geen 10-slagen potmeter liggen dus ik heb met een extra weerstand de maximale spanning op de wiper flink beperkt zodat ik wel in de resolutie van de adc kan sturen.

Het vreemde is dus dat hij hele stukken over slaat, terwijl ik op de multimeter "alle" waardes daar tussenin ook gewoon kan zien. De adc blijft dus op 7 hangen tot hij ineens op 12 over spring ipv 8,9,10 en 11 daar tussenin nog te gebruiken.

Ik gebruik de volledige versie van proton ide met de functie adin. Ik heb al gecheckt of de waardes op de ADRESH en ADRESL overeen komen en dat klopt. Het is dus echt de uitkomst van de adc.

Heeft iemand enig idee waar dit in zou kunnen zitten?

Iedereen alvast bedankt!

Vr. groet,

Daan

OPLOSSING!!!!!!!!!!
Het bleek uiteindelijk te liggen aan de combinatie van een 20MHz kristal en adcon1 zo ingesteld dat ADCS op Fosc/2 stond. OP pagina 67 van de datasheet staat tabel 8-1. Hierin is te zien dat dit te snel is voor deze pic. Kwestei van ADCS zo kiezen dat het binnen de specs valt zoals in die tabel valt en het probleem is (bij mij) opgeloste!

Nogmaals iedereen dank voor het meedenken!!!

Op 11 maart 2018 15:23:59 schreef DaanSteeman:
dus een gekochte gaat niet werken hier.

Dat werkt wel, maar is niet zo leuk. :)

Het vreemde is dus dat hij hele stukken over slaat, terwijl ik op de multimeter "alle" waardes daar tussenin ook gewoon kan zien.

Staat ADCON0 en ADCON1 dan wel goed ingesteld?

Als je haar maar goed zit, GROETEN LAMBIEK.

Haha oke zit wat in, kan misschien wel. Maar is inderdaad niet half zo leuk.
Zie adcon 0 en 1 hier onder

ADCON0 = %10000001
ADCON1 = %00000000

Wat neer komt op:
adcon0.7 = uitkomst is right justified
adcon0.6 = vref is vdd
adcon0.5 = unimplemented
adcon0.4-2 = kanaalselectie, word gedaan door ADIN
adcon0.1 = go/done. Bemoei ik me niet mee, word gedaan door ADIN
adcon0.0 = adc in enabled

adcon1.7 = unimplemented
adcon1.6-4 = ADCS staat op Fosc/2
adcon1.3-0 = unimplemented

Dit zijn de zelfde instellingen waarmee ik op de 18f4520 prima resultaten boek. Ik heb het net nog even geprobeerd. en daar loopt het netjes 0,1,2,3,3,4,5 enz.

Dank voor je snelle reactie!

ADCON1 moet volgens mij zo staan. ADCON1 = %00000001

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 11 maart 2018 17:05:06 schreef Lambiek:
ADCON1 moet volgens mij zo staan. ADCON1 = %00000001

Oeps, typo in de uitleg van de bits.

Van ADCON1 worden alleen bits 6-4 gebruikt. De rest is allemaal unimplemented. Dan maakt het toch niks uit waar die bits op staan? In de datasheet staat "Unimplemented: read as '0'"

PS: Toch even geprobeerd, heeft geen enkel effect...

Er zijn een paar mogelijke oorzaken:

1. TAD is te kort. Je krijgt dan random waardes.
2. Ingangsimpedantie is te hoog. Meer als 2.5kΩ geeft geen lineaire sampling meer...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 11 maart 2018 17:44:44 schreef Arco:
1. TAD is te kort. Je krijgt dan random waardes.

Ik neem aan dat dit het zelfde is als de sampletime. Deze stel ik in met:
Declare Adin_Stime 50
Ik heb dat getest tot 1000us en het heeft geen enkel effect. De waardes zijn ook niet echt willekeurig. Ze zitten wel in de goede richting, alleen zijn de stappen te groot, veel groter dan de eigenlijke resolutie van de adc.

Op 11 maart 2018 17:44:44 schreef Arco:
2. Ingangsimpedantie is te hoog. Meer als 2.5kΩ geeft geen lineaire sampling meer...

Dit heb ik inderdaad ook op meerdere fora gezien. In de datasheet staat dat het maximaal 10k mag zijn. Momenteel zit ik vrijwel precies op die 2,5k. Een 2k2 weerstand met een 250Ω potmeter. (De weerstand om nauwkeuriger in het lage bereik te kunnen sturen). Zowel met als zonder potmeter komen alleen de waardes die ik hierboven genoemd heb voor in de resultaten.

De resultaten lijken ook wel lineair te zijn. De afwijking over de hele ingangrange is redelijk gelijk. er zitten alleen forse uitschieters tussen vanwege die overgeslagen stappen...

gebruik je een aparte Vref voor de AD? (Vdd van de cpu zit nogal wat troep op, kan gauw iets van 50mV zijn)

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 11 maart 2018 18:20:36 schreef Arco:
gebruik je een aparte Vref voor de AD? (Vdd van de cpu zit nogal wat troep op, kan gauw iets van 50mV zijn)

Ah hm, nee ik gebruik momenteel gewoon Vdd. Hij is wel ontkoppeld met een 100nF direct bij de pic. Op de 18f4520 heb ik dat overigens ook altijd gedaan en dat ging prima.
Al zou ik bij dat soort problemen eerder verwachten dat de uitkomst onstabiel is. Dat hij constant wisselde van bijvoorbeeld 19 naar 18 of 20. Maar afhankelijk van waar ik de potmeter zet natuurlijk is de uiteindelijke uitkomst zeer stabiel. Waarschijnlijk onder andere omdat de stap van 19 naar 15 of 23 (wat de dichtstbijzijnde getallen die hij pakt zijn) relatief groot zijn.

Heb je ook gemeten of de spanning niet klopt met de AD waarde, of 'denk' je dat alleen... (zou 0.00488v per stap zijn)

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 11 maart 2018 18:38:45 schreef Arco:
Heb je ook gemeten of de spanning niet klopt met de AD waarde, of 'denk' je dat alleen... (zou 0.00488v per stap zijn)

Ik heb het echt na gemeten. Of in zoverre, met die extra weerstand kan ik met de potmeter fijn genoeg regelen dat ik per 2 of 3 milivolt de spanning kan verhogen of verlagen. En er zijn periodes dat de AD waarde niet veranderd terwijl die op de multimeter wel veranderd. Hieronder een overzicht. De spanning komt van mijn multimeter, met de bijbehorende AD waarde.
2.7mv > 0
9.2mv > 1 (wisselt nog tussen 0 en 1)
13.0mv > 1 (blijft constant 1)
18.9mv > 3 (wisselt nog tussen 1 en 3)
22.4mv > 3 (blijft constant 3)
33.9mv > 7 (wisselt tussen 3 en 7)
35.2mv > 7 (blijft constant 7)
55.4mv > 12 (wisselt nog tussen 7 en 12)
56.9mv > 12 (blijft constant 12)
59.9mV > 14 (wisselt nog tussen 12 en 14)

Ik heb het zelfde bij een van de grootste gaten tussen de AD waardes gedaan. Bij 384mV heb ik constant 78 als AD waarde, vanaf daar:
386mV > 79 (wisselt nog tussen 78 en 79)
388mV > 79 (blijft 79)
427mV > 88 (Wisselt nog tussen 79 en 88)
432mV > 88 (blijft 88)

Het gewissel tussen twee waardes zou ik inderdaad kunnen verklaren door troep op de Vdd. Dit los ik meestal op door 8 metingen te doen en dan de som daarvan 3 bits op te schuiven (dus door 8 delen). Maar binnen een zekere range is de waarde heel constant, bijvoorbeeld AD waarde 79 krijg bijft perfect stabiel tussen de 388mV en de 426mV. Terwijl daar nog 9 stappen tussen zouden moeten zitten.

Plaats eens een condensator tussen de ADC pin en GND.

Dit verlaagt de impedantie verder. Ik zat aan 100nF te denken. Liefst keramisch (lage ESR).

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Ik heb vrijwel altijd een elco van de ADC pin naar GND zitten. Afhankelijk van wat ik precies heb liggen. In een vorig projectje een elco + een weerstand voor een low pass filter. Nu zat er een 33uF elco. Ik heb die vervangen door een 100nF keramische condensator zoals je voorstelde. Helaas, geen effect...

Ik denk eerlijk gezegd ook niet dat het een hardwareprobleem is. Het is (afgezien van de pic zelf) allemaal hardware die ik al vaker gebruikt heb. En twee verschillende multimeters beweren alletwee dat de analoge spanning zich gedraagt zoals ik in mijn vorige post gezet heb.

Het meest waarschijnlijke vind ik toch dat het een instelling is. Maar ook als ik de uitkomsten binair weergeef is er niet echt een patroon te vinden in de waardes. (bijvoorbeeld dat de eerste twee bits niks doen ofzo).

Ik vind op een paar mV nauwkeurig heel netjes voor een ADC die uit vdd is gevoed. (ik krijg meestal veel grotere afwijkingen)
Zoals gezegd, 50mV aan troep op Vdd is niet echt bijzonder...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 11 maart 2018 20:58:30 schreef Arco:
Ik vind op een paar mV nauwkeurig heel netjes voor een ADC die uit vdd is gevoed. (ik krijg meestal veel grotere afwijkingen)
Zoals gezegd, 50mV aan troep op Vdd is niet echt bijzonder...

Maar ondanks die troep dan zou ik toch nog steeds wel die tussenliggende waardes moeten kunnen krijgen? Als van de ene op de andere meting 50mV verschil zit zou ik het daar inderdaad op gooien. Dan is het een kwestie van een paar metingen en daar het gemiddelde van pakken, of desnoods een aparte Vref er aan knopen. Maar ik heb afwijkingen tot 170mV. Dat is gewoon echt te veel, 50mV zou net acceptabel zijn...

De enige vreemde waarde zie ik bij 427mV. Da's een vrij grote sprong (of een schrijffout?)
En dan nog is 79...88 nog maar 53mV, ik zie nergens 170mV?...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 11 maart 2018 21:07:39 schreef Arco:
De enige vreemde waarde zie ik bij 427mV. Da's een vrij grote sprong (of een schrijffout?)
En dan nog is 79...88 nog maar 53mV, ik zie nergens 170mV?...

Het is helaas geen schrijffout. Omdat (om wat voor reden dan ook. De tussenliggende waardes niet gebruikt worden springt die meetwaarde heen en weer tussen 79 en 88. Als ik de potmeter anders in stel kan ik bijvoorbeeld het zelfde gedrag creëren tussen 14 en 15. Dat zou ik logisch vinden, zeker i.v.m troep op de Vdd. Maar die grote sprongen klopt geen bal van...

Die 170mV zit niet in dat lijstje. Ik heb eerder vandaag met grotere stappen gemeten en daar zat onder andere tussen een meetwaarde van de multimeter van 3.34V en (na omrekening in de pic) 3.5096V van de adc. Daar kwam die 170mV vandaan

EDIT: Ik heb toch even geprobeerd om de Vref een apparte spanning te geven. Vanaf de 12V rail van een computervoeding met een 7805je 4.90V gemaakt en de code aangepast (adcon0.6 op 1 gezet) zodat hij de refspanning daar vandaan haalt. Ik krijg nu wel meerdere meetwaardes er uit, ook een aantal die hij tot nu toe niet weergaf. Maar de meting is gigantish instabiel. Ik zet met de pot nu 101.7mV op de AD pin. Dat zou dus volgens mij:

4,90V levert 1023
1023/4,90=208,7755
0,1017*208,7755 = 21.2324

Met andere woorden, het resultaat van de ADC zou dus ongeveer 21 moeten zijn. Ik stuur het resultaat serieel door naar mijn pc, hier onder een lijstje met resultaten:
0,0,8,0,0,9,0,0,0,0,0,0,0,0,9,0,0,0,8,10,0,0,15,15,0,1,0,10,0,2,0,0,0

Dit zijn allemaal afzonderlijke metingen van die 0,1017V. Wat dus een uitkomst van ongeveer 21 zou moeten zijn...... Lijkt helemaal nergens op dus.

De Vref vlak ik af met 100nF keramische condensator en een 33uF elco. Over de adc ingang staat nog steeds die 100nF. Omdat dit haast random lijkt heb ik de sampletime verlengt tot 5000uS. En hier boven was het resultaat. (niet significant anders dan toen het 50uS was)...

[Bericht gewijzigd door DaanSteeman op 11 maart 2018 21:47:41 (41%)]

Ik weet niet precies hoe het bij die PICs is, maar met het instellen van een externe Vref+, krijg je dan ook tegelijk een externe Vref-? Maw, moet je nog een andere pin aan gnd leggen, wat je nu dus niet hebt?

Overigens, als je zulke meetwaardes terugkrijgt doe je echt iets fout, dan is het niet meer een eigenaardigheidje van de micro.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

Bepaal hoe snel je metingen kan doen, en kan doorsturen naar de PC.

Bepaal dan een RC waarmee je in 2x die tijd 5mV aan spanning verkrijgt. Dus als je er 1ms over doet om een meting door te geven, wil je 2.5mV/ms aan spanningstoename hebben. (= 2.5V/sec)

Dus bijvoorbeeld die 33uF: I = C dU/dt = 33uF * 2.5V/sec = 82µA. R = U/I = 5V/82µA = 60 kOhm.

Door nu de condensator te ontladen en via een 60-100kOhm weerstand te laten opladen richting de 5V kan je met de PC netjes een log maken van alle waardes die langskomen.

De ADC zal wel van het "successive-approximation" type zijn. Dat betekent dat als je het 512- en 256-bit gehad hebt en dus bijvoorbeeld weet dat de waarde tussen de 256 en de 512 in ligt. en je gaat het 128-bit proberen te bepalen, dan kan het zijn dat een meetfout: "Meer dan 384" optreed: het is in werkelijkheid minder dan 384. Vervolgens ga je "in de range 384-512, meer of minder dan 448?" Minder! "in de range 384-448, meer of minder dan 416?" Minder! enz.

Zo zal je dan opvallend veel metingen krijgen waarbij de laatste paar bits aan mekaar gelijk zijn. Aannemende dat de hardware wel OK zal zijn, en je signaal niet al te hard staat te veranderen, blijft over dat je vref/vcc dus enorm loopt te stuiteren..... Hoe voed je de boel? Maak eens een foto van je opstelling....

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Tenzij de 16F688 defect is zijn de waarden die je ziet niet normaal.

Op welke kloksnelheid draait de 16F688?

Op 12 maart 2018 10:42:43 schreef flipflop:
Ik weet niet precies hoe het bij die PICs is, maar met het instellen van een externe Vref+, krijg je dan ook tegelijk een externe Vref-? Maw, moet je nog een andere pin aan gnd leggen, wat je nu dus niet hebt?

Overigens, als je zulke meetwaardes terugkrijgt doe je echt iets fout, dan is het niet meer een eigenaardigheidje van de micro.

of een apparte Vref- bestaat hangt af van het model. Deze heeft geen Vref-. Het is bij deze per definitie vss.

Op 12 maart 2018 14:16:10 schreef Paulussie:
Tenzij de 16F688 defect is zijn de waarden die je ziet niet normaal.

Op welke kloksnelheid draait de 16F688?

Hij draait op een 20MHz kristal

@rew: Ik heb vandaag geen tijd gehad om hier mee verder te gaan. Maar begrijp ik het goed dat je eigenlijk een RC wilt maken die "langzaam" van 0v naar 5v gaat en zo dus alle anologe waardes produceert daar tussenin? Met een potmeter, al dan niet met voorschakelweerstand, behaal ik toch eigenlijk precies het zelfde? Afgezien van het feit dat ik met een potmeter gecontroleerder kan regelen en heen en weer kan schuiven tussen waardes?

Of het signaal te snel veranderd... het zit nu dus op een potmeter met voorschakelweerstand. de maximale spanning op de wiper is ongeveer 0,5V. Dus zeg in het beste geval 0,5V per seconde... Maar tijdens het testen draai ik natuurlijk heel langzaam om juist die tussenliggende waardes te pakken te krijgen. Op een redelijk constante snelheid denk ik zeker 10seconde over die halve volt. Misschien nog wel meer.

Ik voed de hele schakeling zoals ik dat altijd doe. Vanuit een labvoeding met diverse spannignen waarvan dit deel vanaf een computervoeding komt. Op het breadboard zit nog 1 dikke elco (2200uF) over de voeding en elke pic heeft een eigen 100nF keramische condensator Ik heb op het zelfde breadboard een 18f4520 zitten waarmee ik nog even getest heb met de adc. En daar zie je gewoon netjes 0,1,2,3,4,enz. voorbij komen. Dus het lijkt me bijzonder onwaarschijnlijk dat het daar aan ligt. Of zou de 16f688 gevoeliger zijn voor dit soort problemen?

Morgen heb ik waarschijnlijk wat meer tijd. Ik zal dan de 16f688 en de 18f4530 eens samen laten lopen vanaf de zelfde potmeter en de uitkomsten naast elkaar leggen. Ik zal dan ook even een foto regelen.

Iedereen in elk geval super bedankt voor het meedenken, als we een antwoord vinden zal ik dat ook nog even duidelijk beschrijven in dit topic voor een volgende die hier tegenaan loopt ;)

guidob

Overleden

Ik gebruik een 16F88 voor een GPS reference. O.a. om de regelspanning van de TCXO te meten. Gebruik daar 8 bits voor, voor mijn toepassing voldoende. Dat werkt verder prima. Is assembly, maar wellicht heb je er wat aan. Geen externe reference.

Full scale is 5V (simpele PLL regeling met XOR). Het hoeft niet echt nauwkeurig, als ik maar kan zien dat de PLL gelocked is. Maar twee cijfers achter de komma krijg ik stabiel.

De main loop kijkt of er een NMEA string gedecodeerd moet worden en voert dat uit. Vervolgens wordt gekeken of de ADC klaar is. Zo ja, wordt dat uitgelezen en op de LCD gezet. Dan weer wachten op een NMEA string.

De ISR (timer1, compare) wordt gebruikt om de 10MHz klok te delen naar 10kHz voor de PLL. Pic draait dus op 10MHz externe klok. Was een beetje proppen :)

De relevante assembly code voor het ACD deel. Er moet aardig gerekend worden om het netjes op het scherm te krijgen.

pic asm code:



        title   "GPSandDivider"
        list    P=PIC16F88
; CONFIGURATION WORDS
;                           CODE PROT COMP CCP1   IS-DEBUG     WRITE PROTECT      EE PROT    LV PROG    BROWN-OUT    MCLR VDD    PWR-UP TIME WATCHDOG   CLK
        __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON  & _PWRTE_ON & _WDT_OFF & _EXTCLK
;                           INTERNAL/EXTERNAL SWITCHOVER BIT   FAIL-SAVE CLOCK MONITOR ENABLE BIT
        __CONFIG _CONFIG2, _IESO_OFF &                        _FCMEN_OFF


;define analog_in, ISP  PORTB,7         ; Analog input and for incircuit programming


; <<<<< INITIALISATIE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; DEFINITIE I/O POORTEN

        clrf    PORTA
        clrf    PORTB
        bsf     STATUS,RP0              ; select bank 1
        clrf    ANSEL                   ; all pins digital
    	bcf		OPTION_REG,7     		; pull-up portb enabled

        movlw   b'11101100'             ; 76532 input, 410 output
        movwf   TRISB                   ; Port B;
        bcf     STATUS,RP0              ; select bank 0

; Define analog input RB7
	    bsf     STATUS,RP0              ; select bank 1
        bsf     ANSEL,6					; define RB7 as analog
		movlw	b'01000000'				; left justified, A/D clock source div2, reference AVdd and AVss
		movwf	ADCON1
        bcf     STATUS,RP0              ; select bank 0
		movlw	b'01110001'				; Fosc/16, channel 6 (RB7), A/D not in progress, A/D on
		movwf	ADCON0

; <<<<< MAIN PROGRAM >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

MainLoop
		btfss	ADCON0,2				; test ADC ready, skip if set; ADC not ready
		call	LcdVolt					; Write ADC value
		goto	MainLoop


LcdVolt
		movf	ADRESH,W				; load ADC value, 8 bits out of 10
		movwf	a8
		movlw	d'5'
		movwf	b8
		call	mpy8x8					; multiply ADC value with 5, result in r16

		movf	r16,W
		movwf	a16
		movf	r16+1,W
		movwf	a16+1					; a16=r16
		movlw	h'FF'
		movwf	b8						; b8=ff
		call	div16x8;   				; divide [ADC*5] by 255, result in q8 and r8; e.g. 4.35V; q8=4,r8=90  090/255=0.35

		movf	q8,W
		movwf	volt					; store voltage

		movf	r8,W					; remainder (e.g. 90)
		movwf	a16
		clrf	a16+1					; a16=r8
		movlw	h'FF'
		movwf	b8						; b8=ff
		call	div16x8;   				; divide remainder by 255, result in q8 and r8; e.g. 90; q8=0,r8=35  090/255=0.35

		movf	q8,W
		addwf	volt,W					; add to voltage (5V range), result in W
		movwf	count0
		call	ConvertToAscii			; volt in ascii

    	movlw   0x8B            		; Position on first line
    	call    LcdCmd

        movf    digit1,W
        call    LcdData                 ; write volt

		movlw	"."
		call	LcdData					; write dot

		movf	r8,W
		movwf	count0
        call    ConvertToAscii			; remainder in ascii

        movf    digit2,W
        call    LcdData	                ; write high value
        movf    digit1,W
        call    LcdData                 ; write low value

		movlw	"V"
		call	LcdData					; write V

		return

;....................................

ConvertToAscii

;Binary to decimal
;Convert 8 bit binary (count0) to decimal digits 1 to 2. Peter Hemsley 15 July 01

        clrf    digit1                  ; clear result memory
        clrf    digit2                  ; clear result memory

        movlw   d'8'                    ; 8 bits to do
		movwf	bitcnt

bitlp   rlf     count0,F                ; Shift msb into carry

		movlw	digit1
        movwf   FSR                     ; Pointer to digits
        movlw   d'2'                    ; 2 digits to do
		movwf	digcnt

adjlp   rlf     INDF,F                  ; Shift digit 1 bit left
        movlw   d'10'
        subwf   INDF,w                  ; Check and adjust for decimal overflow
        btfsc   STATUS,C                ; skip if Not Carry
        movwf   INDF

        incf    FSR,F                   ; Next digit
        decfsz  digcnt,F
		goto	adjlp
        decfsz  bitcnt,F                ; Next bit
		goto	bitlp

; result in digit1 and digit2
        movlw   h'30'
        addwf   digit1,F                ; convert to ascii
        addwf   digit2,F                ; convert to ascii

        return

;....................................


;/*======================================================================*/
; mpy8x8 					 // r16 = a8 * b8
;/*======================================================================*/

mpy8x8
		clrf  	r16       				; r16 = 0;
		clrf  	r16+1

		movlw 	d'8'    				; ix = 8;
		movwf 	ix

		movf  	b8,W      				; W = b8;
		movwf 	r16       				; r16.low8 = W;
		movf  	a8,W      				; W = a8;

m001
		bcf   	STATUS,C				; Carry = 0;
		btfsc 	r16,0     				; if (r16.0) r16.high8 += W;
		addwf 	r16+1,1
		rrf   	r16+1,1				  	; r16.high8 = rr (r16.high8);
		rrf   	r16,1     				; r16.low8  = rr (r16.low8);

		decfsz 	ix,1     				; while (--ix);
		goto  	m001

		return

;/*======================================================================*/
; div16x8 				     // q8,r8 =  a16 / b8
;/*======================================================================*/

div16x8
		movlw 	d'8'     				; ix = 8;	         // 8 bits divisor
		movwf 	ix

		movf  	a16+1,W   				; r8 = a16.high8;
		movwf 	r8
		movf  	a16,W     				; q8 = a16.low8;
		movwf 	q8
		movf  	b8,W      				; W = b8;			 // pre-fetch : BK

m054	bcf   	STATUS,C				; q8 *= 2;			 // shift dividend
		rlf   	q8,1
		rlf   	r8,1      				; r8 = rl(r8);
		rlf   	oldCy,1   				; oldCy = rl(oldCy); // save carry over
		subwf 	r8,1      				; r8 -= W;			 // fits ?

		btfsc 	oldCy,0  				; if (oldCy.0 || Carry)
		goto  	m055

		btfss 	STATUS,C
		goto  	m056

m055	bsf   	q8,0      				; q8.0 = 1;			// yes
		goto  	m057      				; else

m056	addwf 	r8,1      				; r8 += W;			// restore dividend

m057	decfsz	ix,1  					; while ( --ix);
		goto  	m054

		return

Op 11 maart 2018 17:00:56 schreef DaanSteeman:
Haha oke zit wat in, kan misschien wel. Maar is inderdaad niet half zo leuk.
Zie adcon 0 en 1 hier onder

ADCON0 = %10000001
ADCON1 = %00000000

Wat neer komt op:
adcon0.7 = uitkomst is right justified
adcon0.6 = vref is vdd
adcon0.5 = unimplemented
adcon0.4-2 = kanaalselectie, word gedaan door ADIN
adcon0.1 = go/done. Bemoei ik me niet mee, word gedaan door ADIN
adcon0.0 = adc in enabled

adcon1.7 = unimplemented
adcon1.6-4 = ADCS staat op Fosc/2
adcon1.3-0 = unimplemented

Dit zijn de zelfde instellingen waarmee ik op de 18f4520 prima resultaten boek. Ik heb het net nog even geprobeerd. en daar loopt het netjes 0,1,2,3,3,4,5 enz.

Dank voor je snelle reactie!

adcon1.6-4 = ADCS staat op Fosc/2 is fout, ad conversie staat nu veel te snel op 20MHz. Probeer /32 of /64

Als een rommelig bureau staat voor een rommelige geest waar staat dan een leeg bureau voor? - Albert Einstein.

Yesssss, electron24, Dat was het probleem!!!

Terwijl ik even controleerde waar ik adcon1 op moest zetten voor Fosc/32 kwam ik het tabel 8-1 tegen (pag 67). Waar uit bleek dat ik nu zeer ruim "outside of the recommended range" zat. Zodra ik dit veranderd had werkte het direct en zag ik gewoon 0,1,2,3,4,5 enz voorbij komen. De meting opzich is nu ook een heel stuk nauwkeuriger, en dat laatste beetje kan ik met wat kalibratie ook nog wel wat nauwkeuriger krijgen. Zo heb ik dat al eerder eens gedaan. Ik zit ongeveer op het tweede cijfer achter de komma dat hooguit 1 afwijkt van wat het werkelijk zou moeten zijn. Percentueel zit het rond de 1% dus. Maar dat zit nu ook in de nauwkeurigheid van mijn multimeter in de range. Dus dit is voor mij nauwkeurig genoeg ;).

Iedereen hartstikke bedankt voor het meedenken en ik zal de openingspost even aanpassen zodat daar de oplossing in staat.

Vr. Groet,

Daan Steeman