hallo,
Ik ben een voltmeter aan het maken, dus ik gebruik de ADC en wil een 10 bit resolutie, want 8 bit was niet nauwkeurig genoeg.
Nu heb ik een probleem, ik werk met de z-pointer en een tabel waar ik dan mijn waardes uithaal na de adc convertie en dan stuur mijn lcd schermpje deze waardes toe .
ik doe het volgende :
ldi ZH,HIGH(tabel_tientallen*2)
ldi ZL,LOW(tabel_tientallen*2)
in zl , adcl
in zh , adch
lsr zh
ror zl
lsr zh
ror zl
dus ik laad mijn resultaat in het z-pointer register en die gaat dan waardes uit mijn tabel halen,
MAAR dan krijg ik rare tekens op mijn lcd schempje hoe komt dit wat doe ik fout ?
alvast bedankt !
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
En ook nog eerst nog van binair naar bcd omzetten.
je leest:
- 10 bit binare waarde range 1023..0 of hex $1FF..$000
- Dat moet omzetten naar 4 byte bcd waardes:
0000 000d duizend- tallen
0000 hhhh honderd- tallen
0000 tttt tien- tallen
0000 eeee eenheden
- Daar moet je ascii van maken ( OR met $30 van je bcd getallen)
- Deze 4 bytes ascii waarden naar je display sturen.
Zoals free_electron al aangaf moet je eerst van Hex naar het decimale stelsel en dan naar ASCII.
Hoe ?.
stel je getal is: 0x1234 (hex) dat kan maximaal dus 65535 (dec) zijn.
Hoe zet je het om ?. je deelt het getal door 10 (dec) en de rest zet je om naar ascii tot je het complete getal hebt gemaakt.
In pseudo C code:
ASCII_0 = (Number % 10) + 0x30 // ( 0x1234 % 0xA ) + 0x30 = 0x30 = ASCII 0
Number = Number / 10 // ( 0x1234 / 0xA ) = 0x1D2
ASCII_1 = (Number % 10) + 0x30 // ( 0x01D2 % 0xA ) + 0x30 = 0x36 = ASCII 6
Number = Number / 10 // ( 0x01D2 / 0xA ) = 0x002E
ASCII_2 = (Number % 10) + 0x30 // ( 0x002E % 0xA ) + 0x30 = 0x36 = ASCII 6
Number = Number / 10 // ( 0x002E / 0xA ) = 0x0004
ASCII_3 = (Number % 10) + 0x30 // ( 0x0004 % 0xA ) + 0x30 = 0x34 = ASCII 4
Number = Number / 10 // ( 0x0004 / 0xA ) = 0x0000
ASCII_4 = (Number % 10) + 0x30 // ( 0x0000 % 0xA ) + 0x30 = 0x30 = ASCII 0
dus 0x1234 = 04660 (dec) => 4660 op je display.
; Bin16 to Packed BCD
;********************
; input: r17 16 bit high input
; r16 16 bit low input
; Reg: r21
; XH
; XL
; Output: r20 packed BCD value high nibble
; r19 packed BCD value
; r18 packed BCD value low nibble
Hex_Bcd:
clr r18
clr r19
clr r20
clr XH
ldi r21, 16
Hex_Bcd1:
ldi XL, 20 + 1
Hex_Bcd2:
ld r22,-X
subi r22,-3
sbrc r22,3
st X,r22
ld r22,X
subi r22,-0x30
sbrc r22,7
st X, r22
cpi XL,18
brne Hex_Bcd2
lsl r16
rol r17
rol r18
rol r19
rol r20
dec r21
brne Hex_Bcd1
ret
; ADC_UBAT binary to ascii BCD
; ****************************
LCD_Ubat:
lds r17,ADC_UBAT_HIGH ; Read High byte ADC
lds r16,ADC_UBAT_LOW ; Read low byte ADC
lsl r16
rol r17 ; multiplay by 2 range 20.47V .. 00.00V
rcall Hex_Bcd ; return r20:r19:r18 = BCD value
mov r16,r19
andi r16,0b11110000
lsr r16
lsr r16
lsr r16
lsr r16
ori r16,0b00110000
sts LCD_RAM+VB_OFFSET1,r16 ; Tiental display
mov r16,r19
andi r16,0b00001111
ori r16,0b00110000
sts LCD_RAM+VB_OFFSET2,r16 ; Eenheden display
mov r16,r18
andi r16,0b11110000
lsr r16
lsr r16
lsr r16
lsr r16
ori r16,0b00110000
sts LCD_RAM+VB_OFFSET3,r16 ; Tienden na dp display
mov r16,r18
andi r16,0b00001111
ori r16,0b00110000
sts LCD_RAM+VB_OFFSET4,r16 ; hondersten na dp display
ret
Hierbij een voorbeeldje hoe ik het gebruik. Merkop dat mijn range 20.47 tot 00.00 is. Daarom wordt de 10 bit ADC waarde eerst X2 gedaan. Dit om spanningen boven de 10V te kunnen weergeven. Ik gebruik altijd een stukje SRAM buffer waar ik alle display data in formateer. Het uitgeven zelf van die data naar de LCD display gebeurd in een afzonderlijke routine die op events werkt. Zo moet de toepassing slechts in de SRAM schrijven en zich niet moeien hoe die data naar het display zelf gaat.
LCD_RAM is hier het start adres van die sram
De OFFSET1, OFFSET2, OFFSET3 en OFFSET4 zijn de plaatsen waar die waarden in de buffer komen. Die OFFSET waarden staan in een header definitie waar ik de juiste plaatsen kan bepalen zonder opnieuw in deze routines te moeten duikelen.
Gatze
Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously
Voor m'n eerste projecten (bv toerenteller voor een brommer] haalde ik veel van deze website:
http://www.avr-asm-tutorial.net
Binary to ascii
http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2asc
[edit]binary to bcd
http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#bin2bcd
[Bericht gewijzigd door Gatze op (17%)]