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
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
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
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 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
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
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
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.htmlhttp://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,
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
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: .db "Das ist der Text der Zeile 1",0,0
('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 mit
1
printf string1
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.
...
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
@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
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
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
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?
...
> 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,
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
sbrc tfl, EEWRITE rcall EEPROM_read
2
sbrc tfl, EEREAD rcall EEPROM_write
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
.def soll0 = r0 ;Sollwert Kanal 1
2
.def tfl = r17 ;Flags für Tasten, die gedrückt wurden
3
.def twz=r18 ;Tasten-Wiederholzähler
mit der dem hier?
1
out EEARH, r18
2
out EEARL, r17
3
out EEDR,r0
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
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.
...
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.
...
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
lds wl, soll5
2
cp pwz, temp
3
rol temp ;Bit 5
>> 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.
...