@ all,
Ich suche eine Rutine (Atmega8) für eine Umwandlung von hex in 2x 8
bits Register in einer dezimalen Zahlen für eine LCD Ausgabe.
Das Programm "patricia_lcd.asm" soll eine Spannung von 0 bis 5V
auslesen und am LCD ausgeben, ich kriege nur kommische Werte, und das
Problem liegt bei der Umwandlung vor der Ausgabe.
Danke im Voraus für Ihre Hilfe.
Patricia
Hallo Patricia,
schau dir mal die Seite an:
http://www.avr-asm-tutorial.net/avr_de/rechnen/index.html
dort findest du Beispiele (in ASM), wie man mit dem AVR Rechnet. Ein
Beispiel für eine Umwandlung von einem ADC Wert für ein Display ist
auch dabei.
Gruß PatrickHH
Hallo.
Habe nicht alles im Detail durchgegangen, aber einen gravierenden
Fehler gefunden: Du setzt zwar das ADC-Interrupt-Enable-Bit und das
Global-Int-Enable-Bit, hast aber gar keine Interrupt-Service-Routine
dafür. Stattdessen liest Du direkt den ADC, nachdem Du ihm die
Conversion befohlen hast. Das kann nur schief gehen, weil er noch gar
nicht fertig ist.
Stattdessen wird irgendwann, sehr viel später, der ADC-Interrupt
zuschlagen und Dein ganzes Programm von vorne starten. D.h., nicht ganz
von vorne, sondern nur ab da, wo die Int-Service-Routine des ADC stehen
müsste.
mfg
gerd
Ich beziehe mich auf das hier:
http://www.mikrocontroller.net/attachment.php/183626/patricia_Lcd.asm
Noch'n grober Fehler:
Das Programm beginnt mit Textkonstanten. Die stehen also da, wo
eigentlich die Reset- und Interrupt-Vektoren stehen sollten. Da das
Programm bei Adresse 0 gestartet wird (Reset-Vektor), versucht der AVR,
den Text "Uss= ",0 als Befehle abzuarbeiten. Das muss schief gehen!
Also: Texte (und andere Konstanten im Flash) gehören an das Ende.
An die erste Adresse kommt nunmal der Reset-Vektor (rjmp reset), danach
die Sprungtabelle für die Interrupt-Service-Routinen, und erst danach
"normaler Programmcode".
Den Rest habe ich auch nicht weiter analysiert, sieht mir arg nach
Copy&Paste aus.
...
Ich nochmal...
Hier siehst du, wie man ein einfaches Programm aufbauen kann. Es geht
dabei um das Grundgerüst, also Konstanten, Register usw. definieren,
Anordnung von Vektortabelle für Reset und Interrupt, Reset-Routine
(Initialisierung), Aufbau einer ISR (Interrupt-Servive-Routine), Aufbau
einer Mainloop,die per ISR über Flags gesteuert wird, usw:
http://www.mikrocontroller.net/attachment.php/183626/patricia_Lcd.asm
Und hier siehst du eine Sammlung von Ausgaberoutinen für das LCD. Hier
kannst du z.B. sehen, wie man einen Zahlenwert (deinen ADC-Wert für
Spannung) als ASCII-Ziffern an das LCD senden kann. Eine Routine zum
Skalieren deines ADC-Wertes ist zwar nicht dabei, aber die Ausgabe von
8- 16- und 24-Bit-Zahlen an ein LCD:
http://www.mikrocontroller.net/attachment.php/164028/LCDprint.inc
Den kompletten Thread, in dem es allerdings um ein 4x27-LCD mit 2
Controllern geht, findest du hier:
http://www.mikrocontroller.net/forum/read-1-164017.html#164017
Das aufmerksame Lesen dieses Threads dürfte einige deiner
Programmier-Probleme lösen.
...
So, hab nochmal in meine Sammlung geschaut und dieses Testprogramm
gefunden. Es wird ein AD-Wert eingelesen und als Spannungswert am
Display ausgegeben. Habe das Programm vor einiger Zeit mal
zusammengestellt, um zu verstehen, wie so eine Umwandlung
funktioniert.
Gruß PatrickHH
@llo PatrickHH
Mein Problem ist, dass ich keine UART auf meine Boart habe.meinst du
deine Quelle-code kann auch mit der Parallele-schnittstelle funtioniert
Mein Programm gibt es gleich auf das LCD aus. UART hatte ich zum
probieren mal dran gehabt, ist aber jetzt nicht mehr implementiert.
Kannst alles was den UART betrifft noch auskommentieren.
Gruß
dazu müsste man sich aber mit dem programm beschäftigen. man (frau?)
sucht aber vermutlich eine fertige lösung um die hausaufgaben nicht
selbst machen zu müssen.
@llo
habe es geschaft aber möchte noch vor die spannung ausgabe am LCD an
der stelle 0x80 bis 0x85 "Uss= " schreiben aber wird von komische
dingue überschreiben. was ist da los?
mfg
@llo,
hier ist mein code.
will eigendlicht so was hier habe:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Uss= 0...5 V
; 0x80 0x85 0x86
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wo man am poti den spanungswert varieren kann
bei mir geht nu bis 3,754 plus schwarze balken statt 5.000 volt
print:
ldi temp1,0x80 ; Set DDRAM Adress to 0x40
rcall lcd_command
ldi ZL, LOW(text*2) ; Adresse des Strings in den
ldi ZH, HIGH(text*2) ; Z-Pointer laden
print2:
lpm ; Erstes Byte des Strings nach R0 lesen
tst R0 ; R0 auf 0 testen
breq print_end ; wenn 0, dann zu print_end
mov r16, r0 ; Inhalt von R0 nach R16 kopieren
rcall lcd_data ; LCD-Sendefunktion aufrufen
adiw ZH,ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen
rjmp print2 ; wieder zum Anfang springen
print_end:
: Ich habs nicht getestet!
Hier eine etwas optimiertere Version:
ldi temp1,0x80 ; Set DDRAM Adress to 0x40
rcall lcd_command
ldi ZL, LOW(text*2) ; Adresse des Strings in den
ldi ZH, HIGH(text*2) ; Z-Pointer laden
rcall print
..... ;Weiter im Programm
print:
lpm r16,z+ ; Erstes Byte des Strings nach R0 lesen
tst R16 ; R0 auf 0 testen
breq print_end ; wenn 0, dann zu print_end
rcall lcd_data ; LCD-Sendefunktion aufrufen
rjmp print ; wieder zum Anfang springen
print_end:
ret
MfG
Andi
@llo
habe noch versuch habe an der stelle von "Uss= " ist nur komische
sache zu sehen scheint es mehr mal zu schreiben obwohl der ADC wert
stimmt neben an.
hat jemand es versuch zu simulieren? Bitte Hilfe
du definierst:
.def temp1 = r25
Aber dann kommt:
print:
lpm r16,z+ ; Erstes Byte des Strings nach R0 lesen
tst R16
lcd_data erwartet das Zeichen in temp1=r25, aber es steht in r16.
Ändere also beide "r16" in "temp1", damit das Zeichen auch richtig
übergeben wird.