Hallo ihr MC-Gurus!
Ich habe mich gerade frisch hier angemeldet, das ist also mein erstes
Posting.
Ganz kurz zu mir: Ich bin 24, Elektriker und Hobbyelektroniker.
Vor ca. 8 Jahren hab ich das erste mal mit MC's gebastelt, bis vor
kurzem noch mit dem AT89C2051. Jetzt "arbeite" ich seit ca. einem Monat
mit der atMega-Serie (mega32)
Programmiert habe ich bisher immer mit Assembler, da seh ich wenigstens
durch^^ Bascom geht eigendlich auch, aber das wollt ich net kaufen, und
die 4k waren sooo schnell voll^^
Bei C verstehe ich nur Banhof und komme garnicht mit klar.
Also, meine Testumgebung besteht aus dem Pollin Evaluation-board V2.0.1,
dem Pollin Addon-Board V1.0 und einer Lochrasterkarte wo alles
draufkommt was ich bei den anderen beiden Platinen vermisse.
Die beiden Polin-Karten habe ich schon leicht modifiziert, sodas ich
zumindest die ADC-Grundbeschaltung dran habe, der MAX232 funktioniert
und die Taster gegen Masse schalten.
Ich habe bereits das Tutorial "abgearbeitet".
Das LCD funktioniert wunderbar, nachdem ich mir die Tutorial-Routine auf
8-Bit umgeschrieben habe.
*Nun zu meinem Problem:*
Ich habe das Tutorial-Programm zum ADC-Wert ausgeben 8Das einfache, ohne
Umrechnung in Spannung) leicht geändet.(Taktfrequenz, MCU-Typ,
LCD-Routinen)
Am PC empfange ich die Werte einwandfrei, ich kann mittels Poti schön
die Spannung am Eingang einstellen und bekomme dementsprechend die
Messwerte via Uart geleiftert.
Nun wollte ich den Wert auf das LCD schreiben und habe zum Umrechnen der
16-Bit Zahl
1. einfach den ASCII-Code aus dem Register "Zeichen" nach "temp1"
kopiert und an das LCD als Daten gesendet und
2. die 16-Bit-Umwandlung aus dem Tutorial genommen.
Beides funktioniert auf den ersten Blick auch.
Am PC kommt immer das richtig an, jedoch beim LCD nicht.
Von 00000-ca.00273 geht alles so wie es soll. Wenn ich dann am Poti
weiterdrehe kommt jedoch nur noch auf dem PC der richtige Messwert an.
Auf dem LCD "zittern" die letzen 3 Stellen, gehen evtl sogar wieder
etwas zurück (also Wert auf 00247 zB.) und springen dann plötzlich auf
ca.11393
Am PC wird jedoch der richtige Wert angezeigt: 0000393
Wenn ich noch weiter drehe, zB. am PC auf 00411, steht auf dem LCD
11511.
Bei 00543 am PC zeigt mir das LCD 11553 an.
Bei 00605 auf dem PC zeigt das LCD 11715.
Also irgendwas kommt offensichtlich durcheinander, wenn es wirkleich ein
Wert wird, der nich mehr in 8bit gespeichert werden kann.
Das ADC-Test-Programm:
(Ja, ich weiss das z.B. XTAL und F_CPU das gleiche ist, aber ich bin ja
noch am probieren. Ich habe beim Label Transmit die auskommentierten
Zeilen gelassen. Damit wird einfach das über den UART gesendete Zeichen
am LCD ausgegeben, inclusive CR und LF^^ nach dem Label no_round ist die
aktuelle LCD-Ausgabe, welche die Umwandlung aus dem LCD-Tutorial
benutzt)
Und hier noch meine 8bit-LCD-Routinen:
(um die Macros locate und printflash erweitert, ausserdem testweise die
16bit-Addition auch bei 100er und 10er-Stellen hinzugefügt)
; Übergabe: Zahl im Register temp2 (low Byte) / temp3 (high Byte)
243
; veränderte Register: keine
244
;
245
lcd_number16:
246
push temp1
247
push temp2
248
push temp3
249
250
; ** Zehntausender **
251
ldi temp1, '0'-1
252
lcd_number1:
253
inc temp1
254
subi temp2, low(10000)
255
sbci temp3, high(10000)
256
brcc lcd_number1
257
subi temp2, low(-10000)
258
sbci temp3, high(-10000)
259
rcall lcd_data
260
261
; ** Tausender **
262
ldi temp1, '0'-1
263
lcd_number2:
264
inc temp1
265
subi temp2, low(1000)
266
sbci temp3, high(1000)
267
brcc lcd_number2
268
subi temp2, low(-1000)
269
sbci temp3, high(-1000)
270
rcall lcd_data
271
272
; ** Hunderter **
273
ldi temp1, '0'-1
274
lcd_number3:
275
inc temp1
276
subi temp2, low(100)
277
sbci temp3, high(100)
278
brcc lcd_number3
279
subi temp2, low(-100)
280
sbci temp3, high(-100)
281
rcall lcd_data
282
283
; ** Zehner **
284
ldi temp1, '0'-1
285
lcd_number4:
286
inc temp1
287
subi temp2, (10)
288
brcc lcd_number4
289
subi temp2, low(-10)
290
sbci temp3, high(-10)
291
rcall lcd_data
292
293
; ** Einer **
294
ldi temp1, '0'
295
add temp1, temp2
296
rcall lcd_data
297
298
; ** Stack aufräumen **
299
pop temp3
300
pop temp2
301
pop temp1
302
303
ret
Ich hoffe ihr könnt mir helfen und mir sagen wo der Fehler versteckt
ist.
Hab heut schon den halben Tag gesucht und komme nicht weiter.
Also, Danke schonmal im Vorraus für eure Hilfe!
Gruss Stefan
dampf mal Deine Main ein:
_________________________________________________________________________
Main:
clr temp1
clr temp2
clr temp3
clr temp4
ldi messungen, 0 ; 256 Schleifendurchläufe
; neuen ADC-Wert lesen (Schleife - 256 mal)
sample_adc:
sbi ADCSRA, ADSC ; den ADC starten
wait_adc:
sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses
Bit gelöscht
rjmp wait_adc
; ADC einlesen:
in adlow, ADCL ; immer zuerst LOW Byte lesen
in adhigh, ADCH ; danach das mittlerweile gesperrte High
Byte
; alle 256 ADC-Werte addieren
; dazu wird mit den Registern temp4, temp3 und temp2 ein
; 24-Bit breites Akkumulationsregister gebildet, in dem
; die 10 Bit Werte aus adhigh, adlow aufsummiert werden
add temp2, adlow ; addieren
adc temp3, adhigh ; addieren über Carry
adc temp4, temp1 ; addieren über Carry, temp1 enthält 0
dec messungen ; Schleifenzähler MINUS 1
brne sample_adc ; wenn noch keine 256 ADC Werte ->
nächsten Wert einlesen
; Aus den 256 Werten den Mittelwert berechnen
; Mathematisch eine Division durch 256
; Da aber 2^8 = 256 ist ist da einfach durch das weglassen des
niederwertigsten Bytes
; erreicht werden
;
; allerdings wird der Wert noch gerundet
cpi temp2,128 ; "Kommastelle" kleiner als 128 ?
brlo no_round ; ist kleiner ==> Sprung
; Aufrunden
subi temp3, low(-1) ; addieren von 1
sbci temp4, high(-1) ; addieren des Carry
no_round:
rcall lcd_number16
rjmp Main
____________________________________________________________________________
Was passier dann? Z8
Für die Übergabe habe ich doch bei der provisorischen LCD-Ansteuerung
folgende Zeilen:
;provisorishe LCD-Ansteuerung
push temp2
push temp3
mov temp2, adlow
mov temp3, adhigh
rcall lcd_number16
pop temp3
pop temp2
Wenn ich jetzt bei no_round adlow und adhig direkt durch die Register
ersetze, funktioniert die UART-Ausgabe ja nicht mehr. Dann müsste ich
die umschreiben (was eigendlich kein Problem ist).
Wenn ich mein Main einkürze, so wie du es vorschlägst hätte ich ja keine
Ausgabe der Daten mehr, oder seh ich das falsch?
Aber danke für die Antworten.
Was ich noch vergessen hatte: Ich programmiere mit dem AVR-Studio V4.16
und die Programme werden per Ponyprog2000 V2.06f Beta übertragen.
Gruss Stefan
So, hab jetzt ein wenig weiter experimentiert.
Ich habe die komplette UART-Ansteuerung mal rausgenommen (so wie Z8
vorgeschlagen hat, inclusive der Übergebe in den richtigen Registern^^)
Das Problem besteht weiterhin.
Dann habe ich mein 4x16 LCD angschlossen -> das gleiche.
So, jetzt hab ich in der ersten LCD-Zeile konstant "01" ausgegeben, 2
Leerzeichen, dann die über UART gesendeten ASCII-Zeichen.
In der 2. Zeile stehen die von LCD_number16 ausgegebenen Zeichen, in der
3. und 4. Zeile wird adlow und adhigh als binärzahl ausgegeben.
Über die serielle Schnittstelle funktioniert nach wie vor alles super,
jedoch beim LCD nicht.
Wenn ich z.B. den ADC-Wert 270 einstelle, "Zittern" einige Nullstellen,
also springen kurz auf 1, selbst die 0 vom 01 in der ersten Zeile!!!
Ausserdem habe ich bei den Variablen in Zeile 1 und 2 ein Zeichen zu
viel.
Kann es sein das ich ein Timingproblem beim LCD habe? Wenn ja, verstehe
ich nur nicht, warum dann z.B. ein konstanter Text richtig ausgegeben
wird.
Also, ist es möglich das solch komischen Werte durch ein falsches Timing
entstehen?
Gruss Stefan
EDIT: Hab gerade festgestellt, das alle Variablen, also auch die binären
nach kurzer Zeit eine Stelle mehr haben (die sich allerdings nie
verändert).
Ok, hab den Fehler gefunden, denk ich.
Das LCD lief noch über PortA mit DB0-DB7.
Der benutzte ADC-Eingang ist PA.0 ...
Wenn ich da jetzt ne analoge Spannung anlege, erkennt das LCD das
irgendwann als High (1) und dann gibts halt keine 0 mehr, sondern
nurmehr Einsen.
Hab jetzt die LCD-Routine angepasst, das die Datenleitungen an Port C
sind, aber irgendwie funktioniert da was nicht. initialisiert wird
irgendwie, aber Zeichen kommen keine raus... auch nicht mit meinem
Tstprogramm was bisher immer funktioniert hat.
Gruss Stefan
Danke für die Antwort, hat aber leider nix gebracht.
Egal ob Jtag an oder aus, es will nicht funktionieren.
Hab es jetzt an PortD angeschlossen, wo es allerdings auch niht auf
anhieb klappte. Erst nachdem ich das Programm nochmals assembliert und
neu geladen hatte (ohne auch nur ein Zeichen zu ändern) geht es jetzt.
Kann es sein, das das AVR-Studio ab und zu beim Assemblieren die
änderungen nicht mitassembliert?
EDIT:
So, weitergebastelt, also Uart auskommentiert, und siehe da: Der
Analogwert wird korrekt als Dezimalzahl und die Register adlow und
adhigh werden korrekt als Binärzahl dargestellt. Auch der "statische"
Text wird ohne Fehler angezeigt!
JUPPIIIIIIIII! Es geht!!!!
Jetzt muss ich nur noch rausfinden, warum es an PortC nicht geht^^
Gruss Stefan