Hi! Das angehängte Programm soll erstmal 0 auf nem Display ausgeben. Das macht es auch... Danach sollen mittels interrupts die impulse von einer drehencoderschaltung abgefangen werden. Die Drehencoderschaltung ist mit T Flipflops aufgebaut, und es gibt zwei ausgänge, einen für links und einen für rechts drehen. Also die entprellung ist kein Thema, hab ich auch schon durchgemessen. Sind sehr saubere Signale. Nun sollen wie gesagt die Signale abgefangen werden und in ein zählregister incrementiert bzw decrementiert werden. danach wird das zählregister durch 100, 10 und 1 geteilt und die jeweilige anzahl der stellen in einzelne register (hunderter, zehner, einer) gezählt werden. Danach werden diese drei register jeweils mit 30 dezimal addiert und somit zu ASCII zeichen gemacht und auf ein LCD ausgegeben werden. Jedoch zeigt das LCD durchgehend 0. Ich kann mir, zumindest bis jetz noch nicht erklären wo das problem liegt. vielleicht könnt ihr mir ja helfen. MfG Manuel
Also ich weiß jetzt nicht, wie Du die Ausgabeposition auf dem LCD fixierst. Auch verstehe ich nicht, warum Du in Main den Zähler mir dem ASCII-Wert von '0' lädtst. Zählen tut man binär, die Umwandlung in ASCII erfolgt erst bei der Ausgabe an das LCD. Hierzu schreibt man sich Ausgaberoutinen, das macht man nicht in der Mainloop. Hier ein Beispiel für eine Ausgaberoutine für ein Register: Zuerst das Macro, das die Routine aufruft: .macro print8 ;Registername ;Gibt Zahl im Register 2- oder 3-stellig am LCD aus. ;Parameter bestimmt das Register, in dem die Zahl liegt. ;Dieses Register wird nicht verändert. ;Kopie der Zahl temporär in xl, push xl ;verwendete Register sichern mov xl,@0 ;Kopie vom Quellregister rcall lcd_printb ;Aufruf von "Print Byte"... pop xl ;verwendete Register wiederherstellen .endmacro ; Das Macro ruft dann diese Routine auf: lcd_printb: ;Wird vom Makro aufgerufen. Gibt Byte als 2 ;oder 3 Ziffern an LCD aus. push wl ;Reg sichern ldi wl,-1+'0' ;Hunderter-Stelle als ASCII-Zeichen, ;Zahl ist positiv inc wl ;Hunderter hoch und subi xl,100 ;100 subtrahieren bis zum Unterlauf brsh pc-2 ;Unterlauf? nein, 2 Zeilen hoch ; cpi wl,'0' ;ja, ist Ziffer = "0"? ; breq pc+2 ;ja, nicht ausgeben... rcall lcd_data ;Hunderter ausgeben... ldi wl,10+'0' ;Zehner-Stelle als ASCII-Zeichen, ;Zahl ist jetzt unter 0 dec wl ;Zehner runter und subi xl,-10 ;10 addieren bis Überlauf brlo pc-2 ;Überlauf? nein, 2 Zeilen hoch... rcall lcd_data ;ja, Zehner Stelle ausgeben... ldi wl,'0' ;ASCII-0 add wl,xl ;Einer addieren (Rest war ja über 0) rcall lcd_data ;Einer ausgeben... pop wl ;Reg wiederherstellen ret ;zurück Die Unterdrückung der ersten Führungsnull ist in diesem Beispiel deaktiviert (auskommentiert). Die Zahl wird also dreistellig ausgegeben. Das Temp-Register zur Übergabe an LCD_Data heißt bei mir 'wl', Du musst den Code also an Deine Variablennamen in Deinem LCD-Treiber anpassen. Um die Ausgabeposition vor jeder Ausgabe neu einzustellen, solltest Du Dir mal im Datenblatt des LCDs das Kommando 'SET DD-RAM-Address' ansehen. Von LCD_Clear und LCD_Home rate ich ab, das dauert recht lange. Ausgabecursor positionieren und Leerzeichen ausgeben ist bedeutend schneller. Aus dem Hauptprogramm heraus kann nun mit print8 zaehler der Inhalt des Registers namens 'zaehler' am LCD ausgegeben werden. Eine Sammlung weiterer LCD-Ausgaberoutinen findest Du z.B. in der Datei LCDprinta.inc auf folgender Seite: http://www.hanneslux.de/avr/stopuhr/index.html Dort siehst Du auch, wie einfach die LCD-Ausgabe auch in Assembler sein kann. ...
Nicht schlecht! Jetz, als ich das ne stunde auf mich wirken lies, steig ich auch durch wie es viel eleganter zu machen ist! Da sieht man halt die unterschiede zwischen einem anscheinend erfahrenen programmierer und einem Anfänger ganz deutlich! Ist es vielleicht möglich das mein Programm trozdem wegen eines Interruptproblems nicht ging, denn es müsste ja zumindest die 30, die aufgrund meines bugs nach dem ersten schleifendurchgang geladen wird angezeigt werden. Es ist doch schon so, dass mit "sei" die Interrupts komplett aktiviert sind und ich die dann benutzen kann oder? Vielen dank, Manuel
Du musst zusätzlich zu SEI jeden benutzten Interrupt einzeln freischalten. Bei den Timern sind das die "timsk"-Register (alte AVRs haben nur eins, einige neue AVRs für jeden Timer ein separates), bei den externen Interrupts das GIMSK. Am besten im Datenblatt des benutzten AVRs nachschlagen, mache ich auch nicht anders. So "erfahren" bin ich übrigens auch nicht, ich gebe mir nur Mühe, den Code lesbar zu schreiben. Viel Erfolg... ...
Ok, funktioniert alles wie ich es will... Nur mal der vollständigkeit halber der fertige code angehängt Gruß Manu
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.