;this file refers to http://www.mikrocontroller.net/forum/read-1-430713.html ;there are 3 versions, 1 and 2 have the constants within the linear code (without loop, optimised for speed) and uses 32 Bits, ;V.3 uses an external table in flash and uses a loop for the digits (optimised for space). ;The result is stored in R6..R15 (for debugging), but could be output (e.g. to a LCD) instead. ;Then R6 and R7 could be used for full 64-Bit resolution. ;As the result is absolute precise, it can be used for converting any n-bit-number, not only 10 Bits of the ADC. .def a0 =r8 .def a1 =r9 .def a2 =r10 .def a3 =r11 .def a4 =r12 .def a5 =r13 .def a0 =r16 .def a1 =r17 .def a2 =r18 .def a3 =r19 .def a4 =r20 .def a5 =r21 .def b0 =r22 .def b1 =r23 ;.def b2 =r24 ;.def b3 =r25 ;.def b4 =r26 ;.def b5 =r27 .def e0 =r24 .def e1 =r25 .def e2 =r26 .def e3 =r27 .def e4 =r28 .def e5 =r29 .def e6 =r30 .def e7 =r31 ldi b3,0x03 ldi b2,0xff ldi b1,0x20 mul b1,b2 ;alternatively do 5 Shift left operations movw a2,r0 mul b1,b3 add a3,r0 ;adc a3,r1 ldi a3,0x7f ldi a2,0xe0 ldi a1,0x00 ldi a0,0x00 jmp vers3 ;1 ldi e0,0x2f ;digit counter incdigit1: inc e0 subi a0,0x9a sbci a1,0x99 sbci a2,0x99 sbci a3,0x19 brcc incdigit1 subi a0,0x66 sbci a1,0x66 sbci a2,0x66 sbci a3,0xe6 ;2 ldi e1,0x2f ;digit counter incdigit2: inc e1 subi a0,0x29 sbci a1,0x5c sbci a2,0x8f sbci a3,0x02 brcc incdigit2 subi a0,0xd7 sbci a1,0xa3 sbci a2,0x70 sbci a3,0xfd ;3 ldi e2,0x2f ;digit counter incdigit3: inc e2 subi a0,0x37 sbci a1,0x89 sbci a2,0x41 sbci a3,0x00 brcc incdigit3 subi a0,0xc9 sbci a1,0x76 sbci a2,0xbe sbci a3,0xff ;4 ldi e3,0x2f ;digit counter incdigit4: inc e3 subi a0,0xb8 sbci a1,0x8d sbci a2,0x06 ;sbci a3,0x00 brcc incdigit4 subi a0,0x48 sbci a1,0x72 sbci a2,0xf9 ;sbci a3,0xff ;5 ldi e4,0x2f ;digit counter incdigit5: inc e4 subi a0,0xc5 sbci a1,0xa7 sbci a2,0x00 ;sbci a3,0x00 brcc incdigit5 subi a0,0x3b sbci a1,0x58 sbci a2,0xff ;sbci a3,0xff ;6 ldi e5,0x2f ;digit counter incdigit6: inc e5 subi a0,0xc6 sbci a1,0x10 ;sbci a2,0x00 ;sbci a3,0x00 brcc incdigit6 subi a0,0x3a sbci a1,0xef ;sbci a2,0xff ;sbci a3,0xff ;7 ldi e6,0x2f ;digit counter incdigit7: inc e6 subi a0,0xad sbci a1,0x01 ;sbci a2,0x00 ;sbci a3,0x00 brcc incdigit7 subi a0,0x53 sbci a1,0xfe ;sbci a2,0xff ;sbci a3,0xff ;8 ldi e7,0x2f ;digit counter incdigit8: inc e7 subi a0,0x2a sbci a1,0x00 ;sbci a2,0x00 ;sbci a3,0x00 brcc incdigit8 subi a0,0xd6 sbci a1,0xff ;sbci a2,0xff ;sbci a3,0xff ;9 forever: clc brcc forever vers2: ;32 Bits, Stellenzahl n=5 ldi r30,$00 ;z für lpm ldi r31,$02 v2loop: lpm ;get adc-value of the digit into r3..r0 mov r3,r0 inc r30 ;auf Boundaries achten! lpm mov r2,r0 inc r30 lpm mov r1,r0 inc r30 lpm inc r30 ldi e0,0x2f ;reset this digit (one inc is done anyway ->30 = '0') incdig0: inc r7 ;increment this digit sub a0,r0 ;subtract adc-value of one count of this digit sbc a1,r1 sbc a2,r2 sbc a3,r3 brcc incdig0 add a0,r0 ;if negative, revert latest subtraction adc a1,r1 adc a2,r2 adc a3,r3 cpi r30,0x1c ;check if all digits are done brne v2loop breq forever vers3: ;48 Bits, number of digits n=10 ldi a5,$7f ;ldi a4,$e0 ;07fe0 is ADC 03ff<5 ldi a5,$40 ;4000 is ADC 0200<5 ldi a4,$00 ;7f00 is ADC 03f8<5 ldi a3,$00 ldi a2,$00 ldi a1,$00 ldi a0,$00 ldi r26,$0a ;LoopCounter ldi r27,$00 ;Zero for ADC r31,27 ldi r28,$06 ;store result using st y+,e0 from R6..R15 ldi r29,$00 ldi r30,$00 ;z für lpm ;following values generate 3.296777343V for a ADC of 0x3ff ldi r31,$02 ldi r30,$c0 ;z für lpm ;following values generate 3.300000000V for a ADC of 0x3ff ldi r31,$02 ldi r30,$80 ;z für lpm ;following values generate 4.995117187V for a ADC of 0x3ff ldi r31,$03 ldi r30,$40 ;z für lpm ;following values generate 5.000000000V for a ADC of 0x3ff ldi r31,$04 ldi r30,$00 ;z für lpm ;following values generate 99,90234375% for a ADC of 0x3ff ldi r31,$05 ldi r30,$c0 ;z für lpm ;following values generate 100,0000000% for a ADC of 0x3ff ldi r31,$05 v3loop: lpm ;get adc-value of the digit into R5..R0 mov r5,r0 inc r30 ;auf Boundaries achten! ; adc r31,r27 ; doesn't work, as inc doesn't set the carry lpm mov r4,r0 inc r30 lpm mov r3,r0 inc r30 lpm mov r2,r0 inc r30 lpm mov r1,r0 inc r30 lpm inc r30 inc r30 ;for 48 Bits skip 16 Bits, so R6..R15 are free for storing the result inc r30 brne skipinc inc r31 skipinc: ldi e0,$2f ;reset this digit (one inc is done anyway ->30 = '0') v3incdig: inc e0 ;increment this digit sub a0,r0 ;subtract adc-value of one count of this digit sbc a1,r1 sbc a2,r2 sbc a3,r3 sbc a4,r4 sbc a5,r5 brcc v3incdig st y+,e0 add a0,r0 ;if negative, revert latest subtraction adc a1,r1 adc a2,r2 adc a3,r3 adc a4,r4 adc a5,r5 dec r26 ;check if all digits are done (64/8 *n)-1 brne v3loop v3forevr: clc brcc v3forevr .org 0x0100 ;entspricht Byte-Adresse 0200 ; + bedeutet: Wert wurde aufgerundet, - nicht aufgerundet ;following values generate 3.296777343V for a ADC of 0x3ff 1024<53=9223372036854775808 .db $26,$c9,$b2,$6c,$9b,$26,$c9,$b2 ;1- 1V (0x8000000000/3.3) 9223372036854775808/3,3+,5= .db $03,$E0,$F8,$3E,$0f,$83,$e0,$f8 ;2- 0,1V (0x8000000000/ 33) 9223372036854775808/33+,5= .db $00,$63,$4C,$06,$34,$c0,$63,$4c ;3- 0,01V (0x8000000000/330) 9223372036854775808/330+,5= .db $00,$09,$ee,$00,$9e,$e0,$09,$ee ;4- 0,001V 9223372036854775808/3300+,5= .db $00,$00,$FE,$33,$43,$16,$67,$65 ;5+ 0,0001V 9223372036854775808/33000+,5= .db $00,$00,$19,$6B,$86,$b5,$70,$bd ;6- 0,00001V 9223372036854775808/330000+,5= .db $00,$00,$02,$8a,$c0,$ab,$be,$79 ;7- 0,000001V 9223372036854775808/3300000+,5= .db $00,$00,$00,$41,$13,$44,$5f,$d9 ;8+ 0,0000001V 9223372036854775808/33000000+,5= .db $00,$00,$00,$06,$81,$ed,$3c,$c9 ;9+ 0,00000001V 9223372036854775808/330000000+,5= .db $00,$00,$00,$00,$a6,$97,$b9,$47;10- 0,000000001V 9223372036854775808/3300000000+,5= .db $00,$00,$00,$00,$10,$a8,$c5,$ba;11- ;not used yet 9223372036854775808/33000000000+,5= .db $00,$00,$00,$00,$01,$aa,$7a,$2c;12- ;not used yet 9223372036854775808/330000000000+,5= .org 0x0160 ;02c0 ;following values generate 3.300000000V for a ADC of 0x3ff 1023<<53=9214364837600034816 .db $26,$c0,$00,$00,$00,$00,$00,$00 ;1- 1V (0x7fe0000000/3.3) 9214364837600034816/3,3+,5= .db $03,$E0,$00,$00,$00,$00,$00,$00 ;2- 0,1V (0x7fe0000000/ 33) 9214364837600034816/33+,5= .db $00,$63,$33,$33,$33,$33,$33,$33 ;3- 0,01V (0x7fe0000000/330) 9214364837600034816/330+,5= .db $00,$09,$eb,$85,$1e,$b8,$51,$ec ;4+ 0,001V 9214364837600034816/3300+,5= .db $00,$00,$fd,$f3,$b6,$45,$a1,$cb ;5+ 0,0001V 9214364837600034816/33000+,5= .db $00,$00,$19,$65,$2b,$d3,$c3,$61 ;6- 0,00001V 9214364837600034816/330000+,5= .db $00,$00,$02,$8a,$1d,$fb,$93,$8a ;7+ 0,000001V 9214364837600034816/3300000+,5= 0,000001V 9214364837600034816/3300000+,5= .db $00,$00,$00,$41,$02,$ff,$8e,$c1 ;8+ 0,0000001V 9214364837600034816/33000000+,5= .db $00,$00,$00,$06,$80,$4c,$c1,$7a ;9+ 0,00000001V 9214364837600034816/330000000+,5= .db $00,$00,$00,$00,$a6,$6e,$13,$59;10+ 0,000000001V 9214364837600034816/3300000000+,5= .db $00,$00,$00,$00,$10,$a4,$9b,$89;11+ ;not used yet 9214364837600034816/33000000000+,5= .db $00,$00,$00,$00,$01,$aa,$0f,$8e;12+ ;not used yet 9214364837600034816/330000000000+,5= .org 0x01c0 ;0380 ;following values generate 4.995117187V for a ADC of 0x3ff 1024<53=9223372036854775808 .db $19,$99,$99,$99,$99,$99,$99,$9a ;1+ 1V (0x8000000000/5) 9223372036854775808/5+,5= .db $02,$8f,$5c,$28,$f5,$c2,$8f,$5c ;2- 0,1V (0x8000000000/50) 9223372036854775808/50+,5= .db $00,$41,$89,$37,$4b,$c6,$a7,$f0 ;3+ 0,01V (0x8000000000/500) 9223372036854775808/500+,5= .db $00,$06,$8d,$b8,$ba,$c7,$10,$cb ;4- 0,001V 9223372036854775808/5000+,5= .db $00,$00,$a7,$c5,$ac,$47,$1b,$48 ;5+ 0,0001V 9223372036854775808/50000+,5= .db $00,$00,$10,$c6,$f7,$a0,$b5,$ee ;6+ 0,00001V 9223372036854775808/500000+,5= .db $00,$00,$01,$ad,$7f,$29,$ab,$cb ;7+ 0,000001V 9223372036854775808/5000000+,5= .db $00,$00,$00,$2a,$f3,$1d,$c4,$61 ;8- 0,0000001V 9223372036854775808/50000000+,5= .db $00,$00,$00,$04,$4b,$82,$fa,$0a ;9+ 0,00000001V 9223372036854775808/500000000+,5= .db $00,$00,$00,$00,$6d,$f3,$7f,$67;10- 0,000000001V 9223372036854775808/5000000000+,5= .db $00,$00,$00,$00,$0a,$fe,$bf,$f1;11+ ;not used yet 9223372036854775808/50000000000+,5= .db $00,$00,$00,$00,$01,$19,$79,$98;12+ ;not used yet 9223372036854775808/500000000000+,5= .org 0x0220 ;0440 ;following values generate 5.000000000V for a ADC of 0x3ff 1023<53=9214364837600034816 .db $19,$93,$33,$33,$33,$33,$33,$33 ;1- 1V (0x7fe0000000/5) 9214364837600034816/5+,5= .db $02,$8e,$b8,$51,$eb,$85,$1e,$b8 ;2- 0,1V (0x7fe0000000/50) 9214364837600034816/50+,5= .db $00,$41,$78,$d4,$fd,$f3,$b6,$46 ;3+ 0,01V (0x7fe0000000/500) 9214364837600034816/500+,5= .db $00,$06,$8c,$15,$4c,$98,$5f,$07 ;4+ 0,001V 9214364837600034816/5000+,5= .db $00,$00,$a7,$9b,$ba,$dc,$09,$81 ;5+ 0,0001V 9214364837600034816/50000+,5= .db $00,$00,$10,$c2,$c5,$e2,$cd,$c0 ;6- 0,00001V 9214364837600034816/500000+,5= .db $00,$00,$01,$ad,$13,$c9,$e1,$60 ;7- 0,000001V 9214364837600034816/5000000+,5= .db $00,$00,$00,$2a,$e8,$60,$fc,$f0 ;8- 0,0000001V 9214364837600034816/50000000+,5= .db $00,$00,$00,$04,$4a,$70,$19,$4b ;9- 0,00000001V 9214364837600034816/500000000+,5= .db $00,$00,$00,$00,$6d,$d8,$02,$88;10+ 0,000000001V 9214364837600034816/5000000000+,5= .db $00,$00,$00,$00,$0a,$fc,$00,$41;11+ ;not used yet 9214364837600034816/50000000000+,5= .db $00,$00,$00,$00,$01,$19,$33,$3a;12+ ;not used yet 9214364837600034816/500000000000+,5= .org 0x0280 ;0500 ;following values generate 99,90234375% for a ADC of 0x3ff 1024<53=9214364837600034816 .db $0c,$cc,$cc,$cc,$cc,$cc,$cc,$cd ;1+ 10% (0x8000000000/10) 9223372036854775808/10+,5= .db $01,$47,$ae,$14,$7a,$e1,$47,$ae ;2- 1% (0x8000000000/100) 9223372036854775808/100+,5= .db $00,$20,$c4,$9b,$a5,$e3,$53,$f8 ;3+ 0,1% (0x8000000000/1000) 9223372036854775808/1000+,5= .db $00,$03,$46,$dc,$5d,$63,$88,$66 ;4+ 0,01% 9223372036854775808/10000+,5= .db $00,$00,$53,$e2,$d6,$23,$8d,$a4 ;5+ 0,001% 9223372036854775808/100000+,5= .db $00,$00,$08,$63,$7b,$d0,$5a,$f7 ;6+ 0,0001% 9223372036854775808/1000000+,5= .db $00,$00,$01,$d6,$bf,$94,$d5,$e5 ;7- 0,00001% 9223372036854775808/10000000+,5= .db $00,$00,$00,$15,$79,$8e,$e2,$31 ;8+ 0,000001% 9223372036854775808/100000000+,5= .db $00,$00,$00,$02,$25,$c1,$7d,$05 ;9+ 0,0000001% 9223372036854775808/1000000000+,5= .db $00,$00,$00,$00,$36,$f9,$bf,$b4;10+ 0,00000001% 9223372036854775808/10000000000+,5= .db $00,$00,$00,$00,$05,$7f,$5f,$f8;11- not used yet 9223372036854775808/100000000000+,5= .db $00,$00,$00,$00,$00,$8c,$bc,$cc;12- not used yet 9223372036854775808/1000000000000+,5= .org 0x02e0 ;05c0 ;following values generate 100.0000000%for a ADC of 0x3ff 1023<53=9214364837600034816 .db $7f,$e0,$00,$00,$00,$00,$00,$00 ;1- 100% 1023<53/1 9214364837600034816/1+,5= .db $0c,$c9,$99,$99,$99,$99,$99,$9a ;2+ 10% 1023<53/10 9214364837600034816/10+,5= .db $01,$47,$5c,$28,$f5,$c2,$8f,$5c ;3- 1% 1023<53/100 9214364837600034816/100+,5= .db $00,$20,$bc,$6a,$7e,$f9,$db,$23 ;4+ 0,1% 9214364837600034816/1000+,5= .db $00,$03,$46,$0a,$a6,$4c,$2f,$83 ;5- 0,01% 9214364837600034816/10000+,5= .db $00,$00,$53,$cd,$dd,$6e,$04,$c0 ;6- 0,001% 9214364837600034816/100000+,5= .db $00,$00,$08,$61,$62,$f1,$66,$e0 ;7- 0,0001% 9214364837600034816/1000000+,5= .db $00,$00,$00,$d6,$89,$e4,$f0,$b0 ;8- 0,00001% 9214364837600034816/10000000+,5= .db $00,$00,$00,$15,$74,$30,$7e,$78 ;9- 0,000001% 9214364837600034816/100000000+,5= .db $00,$00,$00,$02,$25,$38,$0c,$a6;10+ 0,0000001% 9214364837600034816/1000000000+,5= .db $00,$00,$00,$00,$36,$ec,$01,$44;11+ not used yet9214364837600034816/10000000000+,5= .db $00,$00,$00,$00,$05,$7e,$00,$20;12- not used yet 9214364837600034816/100000000000+,5= ;1024<53/5+,5= ;noch prüfen, ob auch negative Zahlen funktionieren ;(zuerst addieren, dann subtrahieren) ;oder negative Konstanten ;oder Konstanten negieren ;oder alle Bits invertieren und 1 abziehen ;Todo: Suppress leading zeros