hallo, guten nabend habe im anhang ist ein Demoprogramm für 8-fach-PWM mit Tastensteuerung Up-Down was ich hir mal vor einger zeit entdeckt hatte glaub das war von hannes, wie kann ich denn in diesem demo eine menüsteuerung einbinden mit 3-5tasten. bin absoluter anfänger in dieser sache, vielleicht könnte mir jemand ein bischen helfen danke kay
Gast
#506755
Hallo Kay, was verstehst Du unter "Menü-Steuerung" ? Softkeys unter einem LC-Display ? Gruss Otto
hallo, hatte nicht den richtigen anhang, als display hab ich ein 4x40 zb. taste1 kanal wählen taste2 enter taste1 stellrichtung wählen hoch oder runter dimmen taste2 enter taste3 zürück so eventuell sollte das menü sein ich wüsste jetz nicht so richtig wo ich richtig ansätzen muss
Gast
#506806
Hallo Kay, dann mußt Du eine Routine schreiben, die Deine gewünschte Ausgabe auf dem LCD erzeugt - siehe "Print" und die Tastenauswertung modifizieren: ;in "tas" steht jetzt der gültige Tastenzustand, ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten... Gruss Otto
Gast
#506810
als erstes könntest Du die bisherige Sollwertausgabe in die 2. Zeile "locaten" und in die erste einen Text ausgeben, dann merkst Du schon, wie es geht. Otto
hallo otto aber wie fange ich richtig an um zb den tastenzustand zu erkennen und dann auch richtig auf dem display auszugeben vielleicht ist es denn möglich ein kleines beispiel danke
hallo otto habe mal nochmal mein code angehängt wie weit ich bisher gekommen bin kay
Gast
#506834
Hallo Kay,
hier ein kleines Beispiel -
bei Tastendruck ändert sich der Pegel auf "0"
und das Unterprogramme wird aufgerufen.
Im anderen Fall wird der Befehl "übersprungen"
(skip if bit is set)
;menu function
sbis PINA,0x00 ;if port , pin 0 == 0
rcall MEN_98 ;
sbis PINA,0x01 ;if port , pin 1 == 0
rcall MEN_97 ;
sbis PINA,0x02 ;if port , pin 2 == 0
rcall MEN_96 ;
sbis PINA,0x03 ;if port , pin 3 == 0
rcall MEN_95 ;
sbis PINA,0x04 ;if port , pin 4 == 0
rcall MEN_start ;up to start
sbis PINA,0x05 ;if port , pin 5 == 0
rcall MEN_23 ;
sbis PINA,0x06 ;if port , pin 6 == 0
rcall MEN_22 ;
sbis PINA,0x07 ;if port , pin 7 == 0
rcall MEN_21 ;
Gruss Otto
Gast
#506836
Hallo Kay, ja, ich sehe schon: Du kommst damit klar... Gruss Otto
hallo hab das jetz einmal etwas umgesetzt, 1.aber wie kann ich denn zwischen den menüs hin und her wechseln 2.wo muss ich jetzt den aufruf zum dimmen hin schreiben danke kay
Gast
#506869
Hallo Kay, 1. in jedem Menü auch eine andere Tastenauswahl aufrufen 2. In die Tastenabfrage, die zu Deinem Menü passt Hier rufst Du das passende Unterprogramm auf... Gruss Otto
hallo otto, werd mir das jetz noch zugemüte führen werd mich morgen nochmal melden danke erstmal kay
Gast
#506878
Hallo Kay, bin morgen erst spät online - aber es gibt ja noch genug andere... Gruss Otto
Hi Kay... Erstens: Schau Dir bitte mal die von Dir verwendete Routinensammlung mit Printroutinen etwas genauer an (Texteditor reicht). Da sind 'ne Menge Kommentare drin, die das Ziel haben, den Benutzer über die Möglichkeiten der Routinen zu informieren. Da gibt es z.B. das Macro "printf" (Print Text aus Flash), mit dem Du in einem Atemzug ganze Texte am LCD ausgeben kannst. Das erspart Dir das separate Ausgeben jedes einzelnen Buchstabenns. Zweitens: Einige Beispiele, wie man Menütexte auf das Display bekommt, Werte ändert und auf die Menütasten reagiert, findest Du hier: http://www.hanneslux.de/avr/stopuhr/index.html http://www.hanneslux.de/avr/zuenduhr/index.html Beide nutzen zwar ein LCD mit 8 Zeilen je 24 Zeichen, aber das geht auch mit LCD 2x16. Vergiss den Befehl "Locate" nicht, der vom 4x27-LCD müsste auch mit einem 4x40 LCD zurechtkommen. In Deinem Fall (8 x PWM) würde sich anbieten, mit einer Taste "Menü" den Menüpunkt hochzuzählen (Wert 0..7), zwei Tasten als "Plus" und "Minus" zum Erhöhen und Vermindern der Werte zu nutzen und mit einer "Save"-Taste den neuen Wert ins EEPROM zu schreiben, damit beim Neustart die letzten Einstellungen erhalten bleiben (z.B. für Lüftersteuerung). Brauchst Du keine Sicherung im EEPROM, dann kannst Du mit 2 Tasten den Menüpunkt wählen (up/down) und mit zwei weiteren Tasten den Wert verändern. In beiden Varianten kannst Du die Variable "mp" (Menüpunkt) als Index auf die zu verändernde Variable (hier aus Geschwindigkeitsgründen r0..r7, ansonsten Adressen im SRAM) oder als EEP-Adresse benutzen. Zum Anzeigen des entsprechenden Menütextes ist die Routine "printt" sehr hilfreich, die erlaubt das Ausgeben indizierter Texte wie Menüpunkte oder Wochentage, Monatsnamen usw. Einfach mal ein bissel mit den Printroutinen spielen. Bei Deinem 4x40-LCD und 8 PWM-Werten kannst Du auch mit einer festen Zuordnung von Ausgabeposition und Kanal alle 8 Werte gleichzeitig anzeigen. Der Wert, der gerade verändert werden kann, kann dann blinkend dargestellt werden, indem man ihn jede volle Sekunde neu schreibt und jede halbe Sekunde mit Leerzeichen überschreibt (Software-Blinken). Es gibt da viele Möglichgeiten... ...
HALLO HANNES, das hab ich gestern probiert aber hat bei mir nich richtig hingehauen aber ich weiss da aber nicht richtig wo ich da ansetzen muss damit es auch funktioniert, vielleicht gibst da einen kleinen lösungsansatz danke kay
Kay Bohn wrote u.a.:
> vielleicht gibst da einen kleinen lösungsansatz
Am Ende des Quelltextes (also hinter dem Programmcode):
- Label für Text setzen (nenne es Textnamen)
- danach .db "Inhalt des Textes",0 eintragen (.db steht für Datenbytes),
dabei darauf achten, dass die Anzahl der Bytes geradzahlig ist, ggf.
zwei Nullen am Ende (.db "text",0,0)
Im Programmcode:
- mit "locate Zeile,Spalte" die Ausgabeposition festlegen
- mit "printf label" den Text ausgeben, der unter dem Label abgelegt
ist.
Im Zweifel nicht nur den Kommentar des jeweiligen Macros lesen, sondern
auch den Programmcode des Macros und der damit aufgerufenen Routine
lesen und versuchen zu verstehen.
Und Bitte die Routinensammlungen unterschiedlicher Herkunft nicht
durcheinander mischen, die neuere Print-Sammlung hat bei "print" nämlich
eine veränderte Syntax. Da wird neben dem Zeichen jetzt auch die Anzahl
angegeben: print '-',24 erzeugt z.B. eine ganze Zeile Minuszeichen,
print ':',1 erzeugt nur einen Doppelpunkt.
Es ist also immer erforderlich, auch mal in den Quelltext fremder
Routinen reinzuschauen, wenn man diese Routinen benutzen will. Ich
weigere mich z.B. fremde Routinen zu benutzen, die ich nicht verstehe.
Da können sie noch so gut sein, entweder ich verstehe sie, oder ich
verzichte darauf.
...
hallo hannes, habe mir das mal zu herzen genommen, hab heute den ganzen tag versucht etwas zustande zu bringen,habe mal denn code angehängt wie weit ich gekommen bin,das hin und herschalten zwischen den einzelnen (menü)texten funktioniert, aber wie muss ich weiter vorgehen um zb.wenn ich kanal1 anwähle und möchte hoch oder runter regeln. bin nun nicht son absoluter profi wie ihr vielleicht, deshalb meine frage, vielleicht kann mir einer von euch ein wenig weiterhelfen danke kay
Ich glaube, so wird das nix. Ich habe Dir meine Quelltexte nicht empfohlen, damit Du sie unverstanden nimmst und zerschnippelst, sondern damit Du sie analysierst und verstehst und mit diesem Verständnis Deine eigenen Routinen schreibst. Denn für Deinen Zweck taugt das Programm nix, da muss man die einzelnen "Bausteine" anders zusammenfügen. Analysiere doch erstmal, was DEIN Programm tun soll... Es soll: - 8 PWMs erzeugen - ein LCD ansteuern - Taster abfragen - die PWM-Grundwerte verändern Was davon ist wirklich zeitkritisch? - Das Erzeugen der 8 PWMs. Also fängt man mit dem Timer-Interrupt an, in dem die PWMs behandelt werden und natürlich mit der Initialisierung desselben. Also mit dem Programm 8pwm (oder wie das jetzt heißt). Da der Controller nun aber etwas mehr tun muss, muss Rechenzeit beschafft werden indem man das Aufrufintervall der Timer-ISR erhöht. Dies kann ggf. mit der Erhöhung der Taktfrequenz gekoppelt werden, um die PWM-Frequenz nicht zu langsam werden zu lassen. Nun lässt man in dieser Timer-ISR einen (Software-)Zähler mitlaufen, um ein weiteres "Zeitnormal" zu schaffen. In dessem Überlauf werden die Tasten entprellt und ein Register fürs Hauptprogramm hochgezählt, das mitteilt, was die Stunde geschlagen hat, quasi eine Art Kurzzeit-Uhr. Die kann man immer mal brauchen... Weitere Interrupts sind vermutlich nicht nötig. Ich würde sie zumindest vermeiden, um der PWM die absolute Priorität zu geben. Nun kommt die LCD-Ausgabe. Um den Timer-Interrupt nicht zu stören, würde ich hier die einfache direkte Ausgabe ohne Interrupt oder Timer-Synchronisation (also mit Wartezeiten) vorziehen, so wie es im Tutorial beschrieben ist. Die LCD-Ausgabe wird dann nur aufgerufen, wenn es etwas auszugeben gibt. Nun kommt die Sache mit den Menüpunkten. Die Hauptschleife fragt die Tastenflags ab und verzweigt bei gedrückter Taste zur (selbstzuschreibenden) Routine Menu. Dort wird auf die Tastendrücke reagiert. Hierbei kommt es darauf an, wie Du Dein Menü organisieren willst. Mein Zünduhr-Menü oder mein Stopuhr-Menü dürfte für Deinen Zweck die schlechteste Organisationsform sein. Es bietet sich z.B. ein "Cursorkreuz" mit 4 Tastern an, bei dem 2 Taster den PWM-Kanal auswählen, 2 andere den PWM-Tastgrad-Wert. Das währe wohl am einfachsten zu realisieren. Diese Routine müsste dann: - bei K+ den Kanal erhöhen - bei K- den Kanal vermindern - bei P+ den PWM-Tastgrad des Kanals K erhöhen - bei P- den PWM-Tastgrad des Kanals K vermindern - nach getaner Änderung die Tastenflags löschen und den neuen Wert am LCD ausgeben. Dies kann automatisiert werden, indem man anhand der aktuellen Kanalnummer die Ausgabeposition und den Wert (Kanalnummer als Index) ermittelt, also eine Ausgaberoutine für alle Kanäle. Wenn Du dann nochmal ins AVR-Tutorial schaust, findest Du eine Lösung, wie man die Tastenentprellung erweitern kann, um auch auf längere Tastendrücke reagieren zu können. Damit könntest Du die Tastgradwerte auch durch Dauerdruck in größeren Intervallen ändern. Bei der Kanalnummer hat das natürlich keinen Sinn. Das LCD kann so aufgeteilt werden, dass jeder Kanal seine eigene Position bekommt und alle Werte gleichzeitig angezeigt werden. Um nun zu zeigen, welcher Kanal gerade geändert werden kann (also welchen Wert die aktuelle Kanalnummer hat), kann man diesen Bereich der Anzeige blinken lassen. Aber das habe ich Dir ja weiter oben schon erklärt. Ein weiterer Timeout-Zähler könnte das Blinken nach einer gewissen Zeit der Nichtbetätigung wieder deaktivieren. ...
hallo hannes, erstmal danke. ich werd mich jetzt in den nähsten tagen mich damit intensiver beschäftigen. danke kay
HALLO, sitze schon die ganze woche dran aber ich komme einfach nich weiter, hab 5 tasten declariet hoch, runter,links,rechts,enter . aber wie schreib ich die routine um die fünf tasten aszuwerten, zb. taste2=runter -> menüauswahl, taste2 nochmal drücken in das untermenü1 springen dann mit enter bestätigen dann taste2 nochmal drücken kanal auswählen dann mit enter bestätigen dann die stellrichtung wählen + oder - wählen. mein grösstes problem wie werte ich die tasten aus um in den einzelnen menüs zu wechseln und um die kanäle auzuwählen da komm ich einfach nicht weiter. habe auch nich so viel ahnung wie die meisten von euch hier, alleine komme ich hier überhaupt nicht weiter, vielleicht kann mir denn jemand ein bischen weiter helfen, bitte. habe nochmal den code mal angehängt. danke kay
Gast
#511416
Hallo Kay, Du mußt Dir merken, in welcher Menüebene Du Dich befindest und davon abhängig die richtige Tastenauswertung aufrufen. Gruss Otto
Hey Kay... So wird das nix... Schau Dir die Macros 'printf' und 'printt' in lcdprint an. Und dann benutze sie. Du müllst Dein Programm mit unsinnigen Einzelzeichenausgaben zu und verschwendest sinnlos Speicherplatz und Rechenzeit (jedes print-Macro sichert das Register wl und stellt es hinterher wieder her). Um den ersten Text auf dem LCD auszugeben, definierst Du Dir ein paar Stringkonstanten (sinnvollerweise am Programmende)
1 | |
('string1' ist das Label, also der Konstantenname, erkennbar am
Doppelpunkt, '.db' dteht für Datenbyte, die Anzahl innerhalb einer Zeile
muss geradzahlig sein, weil jede Adresse zwei Bytes enthält, dahinter in
Anführungszeichen steht der Inhalt der Konstante, der mit printf
ausgegeben wird, 0 wird als Endekennung benutzt, damit printf weiß, wann
es genug ist.
und gibst diese mit1 | |
aus. Im nächsten Schritt legst Du Dir eine Liste von Ausgabetexten an, wobei jeder Text seinen eigenen Namen bekommt. Eine weitere Liste (Indexliste) enthält die Namen der Texte (die ja auch nur Platzhalter für Adressen sind), um mittels eines Index (Menüpunkt) und dem Macro 'printt' einen indizierten Text ausgeben zu können. Dann solltest Du mal eine verwertbare Struktur in Deine Menüpunkte bringen. Du hast nur ein eindimensionales Feld (Array) von Menütextkonstanten. Also ordne die Menüpunkte so an, dass sie mit einem Menüpunktindex unterschieden und ausgewählt werden können. Einfacher wäre es, wenn Du z.B. mit hoch/runter den Kanal wechselst und mit links/rechts den PWM-Wert des entsprechenden Kanals. Denn in Deiner Anwendung braucht es eigentlich kein Menü mit auswechselbaren Texten. Zeige einfach an 8 definierten Stellen Deines LCDs die 8 Werte an und markiere den Teil des LCDs, der den gerade veränderbaren anzeigt auf geeignete Weise. Falls Dir Blinken zu kompliziert ist, kannst Du ja vor und hinter dem Ausgabetext ein Sonderzeichen platzieren, z.B. '>' und '<' oder die Pfeilsymbole des LCD-Zeichensatzes. Oder '*', oder, oder... Anhand der Markierung sieht der Benutzer, welchen Wert er gerade ändern kann. Programme werden nicht ohne Plan drauflos geschrieben oder zusammenkopiert, Programme strukturiert man mit Bleistift und Papier vor dem Einschalten des Computers und das unabhängig von der benutzten Programmiersprache. Dabei zerlegt man die zu lösende Aufgabe in kleine Teilaufgaben, die dann konsequent umgesetzt werden. Ich würde Dir auch raten, Dein Projekt zu verschieben und erstmal das AVR-Tutorial (hier auf dieser Seite) konsequent durchzuarbeiten. Mit 'konsequent' meine ich, dass Du nicht bloß die vorhandenen Programmcodes in den Flash lädtst, sondern auch jede Zeile Programm verstehst und genau sagen kannst, warum das so und nicht anders gemacht wurde. ...
Gast
#511443
Hallo Kay, Hannes hat damit recht, dass vor dem Einschalten des Computers die Struktur des Programmes stehen sollte. Überlege Dir, welche "Menü-" und "Tasten-Ebenen" es geben soll. Auch die Wirkung der einzelnen Befehle - speziell aber die Anwendung "fremder" Funktionen sollte bekannt sein. Es gab mal Zeiten, da durfte man nur ganz kurz an einen Computer, um ein geschriebebenes Programm auszuprobieren... und wenn es nicht richtig lief mußte man dies "theoretisch" lösen - diese Zeiten sind zum Glück vorbei. Natürlich muß man auch mal "spielen" und die Wirkung eines Befehls ausprobieren. (Viele gute Programmierer haben mit dem "Aufbohren" eines "Hello World" angefangen und dabei Spaß daran bekommen - die meißten geben es nur nicht zu.) Aber wenn zu viele Zeilen mit unbekannten Befehlen und Funktionen auf einmal überblickt werden sollen, verliert man schnell den Überblick. Gruss Otto
> (Viele gute Programmierer haben mit dem "Aufbohren" > eines "Hello World" angefangen und dabei Spaß daran > bekommen - die meißten geben es nur nicht zu.) Das ist wohl wahr... @Kay: Ich zähle mich keinesfalls zu den "guten Programmierern", gebe aber offen zu, dass ich mit dem Aufbohren von Hallo-Welt-Programmen begonnen habe. Auch das Spielen mit Programmvarianten ist mir nicht fremd. Will man aber eine ganz bestimmte Aufgabe mittels Programm lösen, dann muss die Aufgabe vorher strukturiert werden. Denn schon dabei stellt man sehr schnell fest, dass man die Aufgabe nicht exakt genug formuliert hat. Und das Schreiben von Programmcode für eine nicht exakt formulierte Aufgabe wird sehr zeitintensiv und birgt sehr viele Fehlerquellen. Du willst die Taster hoch, runter, links, rechts und Enter. Nun erkläre uns doch mal mit normalen Sätzen, was passieren soll, wenn der jeweilige Taster betätigt wird. Falls die Funktion der Taster vom Menüpunkt abhängig ist, dann ist es wohl erforderlich, eine Tabelle anzufertigen, in die eingetragen wird, bei welchem Menüpunkt welche Taster welche Aktionen auslösen sollen. Manchmal reicht aber auch eine Art Plan, wie man sich durch die Punkte durchhangeln kann. Bei nur 4 Bedientasten kann man damit recht übersichtlich darstellen, welcher Taster in welchem Punkt welche Funktion haben soll. Im Anhang ist als Beispiel ein erster Entwurf für ein Menü. Es waren noch einige weitere Entwürfe und Änderungen notwendig, bis ich das Menü in Programmcode gießen konnte. Das Endergebnis kennst Du ja, den Link zur Zünduhr habe ich ja weiter oben bereits genannt. ...
hallo, so sitze jetz schon mehrere wochen jeden tag 3-4stunden dran um das "menü" zu realisieren. habe mir auch einen plan aufgezeichnet wie das "menü" aufgebaut sein soll, bei der umsetzung habert es ganz gewaltig ,ich komme auch nicht ein kleines bischen weiter, liegt auch daran das ich nicht so viel ahnung hab. daher wird es wohl besser sein ich lass das mit dem "menü" und lasse das orginal programm so wie es ist. ich danke euch trotzdem für eure mühe. gruss kay
hallo, habe nochmal probiert siehe anhang. im code sind 5 tasten deklariert dimplus hochdimm dimminus runterdimm chanplus kanal hoch chnminus kanal runter ruck zurück zum ausgangspunkt im code werden erstmal nur 2tasten abgefragt, chanplus kanal hoch dimplus hochdimm chanplus (t2) kanal1 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal2 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal3 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal4 --> dimplus (t4) hochdimmen das haut nicht richtig hin nur bei mehrmaligen tastendruck von t2 und t4 wechseln die kanäle. vielleicht kann mir denn jemand weiterhelfen. mfg kay
Ausschnitt aus Deinem Programm:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
Ist das Dein Ernst? ...
hallo hannes, JA? wie fange ich richtig an, wenn ich zb.t2 drücke verzweige dann nach kanal1 t2 noch ma drücken kanal2 usw. chanplus (t2) kanal1 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal2 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal3 --> dimplus (t4) hochdimmen t2 nochmal drücken chanplus (t2) kanal4 --> dimplus (t4) hochdimmen wie setze ich das richtig im code um? hoffe habe mich richtig ausgedrückt. danke mfg kay
@Kay: Es tut mir leid, dass ich das so drastisch sagen muss, aber Dein Programm ist den Speicherplatz nicht wert, den es belegt. Es ist kein Programm, sondern ein Haufen sinnlos zusammenkopierter Programmzeilen. Normal gliedert man (gliedere ich) ein Programm so: - Deklarationen (stimmt halbwegs, ist ja auch aus 8pwm kopiert) - Interrupt-Sprungtabelle (stimmt vermutlich auch) - hier kann man, falls erforderlich, Zusatzcode includieren, z.B. für LCD - Initialisierung, endet meist mit 'sei' - Hauptschleife als Endlosschleife, in der diverse Ereignisflags geprüft werden und ggf. Unterprogramme aufgerufen werden. - Unterprogramme der Hauptschleife, die von der Hauptschleife aufgerufen werden, wenn bestimmte Bedingungen erfüllt sind. Normal ruft man sie mit rcall / ret auf, unter bestimmten Bedingungen ist auch der Aufruf mit rjmp / rjmp mainloop sinnvoll. - Interrupt-Service-Routinen. Interrupts werden durch äußere Ereignisse (Timer-Überlauf, UART-RX, ...) ausgelöst und rufen über die Interrupt- Sprungtabelle die entsprechende ISR auf, die mit reti abzuschließen ist. - Konstanten, Tabellen usw... Die Hauptschleife kann ich bei Dir nicht erkennen, mangels Rücksprung (was ja die Schleife bildet) läuft die Abarbeitung gleich in die Menüauswertung rein. Die Menüauswertung soll aber nur aufgerufen werden, wenn mindestens eine Taste betätigt wurde, also wenn tfl ungleich 0 ist. Dass es trotzdem keinen Stacküberlauf gibt, liegt nur daran, dass die Unterprogramme nicht mit rcall/ret aufgerufen werden und der Rücksprung rjmp tastaus eine zufällige Endlosschleife (Mainloop-Ersatz) bewirkt. Dann hast Du sinnfrei kopiert und gelöscht, in Zeile 208 steht z.B. ein Skip (also ein IF THEN), es fehlt aber der Verzweigungsteil, weil die zwingend erforderliche Folgezeile nicht mitkopiert oder wieder gelöscht wurde. Im Absatz Menü fragst Du viermal hintereinander einunddieselbe Taste ab und verzweigst zu vier verschiedenen Unterprogrammen. Es kann natürlich nur in das erste Unterprogramm verzweigt werden oder in garkeins. Die anderen drei Abfragen werden nie erreicht wenn die erste schon zutrifft oder sind auch abweisend, wenn die erste abweisend war. In channel1 addierst Du zu soll0 das Register ri. Das hatte Sinn bei der Urversion mit Shift-Taste, bei der die Zählrichtung vom Zustand der Shift-Taste abhängig war, ri (Richtung) hatte den Wert 1 oder -1 (155). Da Du getrennte Tasten für hoch und runter hast, kannst Du den Wert mit inc und dec erhöhen und vermindern, musst aber auf Überlauf/Unterlauf achten. Das getrennte Zugreifen auf jeden der 8 Sollwerte kannst Du vergessen, da arbeitet man mit einer Kopie, die gemäß Kanalzähler als Index auf das Feld mit den 8 Sollwerten zugreift. Man setzt dazu einen Pointer (z.B. XH:XL) auf das Feld mit den Sollwerten (hier 0 oder 0x0000, falls das verständlicher sein sollte), addiert den Index (also die aktuelle Kanalnummer) dazu und holt den Wert mit ld wl,x bzw. schafft ihn mit st x,wl zurück. So kannst Du mit einer Routine die Werte aller Kanäle (nacheinander) ändern, mit der zweiten Routine änderst Du die Kanalnummer. Inzwischen sind auch die Register knapp geworden. Nun müsste man beginnen, SRAM zu verwenden. Im Interesse einer möglichst hohen PWM-Frequenz sollten PWM-Zähler und die 8 Sollwerte aber in (schnellen) Registern bleiben. Als ich das Urprogramm schrieb, war ja von LCD keine Rede. Jetzt, mit LCD, müssten die Ressourcen neu verteilt werden. Ich würde die Entprellung aus der ISR herausnehmen und per Flag in der Mainloop zyklisch aufrufen. Das ermöglicht, die Variablen für die Entprellung im SRAM zu halten, denn sie werden nur 50 mal pro Sekunde benötigt. Was sollen die 8 PWMs eigentlich mal ansteuern? LEDs? Halogenlampen? Lüftermotoren? Alles in Allem meine ich, dass Du mit etwas Kleinerem beginnen solltest um erstmal schrittweise logisch denken zu lernen. Code, den Du nicht verstehst, nützt Dir nichts. Das Projekt ist für Deinen momentanen Wissensstand zu groß. Du siehst doch selbst, dass Du keinerlei Konzept hast. Oder? ...
HALLO HANNES, Was sollen die 8 PWMs eigentlich mal ansteuern? Halogenlampen. 1. aber wie setze ich das nun praktisch um:? Das getrennte Zugreifen auf jeden der 8 Sollwerte kannst Du vergessen, da arbeitet man mit einer Kopie, die gemäß Kanalzähler als Index auf das Feld mit den 8 Sollwerten zugreift. Man setzt dazu einen Pointer (z.B. XH:XL) auf das Feld mit den Sollwerten (hier 0 oder 0x0000, falls das verständlicher sein sollte), addiert den Index (also die aktuelle Kanalnummer) dazu und holt den Wert mit ld wl,x bzw. schafft ihn mit st x,wl zurück. So kannst Du mit einer Routine die Werte aller Kanäle (nacheinander) ändern, mit der zweiten Routine änderst Du die Kanalnummer. 2. du sagst das ich " viermal hintereinander einunddieselbe Taste abfrage" aber wie muss ich das denn nun schreiben, das ich zb. 4 mal t1 drücke und bei jedem tastendruck eine andere aktion aufgerufen wird. mfg kay
Gast
#526362
Hallo Kay, bau Dir erst mal eine Minimalversion des Programmes. Übernimm nur Teile, die Du verstanden hast. Wenn Du abfragen willst, wie oft eine Taste betätigt wurde, mußt Du die Pegelwechsel zählen - nicht 4x hintereinander die selbe Taste abfragen - und nach erreichen des Zählerstandes die gewünschte Funktion ausführen. - Taste betätigt abfragen - Zähler erhöhen - Zähler sperren, bis Taste losgelassen Otto
Gast
#526395
Also, tut mir ja wirklich leid, aber ich kann mir eine Antwort nicht verkneifen... Ich bin bei weitem kein Profiprogrammierer, aber das was in dem Thread hier abgeht ist ja wirklich lustig... @Kay: Such dir ein Projekt, dass deinem Wissen entspricht: z.B. das Tutorial auf der Seite hier. Lerne indem du die Programme aus dem Tutorial erweiterst und eigene Ideen ausprobierst. Das was du hier vorhast ist definitiv eine Nummer zu groß für dich!!! Ich will dich hier nicht schlecht machen, auch ich habe mit dem Tutorial angefangen. Aber wenn du dir hier alles vorkauen lässt, wirst du nicht viel dabei lernen. @alle Anderen: Respekt für eure Geduld! (Falls da nicht ein Troll durchs Forum trampelt) Just my two cents... Dominik
Otto wrote: > - Taste betätigt abfragen > - Zähler erhöhen > - Zähler sperren, bis Taste losgelassen Oder besser gleich ne zentrale Funktion nehmen, die die Ereignisse (Taste gedrückt, Taste lange gedrückt, Wiederholfunktion) fix und fertig aufbereitet. Peter
Gast
#526479
Hallo Peter, nicht gleich übertreiben - das kommt danach Gruß Otto
Kay Bohn wrote: > Halogenlampen. Naja, da werden noch Probleme mit der Entstörung der Schaltstufen auftreten. Wirst ja sehen, wenn der Messwagen der RegTP (heißen die noch so?) vor Deinem Domizil steht (falls Deine MOSFETs nicht schon beim ersten Einschalten am Kaltstrom der Halogenlampen sterben). Das Erzeugen einer PWM ist ja eine Kleinigkeit, das störungsfreie Dimmen größerer Lasten ist da schon etwas aufwendiger. > 1. > aber wie setze ich das nun praktisch um:? Z.B. indem man versucht, die Aufgabe in kleinere, überschaubare und realisierbare Einheiten zu zerlegen. > 2. > du sagst das ich " viermal hintereinander einunddieselbe Taste abfrage" > aber wie muss ich das denn nun schreiben, das ich zb. 4 mal t1 drücke > und bei jedem tastendruck eine andere aktion aufgerufen wird. Das wurde bereits mehrfach genannt. Man verändert mit der Taste einen Zähler und wertet diesen Zählerstand aus. Wenn ich kleine Steuerungen mit zweizeiligem LCD mache, dann nehme ich 4 Tasten: - Menütaste: schaltet zum nächsten Menüpunkt... - Plus-Taste: erhöht den Parameterwert, der für diesen Menüpunkt gilt - Minus-Taste: vermindert den Parameterwert - Save-Taste: übernimmt den geänderten Parameter ins EEPROM und schaltet auf Menüpunkt 0, also auf Normalbetrieb. Die Plus/Minus-Tasten haben dann eine Repeat-Funktion. Nun zu Deinem PWM-Projekt: Was soll das Programm tun? Es soll: - PWM auf 8 Kanälen erzeugen - Die Werte der 8 PWMs ständig anzeigen - Die Tasten abfragen und entprellen - Die Werte ändern Die letzten beiden Punkte sind so schwammig formuliert, dass sie präzisiert werden müssen. Was soll passieren, wenn die Kanal-Plus- oder Kanal-Minus-Taste betätigt wird? Es soll der aktive (also der momentan beeinflussbare) Kanal ausgewählt (also verändert) werden. Dazu braucht man einen Zähler, der die momentan auswählbare Kanalnummer verkörpert bzw. darstellt. Dieser Zähler (nennen wir ihn 'kanal' und nutzen wir dazu ein unteres Register) wird je nach Tastendruck erhöht oder vermindert. Da dieser Zähler dabei Werte von 0 bis 255 annehmen könnte, wir aber nur 8 Kanäle haben, muss der Zählumfang begrenzt werden. Das geht am einfachsten, indem man nur die unteren drei Bit benutzt, die haben den Wertebereich 0 bis 7. Mit einer AND-Verknüpfung kann man diese Bits maskieren. Was soll nun passieren, wenn eine der Dimm-Tasten gedrückt wird? Klar, es soll eine PWM im Tastgrad verändert werden. Aber welcher Kanal?? Klar, der Kanal, der mittels Kanaltasten ausgewählt wurde, also der Kanal, dessen Nummer im Register 'kanal' steht. Um nun nicht mittels CPI alle möglichen Kanalnummern durchtesten zu müssen, nimmt man die Kanalnummer als Index auf das Array mit den 8 PWM-Werten (mit Soll0 bis Soll7 bezeichnet, der Einfachheit und des Tempos halber in den Registern r0 bis r7 gehalten) und holt sich eine Kopie des Wertes in ein freies Register (wl). Nun braucht bei der Auswertung der Dimmtasten keine Rücksicht mehr auf die Kanalnummer genommen werden, es wird einfach nur die Kopie manipuliert und dabei natürlich das Überschreiten des zulässigen Maximalwertes und das Unterschreiten von 0 wirksam verhindert. Am Ende der Tastenauswertung schreibt man den Wert der Kopie einfach wieder in das Array zurück. Eigentlich hält man so ein Array mit Variablen im SRAM und nicht in Registern. Hier ging es aber darum, in der ISR unnötige SRAM-Zugriffe zu vermeiden, damit die PWM nicht allzu langsam wird. Normalerweise meidet man auch die Register r0 und r1 für globale Variablen, da sie als Resultatregister der Multiplikation dienen. Doch in diesem Programm (in der ersten Version) stand Multiplikation nicht zur Debatte, also nahm ich keine Rücksicht darauf. Sollte MUL zwingend notwendig sein, so muss man die beteiligten Register eben frei halten... Im Anhang ist ein funktionierendes Programmbeispiel. Kannst ja mal versuchen, es zu verstehen. Achte darauf, dass Dein LCD an einem anderen Port hängt als Deine Taster und LEDs und dass in der Include-Datei mit den LCD-Routinen die Anschlussbelegung des LCDs korrekt eingetragen wird. Die Initialisierung des LCD-Ports erfolgt in der Include-Datei, Du brauchst also im Hauptprogramm keine kryptischen Hexwerte in die Portregister schreiben. Falls Dein fertiges Gerät Funkstörungen verursachen sollte und Dein Nachbar Dich bei der zuständigen Behörde anzeigt, weil er kein Radio oder TV mehr empfangen kann, dann hast Du irgendwas im Leistungsteil nicht richtig gemacht. Ich übernehme dafür keine Verantwortung. ...
hallo hannes, das leistungsteil ist richtig aufgebaut und relativ gut abgeschirmt hab ich schon öfters gebaut, hab mal zum test ein radio daneben gestellt um zu testen ob störungen auftreten, 1a empfang stört nix. ich glaub ich sollte mich erstmal intensiv mit den grundlagen befassen des avr assembler. ich danke nochmals für die hilfe und vorallem um die geduld!!!!
Kay Bohn wrote: > hallo hannes, > > das leistungsteil ist richtig aufgebaut und relativ gut abgeschirmt hab > ich schon öfters gebaut, hab mal zum test ein radio daneben gestellt um > zu testen ob störungen auftreten, 1a empfang stört nix. > > ich glaub ich sollte mich erstmal intensiv mit den grundlagen befassen > des avr assembler. > > > > ich danke nochmals für die hilfe und vorallem um die geduld!!!! Funktioniert es denn jetzt wenigstens? ...
ja super
hallo hannes, du hattest das programm... 8pwm2.asm... gepostet , nun meine frage wollte erstmal schritt für schritt etwas umändern für die lcd ausgabe , erstmal ohne dimmfunktion. .dseg ;SRAM-Variablen text : .byte 1 ;aktuelle zeile ZB. tasten: sbrc tfl,chanplus ;Kanal-Plus-Taste betätigt? - nein... lds wh,text ;text aus SRAM holen inc text ;inc =zeileneintrag erhöhen sts text,wh ;erstmal zurück ins SRAM cpi wh,7 ;Überlauf? brne ausgabe chanplus =1xdrücken um eine zeil vorwärts aus tabelle holen usw. sbrc tfl,chanminus ;Kanal-Minus-Taste betätigt? - nein... lds wh,text ;text aus SRAM holen dec text ;dec = zeileneintrag verringern sts text,wh ;erstmal zurück ins SRAM ldi wl,7 ; 7 einträge in der tabell text brne ausgabe chanminus= 1x drücken um wieder eine zeile zurück ausgabe: ;Wochentag und Uhrzeit ausgeben locate 0,20 ;Ausgabeposition printts textTabelle ,text ;Text aus Tabelle Rjmp mainloop textTabelle : .dw ZEILE0: .dw ZEILE01: .dw ZEILE02: .dw ZEILE03: .dw ZEILE04: .dw ZEILE05: .dw ZEILE06: .dw ZEILE07: ZEILE0: .db "set ",0,0 ZEILE01: .db "kanal 1 ",0,0 ZEILE02: .db "ok",0,0 ZEILE03: .db "kanal 2 ",0,0 ZEILE04: .db " ok ",0,0 ZEILE05: .db "kanal 3 ",0,0 ZEILE06: .db "ok",0,0 könnte das so in etwa funktionieren DANKE kay
> könnte das so in etwa funktionieren
Vermutlich nicht.
Du machst einen entscheidenden Fehler.
Du kopierst wild irgendwelchen Code aus verschiedenen Programmen
zusammen ohne ihn zu verstehen. Das bringt nix. Auch wenn die
verwendeten Programmfragmente alle von denselben (meinen) Fingern
getippt wurden passen sie nicht so einfach zusammen, da sie zu
unterschiedlichen Zeiten für verschiedene Projekte mit unterschiedlicher
Hardware (LCD 4x27 bzw. 8x24) und unterschiedliche Aufgaben geschrieben
wurden. Das ist also nicht mischbar.
Versuche stattdessen erstmal den funktionierenden Code zu verstehen. Ich
habe versucht, Dir das zu erleichtern, indem ich mir viel Mühe beim
Kommentieren des Codes gab. Solange Du fremden Code nicht verstehst,
wirst Du ihn auch nicht sinnvoll ändern können.
...
hallo hannes, so hab den code mal angehängt funktioniert einigermaßen. was mach ich da nur verkehrt . vielleicht könntest mal drüberfliegen. mfg kay
hallo hannes, anbei dein quellcode, mit einem zusatz lese und schreibroutine für das interne eeprom. wenn ich kanal 1 zb. auf 25% einstelle und taste 4 drücke sollte der wert ins eeprom geschrieben werden, so wenn wenn ich kanal 1 auf 0% stelle und drücke die taste 5 wert aus eeprom lesen, dann steht im display 255. irgendwo liegt der fehler. vielleicht kann mir einer weiterhelfen. danke mfg kay
Kay Bohn wrote: > hallo hannes, > > anbei dein quellcode, mit einem zusatz lese und schreibroutine für das > interne eeprom. > > wenn ich kanal 1 zb. auf 25% einstelle und taste 4 drücke sollte der > wert ins eeprom geschrieben werden, so wenn wenn ich kanal 1 auf 0% > stelle und drücke die taste 5 wert aus eeprom lesen, dann steht im > display 255. > > irgendwo liegt der fehler. > > vielleicht kann mir einer weiterhelfen. > > danke > mfg kay Wie kommst Du auf die Idee, dass Deine Routinen funktionoieren könnten? Wie (auf welche Art) übergibst Du den EEPROM-Routinen die EEPROM-Adresse, an die die Daten geschrieben werden sollen bzw. von der die Daten gelesen werden sollen? Wie übergibst Du der EEWRITE-Routine den zu speichernden Parameter? Wie verwertest Du den von EEREAD gelesenen Parameter im Hauptprogramm? Funktioniert es eigentlich, zwei ASM-Befehle in eine Zeile zu schreiben?
1 | |
2 | |
Ich weiß es nicht, habe es nie ausprobiert, werde es auch nicht tun, da ich es für sinnfrei halte. Wie verträgt sich eigentlich
1 | |
2 | |
3 | |
mit der dem hier?
1 | |
2 | |
3 | |
Du setzt die EEP-Adresse also auf den Wert, der gerade zufällig in r18 und r17 steht, also im Tasten-Wiederholzähler und im Register, dass die neu gedrückten Tasten meldet. Was soll das? Wenn Du für jeden Kanal einen Wert speichern können möchtest, dann solltest Du als Adresse auch die momentan aktuelle Kanalnummer benutzen. Ansonsten kannst Du gleich würfeln. Weiterhin benutzt Du r0 für EEP-Daten, obwohl r0 für den Sollwert des Kanal 1 reserviert ist. Du musst den Wert des gerade zur Änderung ausgewählten Kanals über den Index (Kanalnummer) ermitteln und ans EEP übergeben, dann muss die untere EEP-Adresse der Kanalnummer entsprechen, die obere EEP-Adresse muss einen festen Wert (0?) haben. Du musst damit aufhören, unverstandenen Code zusammen zu kopieren und damit beginnen, den benutzen Code zu verstehen und so anzupassen, dass er sich mit dem bereits vorhandenen Code verträgt. Anders wird das nix. ...
hallo hannes, so habe den quelltext nochmal angefügt,habe das nochmal umgeändert den wert speichern und lesen geht, der zuvor eingestellte wert wird richtig angezeigt, aber ob das so richtig ist? (Wie kommst Du auf die Idee, dass Deine Routinen funktionoieren könnten?) so steht es im datenblat des m8515. wie macht mann das richtig, hab im forum schon alles durchgeschaut aber nichts richtiges gefunden. vielleicht kann mir einer helfen. danke mfg kay
Kay Bohn wrote: > hallo hannes, > > so habe den quelltext nochmal angefügt,habe das nochmal umgeändert den > wert speichern und lesen geht, der zuvor eingestellte wert wird richtig > angezeigt, aber ob das so richtig ist? > > (Wie kommst Du auf die Idee, dass Deine Routinen funktionoieren > könnten?) > so steht es im datenblat des m8515. Richtig. Nur der Autor des Datenblatts geht davon aus, dass der Leser und Benutzer (Programmierer) mitdenkt und das Beispiel an seine Gegebenheiten und Bedürfnisse anpasst. Der Codeschnipsel im Datenblatt soll uns Folgendes sagen: - warte erstmal, bis der EEPROM betriebsbereit ist, er könnte ja noch vom letzten Schreibzugriff beschäftigt sein - setze eearl und eearh auf die Adresse, in die geschrieben werden soll oder von der gelesen werden soll Lesen: - Setze Leseimpuls (eere) - lies Wert aus eedr aus Schreiben: - lege den zu schreibenden Wert in eedr - hebe den Schreibschutz auf (eemwe) - setze innerhalb 4 Takte Schreibimpuls (eewe) Falls ein Programm mit Interrupts arbeitet, könnte zwischen Schreibschutz aufheben und Schreibimpuls setzen ein Interrupt zuschlagen und damit das Setzen des Schreibimpulses innerhalb der erlaubten 4 Takte verhindern. Aus diesem Grunde schaltet man an dieser Stelle auch noch kurzzeitig den Interrupt aus (CLI und SEI). Das Datenblatt nimmt für das Beispiel irgendwelche Register, die dem Autor gerade sinnvoll erscheinen. Nun weiß der Autor aber nicht, dass bei uns r17 und r18 bereits vergeben sind, auch nicht, dass r0 in diesem Programm einen von 8 Sollwerten enthält. Also ist er sich keiner Schuld bewusst, wenn er diese Register verwendet. Wir dürfen aber r17 nicht einfach für die EEP-Adresse nehmen, denn es enthält ja die Tastenflags. Auch r18 ist tabu, es enthält den Repeat-Zähler. Aber wir brauchen ja auch gar keine zwei Register für die EEP-Adresse, es war also Quatsch, dass Du einfach mal schnell die verwendeten Register umbenennst. Was wir brauchen, ist erstmal eine Analyse, was im EEP gespeichert werden soll. Also wieviele Adressen (Speicherzellen) wir brauchen und was da rein soll. Ich denke mal, es sind für jeden Kanal ein Byte abzuspeichern. Da wir 8 Kanäle haben, brauchen wir also 8 EEP-Zellen. Da bietet es sich an, als Adresse die Kanalnummer zu nehmen, denn sie enthält immer die Nummer des gerade zum Einstellen ausgewählten Kanals. Wir schreiben also die Kanalnummer in eearl. Und da diese Kanalnummer kleiner ist als der gesamte Adressbereich des EEP, wird eearh mit 0 beschrieben, der Einfachheit halber mit dem Register "null", das immer 0 enthält. Statt: out EEARH, r18 out EEARL, r17 oder gar: out EEARH, SOLL0 ;r0 out EEARL, r15 schreibt man besser: out eearh,null ;immer nur die untere EEP-Page benutzen our eearl,kanal ;Adresse = Kanalnummer Und schon ist die Adresse korekt auf den entsprechenden Kanal gesetzt. Wir haben also ein Teilproblem gelöst. Aber inzwischen merke ich: Ob ich Dir das erkläre, oder in Hamburg auf'm Bau fällt 'ne Schaufel um... Analysiere doch meine Änderung (im Anhang) selbst. Ich hoffe, es läuft, ich habe die Änderung nur mittels Texteditor gemacht, also weder mit AVR-Studio noch mit Hardware getestet. > > wie macht mann das richtig, hab im forum schon alles durchgeschaut aber > nichts richtiges gefunden. > > vielleicht kann mir einer helfen. Ich vermute, Dir kann keiner helfen solange Du penetrant das Mitdenken verweigerst. > > danke > mfg kay ...
hallo hannes, habe den quelltext nochmal angefügt funktioniert jetzt mit der sollwert speicherung. nun zu meiner frage, wenn zB. 3minuten keine taste gedrückt wird, dann soll zb. die hintergrundbelechtung ausgeschaltet werden. kann ich den timer0 dafür verwenden? für eine antwort wäre ich dankbar mfg kay
Kay Bohn wrote: > hallo hannes, > > habe den quelltext nochmal angefügt funktioniert jetzt mit der sollwert > speicherung. > > nun zu meiner frage, wenn zB. 3minuten keine taste gedrückt wird, dann > soll zb. die hintergrundbelechtung ausgeschaltet werden. Ich habe mir den Quelltext mal angesehen, kann aber nichts entdecken, was auf das Schalten der Hintergrundbeleuchtung schließen lässt. Das Programm unterstützt also gar keine Hintergrundbeleuchtung. Das Programm ist für das Pollin-LCD mit 4 Zeilen je 27 Zeichen geschrieben, das auch keine Hintergrundbeleuchtung hat. > > kann ich den timer0 dafür verwenden? Das weiß ich nicht. Ich könnte ihn dafür verwenden, wenn ich eine Hintergrundbeleuchtung am LCD hätte. Ob Du das kannst, weiß ich nicht. > > für eine antwort wäre ich dankbar Die hast Du hiermit erhalten. > mfg > kay MfG, Hannes P.S.: Deine Shift-Taste geht bald kaputt...
hallo Hannes, habe mir deine uhr(baustelle) mal angesehen die du glaube ich hier mal reingestellt hattes, ein mitlaufenden Zähler kann mann ja eigentlich immer mal gebrauchen. habe jetz mal denn quellcode etwas umgeändert siehe Anhang so das nach ca 5 minuten die hintergrund beleuchtung ausgeht und nach einem erneuten tasten druck die hintergrundbeleuchtung wieder angeht, funktioniert auch ganz gut mfg kay
hallo, mal ne kurze frage, wollte anstadt den m8515 den m162 einsetzen wie muss ich die Reset- und Interrupt-Vektoren für den m162 anpassen, zuzeit geht es mit dem m162 nicht,er zeigt auf dem display etwas an aber reagiert auf keinen tastendruck. benutze ponyprog habe bei den configurations und security bits alle haken entfernt. quellcode ist im anhang vielleicht kann mir einer weiter helfen danke mfg kay
Kay Bohn wrote: > hallo, > > mal ne kurze frage, > > wollte anstadt den m8515 den m162 einsetzen wie muss ich die Reset- und > Interrupt-Vektoren für den m162 anpassen, > zuzeit geht es mit dem m162 nicht,er zeigt auf dem display etwas an aber > reagiert auf keinen tastendruck. Das kann ja auch nicht gehen, da Du die Vektoren nicht angepasst hast. Der Mega162 hat mehr als 8kB Flash, da sind für jeden Vektor 2 Adressen reserviert, damit man den Befehl JMP einsetzen kann, der 32 Bit Flash belegt (RJMP belegt nur 16 Bit Flash, kann aber nur +/- 4kB weit springen). Du musst also in der Vektortabelle RJMP durch JMP ersetzen und sicherstellen, dass Du die Vektortabelle des Mega162 benutzt (siehe Datenblatt des Mega182). > > benutze ponyprog Naja, wenns "scheeen" macht... > habe bei den configurations und security bits alle haken entfernt. Da sollte man genau wissen was man tut. Da kann man sich schnell aussperren. > > quellcode ist im anhang Interrupt-Sprünge sind falsch, Du musst JMP statt RJMP verwenden. > > vielleicht kann mir einer weiter helfen Das habe ich soeben getan. > > danke > mfg kay ...
hallo hannes, habs eben nochmal probiert, tut sich garnix quellcode im anhang, oder muss nach jedem jmp nochmal ein reti schreiben zb. .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 162 jmp RESET ;Reset Handler jmp nix;EXT_INT0 ;IRQ0 Handler reti jmp nix;EXT_INT1 ;IRQ1 Handler reti jmp nix;TIM1_CAPT ;Timer1 Capture Handler reti jmp nix;TIM1_COMPA ;Timer1 Compare A Handler reti jmp nix;TIM1_COMPB ;Timer1 Compare B Handler reti jmp nix;TIM1_OVF ;Timer1 Overflow Handler reti jmp TIM0_OVF ;Timer0 Overflow Handler reti jmp nix;SPI_STC ;SPI Transfer Complete Handler reti jmp nix;USART_RXC ;USART RX Complete Handler reti jmp nix;USART_UDRE ;UDR0 Empty Handler reti jmp nix;USART_TXC ;USART TX Complete Handler reti jmp nix;ANA_COMP ;Analog Comparator Handler reti jmp nix;EXT_INT2 ;IRQ2 Handler reti jmp nix;TIM0_COMP ;Timer0 Compare Handler reti jmp nix;EE_RDY ;EEPROM Ready Handler reti jmp nix;SPM_RDY ;Store Program memory Ready Handler reti nix: ;unbenutzte Interrupts rjmp nix reti ;zurück... vielleicht kann mir nochmal jemand helfen danke mfg kay
Gast
#625097
Hallo Kay,
1. jmp nix;EXT_INT0 ;IRQ0 Handler
reti
jmp nix;EXT_INT1 ;IRQ1 Handler
..
..
..
nein - so nicht....
2. nix: ;unbenutzte Interrupts
rjmp nix
ist eine Endlosschleife !!!!
Otto
hallo, hab grad nochmal im DB nachgeschaut muss ich den die anderen sprünge im programm zb. rjmp durch jmp und rcall durch call ersetzen, so sollte es doch gehen oder? .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 162 jmp RESET ;Reset Handler jmp nix; EXT_INT0 ; IRQ0 Handler jmp nix; EXT_INT1 ; IRQ1 Handler jmp nix; EXT_INT2 ; IRQ2 Handler jmp nix; PCINT0 ; PCINT0 Handler jmp nix; PCINT1 ; PCINT1 Handler jmp nix; TIM3_CAPT ; Timer3 Capture Handler jmp nix; TIM3_COMPA ; Timer3 CompareA Handler jmp nix;TIM3_COMPB ; Timer3 CompareB Handler jmp nix; TIM3_OVF ; Timer3 Overflow Handler jmp nix; TIM2_COMP ; Timer2 Compare Handler jmp nix; TIM2_OVF ; Timer2 Overflow Handler jmp nix; TIM1_CAPT ; Timer1 Capture Handler jmp nix; TIM1_COMPA ; Timer1 CompareA Handler jmp nix; TIM1_COMPB ; Timer1 CompareB Handler jmp TIM1_OVF ; Timer1 Overflow Handler jmp nix; TIM0_COMP ; Timer0 Compare Handler jmp nix; TIM0_OVF ; Timer0 Overflow Handler jmp nix; SPI_STC ; SPI Transfer Complete Handler jmp nix; USART0_RXC ; USART0 RX Complete Handler jmp nix; USART1_RXC ; USART1 RX Complete Handler jmp nix; USART0_UDRE ; UDR0 Empty Handler jmp nix; USART1_UDRE ; UDR1 Empty Handler jmp nix; USART0_TXC ; USART0 TX Complete Handler jmp nix; USART1_TXC ; USART1 TX Complete Handler jmp nix; EE_RDY ; EEPROM Ready Handler jmp nix; ANA_COMP ; Analog Comparator Handler jmp nix;SPM_RDY ; Store Program Memory Ready Handler für ne antwort wäre ich dankbar mfg kay
Otto wrote: > Hallo Kay, > > 1. jmp nix;EXT_INT0 ;IRQ0 Handler > reti > jmp nix;EXT_INT1 ;IRQ1 Handler > .. > .. > .. > > nein - so nicht.... Stimmt, soooo nicht, das reti muss da raus, das ergibt keinen Sinn. > > > 2. nix: ;unbenutzte Interrupts > rjmp nix > > ist eine Endlosschleife !!!! Diese Endlosschleife ist gewollt. Darin soll sich das Programm aufhängen, falls durch Programmierfehler ein Interrupt erfolgt, der nicht durch eine ISR bearbeitet wird. In der "teig'schen Phase" kommen da noch entsprechende Debug-Maßnahmen (Error-LED einschalten) rein. Im Normalfall (fehlerfreies Programm) wird diese Schleife ja nie erreicht. > > > Otto Kai: Du musst die Reihenfolge (und Anzahl) der Vektoren an den Mega162 anpassen. Dazu musst Du Dir das Datenblatt anschaun, das enthält die Liste der Vektoren. Weiterhin musst Du die RJMP-Anweisungen durch JMP-Anweisungen ersetzen, da AVRs ab 16kB Flash 2 Adressen pro Vektor reserviert haben, AVRs bis 8kB Flash aber nur eine Adresse. Wenn Du das konsequent durchführst, dann sollte das Programm wieder korrekt laufen. ...
> muss ich den die anderen sprünge im programm zb. rjmp durch jmp und > rcall durch call ersetzen, Nein, dass musst Du nicht. Dazu ist Dein Programm zu klein. Dein Programm passt ja locker in einen Tiny2313, nur hat der leider zu wenig Pins. ...
hallo hannes, habe mir das so aus dem datenblatt rausgeschrieben für denm162 .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 162 jmp RESET ;Reset Handler jmp nix; EXT_INT0 ; IRQ0 Handler jmp nix; EXT_INT1 ; IRQ1 Handler jmp nix; EXT_INT2 ; IRQ2 Handler jmp nix; PCINT0 ; PCINT0 Handler jmp nix; PCINT1 ; PCINT1 Handler jmp nix; TIM3_CAPT ; Timer3 Capture Handler jmp nix; TIM3_COMPA ; Timer3 CompareA Handler jmp nix;TIM3_COMPB ; Timer3 CompareB Handler jmp nix; TIM3_OVF ; Timer3 Overflow Handler jmp nix; TIM2_COMP ; Timer2 Compare Handler jmp nix; TIM2_OVF ; Timer2 Overflow Handler jmp nix; TIM1_CAPT ; Timer1 Capture Handler jmp nix; TIM1_COMPA ; Timer1 CompareA Handler jmp nix; TIM1_COMPB ; Timer1 CompareB Handler jmp TIM1_OVF ; Timer1 Overflow Handler ;;******den brauchen wir******* jmp nix; TIM0_COMP ; Timer0 Compare Handler jmp nix; TIM0_OVF ; Timer0 Overflow Handler jmp nix; SPI_STC ; SPI Transfer Complete Handler jmp nix; USART0_RXC ; USART0 RX Complete Handler jmp nix; USART1_RXC ; USART1 RX Complete Handler jmp nix; USART0_UDRE ; UDR0 Empty Handler jmp nix; USART1_UDRE ; UDR1 Empty Handler jmp nix; USART0_TXC ; USART0 TX Complete Handler jmp nix; USART1_TXC ; USART1 TX Complete Handler jmp nix; EE_RDY ; EEPROM Ready Handler jmp nix; ANA_COMP ; Analog Comparator Handler jmp nix;SPM_RDY ; Store Program Memory Ready Handler nix: ;unbenutzte Interrupts rjmp nix reti ;zurück... werd das so morgen mal ausprobieren mfg kay
Erwarte jetzt aber bitte nicht, dass ich Deine Vektoren mit dem Datenblatt vergleiche (und abzähle), oder dass ich mir einen Mega162 kaufe um Dein Programm darauf auszuprobieren. Ich könnte es zwar im Simulator des AVR-Studio prüfen, aber das kannst Du auch selbst. Außerdem bräuchte ich dazu den kompletten aktuellen Quelltext, etwas Zeit, Lust und eine gewisse Motivation. Am Letztgenannten wird's wohl hapern. ...
Gast
#625219
Condi wrote:
> http://www.mikrocontroller.net/articles/AVR-Tutorial
Der Hinweis hätte glatt von mir sein können.....
Kay, was gibt es eigentlich für einen Grund, für diese einfache Aufgabe
einen Mega162 zu verwenden? Welche Vorteile hat das gegenüber dem
Mega8515? Die zweite Serielle wird es wohl nicht sein, denn Du nutzt ja
nichtmal die erste. Warum Mega162 und nicht gleich Mega644? Der ist doch
viel hochwertiger (also besser).
MfG, BlauBär
hallo, BlauBär der m162 hat mehr flasch als der m8515. hallo hannes, die sollwerte soll0-soll7 werden mit registern defeniert r0-r7, wollte nun die soll0-7 im sram ablegen, habe schon mal was probiert funktioniert aber nich richtig. code im anhang vielleicht könnte mir einer weiter helfen danke mfg kay
Kay Bohn wrote: > hallo, > BlauBär > der m162 hat mehr flasch als der m8515. Das ist natürlich ein schlagendes Argument!!! Der Flash des Mega8515 ist zu 11,8% ausgelastet. Der Code darf also auf das 8-fache wachsen, bis es im Mega8515 eng wird. Es gibt also keinen Grund, einwem Mega162 oder Mega232 einzusetzen. > > > hallo hannes, > die sollwerte soll0-soll7 werden mit registern defeniert r0-r7, Ja. Das hatte auch einen triftigen Grund. Nämlich die Abarbeitungsgeschwindigkeit bei der Software-PWM. Die PWM wird bedeutend langsamer, wenn die Daten aus dem SRAM geholt werden müssen. > wollte nun die soll0-7 im sram ablegen, habe schon mal was probiert > funktioniert aber nich richtig. > code im anhang Nunja, Du lädtst den Wert in das Register wl, vergleichst dann aber temp mit dem PWM-Treppenzähler. Kannst Du mir mal verklickern, welche Logik dahinter steckt?
1 | |
2 | |
3 | |
> > vielleicht könnte mir einer weiter helfen danke > mfg kay Wie soll das Helfen funktionieren bzw. ablaufen? Bisher war es doch so: - Du findest Code von mir, klatscht Code verschiedener Quellen zusammen und wunderst Dich, dass es nicht geht. - Ich repariere Dir das und es geht. - Du bastelst dran rum bis wieder nix geht. - Ich repariere es wieder. - Du willst einen größeren Controller, obwohl das Programm noch keine 12% des verfügbaren Flash belegt. Du deaktivierst alles das, was Du nicht verstehst (z.B. Werte beim Start aus EEP laden). Du verbastelst gut funktionierende Routinen, bis sie nicht mehr funktionieren und rufst jetzt nach Hilfe. Soll das jetzt so weiter gehen? Irgendwie verliere ich langsam die Lust und die Motivation. Was soll das Projekt eigentlich werden? Wo soll dieses Teil eingesetzt werden? ...
hallo hannes, Was soll das Projekt eigentlich werden? Wo soll dieses Teil eingesetzt werden? es soll eine raumbeleuchtumg werden mit 63 halogenlampen a20 watt bei 12Volt die lampen und stromversorgung sind schon installiert und geht. der hintergrund warum die sollwerte ins sram sollen ist das die register langsam knapp werden,es sollten dann vielleicht noch ein paar ausgänge dazu kommen,um lampen zu dimmen muss die pwm nicht so schnell sein. deshalb war meine frage wie macht mann das im sram, hab nochma was umgeändert vielleicht kann nochmal jemand drübersehen danke mfg kay
Kay Bohn wrote: > es soll eine raumbeleuchtumg werden mit 63 halogenlampen a20 watt bei > 12Volt die lampen und stromversorgung sind schon installiert und geht. > > der hintergrund warum die sollwerte ins sram sollen ist das die register > langsam knapp werden,es sollten dann vielleicht noch ein paar ausgänge > dazu kommen, Wieviele Ausgänge konkret? Mach doch mal Nägel mit Köpfen... Mach eine konkrete Schaltung mit allen Ein- und Ausgängen des Mega8515. Das was Du vor hast, macht der Mega8515 genauso gut wie der Mega162. Dann mache eine konkrete unmissverständliche Beschreibung, was das Programm machen soll. Dann Schreib mir 'ne Mail. > um lampen zu dimmen muss die pwm nicht so schnell sein. > deshalb war meine frage wie macht mann das im sram, hab nochma was > umgeändert Deine Soft-PWM müsste so halbwegs gehen (außer Bit 0, da vergleichst Du wieder Äpfel mit Birnen), aber es geht auch noch etwas schneller. Doch kleckerweise wird das nix. Mach ein Pflichtenheft, also eine konkrete Beschreibung, was die Software tun soll. ...
HALLO, danke nochmal schicke dir morgen ne mail mfg kay
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
