Hi, ich bin habe mir momentan ein kleines Projekt zugemutet aber da ich
nicht so viel Erfahrung habe in Atmega8 programmieren hab ich gehofft
ihr könntet mir etwas helfen.
Also meine Idee ist es einen Multiplexer zu programmieren (Platine ist
schon fertig). Dieser Multiplexer hat 20 Digitale Eingänge
(PD0...PD7,PB0...PB6, PC0..PC5) die eingelesen werden müssen und in
einem Array gespeichert.
Nun soll meine SPS eine Anfrage über PB6 schicken( auf steigende Flanke
schauen) dann soll der Atmega 100ms warten. Anschließende soll nach
einer festgelegten Reihenfolge die Zustände der 20 Digitalen Eingänge
über den Ausgang PB7 in einem 50ms Takt ausgegeben werden. Ist so eine
Art Morse.
Es geht mir nur um die Atmega Programmierung.
Ich weiß garnicht wie ich da Anfangen könnte.
Es würde mich sehr freuen wenn einer von euch genug Zeit und Lust hat
mir dabei zu helfen.
Ah, so eine Art Bake?
Der PB6 kann nicht als digitaler Eingang benutzt werden, wenn er schon
mit der SPS kommuniziert.
Das Array braucht es auch nicht, die Abfrage der Eingänge macht man
während man sie sendet.
Wenn PB6 als open collector arbeitet, dann kann das funktionieren. Die
SPS gibt quasi die Kommunikation frei.
Die Aufgabe ist super simpel:
- Warte auf PB6 high
- Setze Timer(n) auf 100 ms
- Warte auf Timer(n) abgelafuen, wenn PB6 low dann zum Start
- Schleife über alle Inputs :: frage Input ab und sende byte
Peter Q. schrieb:> Ich weiß garnicht wie ich da Anfangen könnte.
Indem du die Aufgabe in Teilschritte zerlegst (hast du weitgehend
als Prosa bereits hingeschrieben) und daraus einen Programmablauf
planst.
Die nötigen Grundlagen musst du dir natürlich schon erstmal
(spielerisch) vorher aneignen, also:
. wie lese ich Pins ein
. wie erkenne ich die Änderung eines Pins
. wie gebe ich ein Bit aus
. wie warte ich eine bestimmte Zeit
Das alles geht noc völlig linear für den Anfang, ohne Intrrupts,
ohne Timer. Das ist natürlich nicht sehr elegant dann, aber es löst
die gestellte Aufgabe und braucht am wenigsten Knowhow deinerseits.
Optimieren kannst du danach:
. Schaltflanke per Interrupt erkennen (geht beim ATmega8 nur über
Timerinterrupt, wenn du einen ATmega88 nimmst, könntest du auch einen
Pinchange-Interrupt benutzen)
. Ausgabe über Timerinterrupt steuern
. Rest der Zeit schlafen gehen
Thomas W. schrieb:> Das Array braucht es auch nicht, die Abfrage der Eingänge macht man> während man sie sendet.
Dann hast du aber keinen Momentanzustand (*), sondern würdest sich
ggf. ändernde Werte ausgeben.
(*) Hast du natürlich streng genommen sowieso nicht, weil sich nicht
alle drei Ports gleichzeitig abfragen lassen, aber zumindest sehr
schnell hintereinander.
okay also der eingang PB6 wird von 24V über einen Optokoppler
geschaltet, das ich auf die gewünschte eingangspannung komme.
Wie arbeite ich denn mit einem Interrupt? Pins einlesen und ausgänge
schalten bekomm ich auch noch hin aber die Schleife bei einem Interrupt
starten usw. raff ich noch nicht so :D
Kann jemand zufällig so eine kleine Code Anleitung schicken :D
Peter Q. schrieb:> DDRD &= ~(1 << PD0), ~(1 << PD1),~(1 << PD2),~(1 << PD3),~(1 << PD4),~(1> << PD5),~(1 << PD6),~(1 << PD7);
Nun, die Übung mit dem Komma-Operator solltest du dir nochmal
ansehen. Der hat eine ganz andere Bewandnis als das, was du hier
willst.
Aber: die DDRx-Register sind nach einem Reset ohnehin 0, noch
„nuller“ geht's nicht. Lass sie also einfach in Ruhe.
Korekt wäre übrigens:
1
DDRB&=~((1<<PB0)|(1<<PB1)|…|(1<<PB6));
> _flanke = PINB; // zu testende Variable
Lass mal den Unterstrich weg.
> while(1){> if ( ( flanke & (1<<PB6) ) != 0 )> && ( alteflanke & (1<<PB6) ) == 0 ) )
Vergiss nicht, „alteflanke“ vor dem Ende der while-Schleife mit
dem aktuell getesteten Wert zu setzen.
> PINB7 = inp (PIND0); // Schreibe Zustand an PD0 in PB7
inp() ist nirgends definiert.
Ansonsten ist das aber als allereinfachste Implementierung OK.
liefert unabhängig davon, ob #define inp(x) (1<<(x)) ist, eine
Fehlermeldung, da PINB7 eine Konstante =7 ist.
Was soll in deinen Augen PINB7 = <expr> bewirken ?
Hallo
Peter Q. schrieb:> Dann müsste es ja so gehen oder?> Wenn ich jetzt das Programm mit dem Programmer auf den Atmega8 brennen> möchte, woraum muss ich da achten damit der seinen internen Ozilator> benutzt?
Nicht glauben, sondern wissen ist angesagt.
Also über testen und abändern kann man vielleicht verstehen, was Jörg
Wunsch und Peter Dannegger die mitteilen möchten.
Du denkst an PINB7 kann man Informationen ausgaben und das ist falsch.
Schau dir bitte auch die Procedure
1
pinb7(uint8_tval);
, dies ist eine besondere Funktion.
Die Nahmeswahl ist nicht die Beste, da Du so den Unterschied zu PINB7
nicht siehst!
1
writeBit_to_B7(uint8_t);
Am effizientesten wird Dir, nach eine weile, 1-2 Jahre, lernen die
Macrosammlung sbit.h von Peter Dannegger vorkommen.
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