mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MENÜ-STEUERUNG


Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Kay,

was verstehst Du unter "Menü-Steuerung" ?
Softkeys unter einem LC-Display ?

Gruss Otto

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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




Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo otto

habe mal nochmal mein code angehängt
wie weit ich bisher gekommen bin




kay

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Kay,

ja, ich sehe schon: Du kommst damit klar...

Gruss Otto

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo otto,
werd mir das jetz noch zugemüte führen
werd mich morgen nochmal melden

danke erstmal
kay

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Kay,

bin morgen erst spät online - aber es gibt ja noch genug andere...

Gruss Otto

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo hannes,

erstmal danke.
ich werd mich jetzt in den nähsten tagen mich damit intensiver 
beschäftigen.

danke
kay

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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



Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Kay,

Du mußt Dir merken, in welcher Menüebene Du Dich
befindest und davon abhängig die richtige
Tastenauswertung aufrufen.

Gruss Otto

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)
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
 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.

...

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> (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.

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ausschnitt aus Deinem Programm:
menu:

M0:
 sbrC tfl,chanplus               ;kanal hoch Taste? nein...
 RJMP channel1                  ;ja...

M1:
 sbrC tfl,chanplus               ;kanal hoch Taste? nein...
 RJMP channel2                  ;ja...
 
M2:
 sbrc tfl,chanplus               ;kanal hoch Taste? nein...
 RJMP channel3                  ;ja...
 
M3:
 sbrc tfl,chanplus               ;kanal hoch Taste? nein...
 RJMP channel4                  ;ja...
 ;cbr tfl,(1<<chanplus)
 cbr tfl,alltast            ;alle Tasten sind erledigt
 rjmp tastaus

Ist das Dein Ernst?

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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?

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

nicht gleich übertreiben - das kommt danach

Gruß Otto

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!!!!

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja super

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
sbrc tfl, EEWRITE          rcall EEPROM_read
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
.def soll0 = r0             ;Sollwert Kanal 1
.def tfl = r17              ;Flags für Tasten, die gedrückt wurden
.def twz=r18                ;Tasten-Wiederholzähler
mit der dem hier?
out EEARH, r18
out EEARL, r17
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.

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Troll Blaubär (blaubeer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
 lds wl, soll5
 cp pwz, temp
 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?

...

Autor: Kay B. (newbie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Kay B. (newbie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HALLO,
danke nochmal schicke dir morgen ne mail

mfg kay

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.