Hallo!
Ich arbeite mit einem ATmega32L. Ich möchte gerne einen Start/Stop
button implementieren. Das Programm soll nach dem Überschreiben nicht
sofort loslaufen, sondern erst beim Betätigen des Buttons. Wie
implementiere ich sowas?
Vielen Dank fürs Helfen!
Hallo,
um das mal ganz genau zu sagen, wenn dein Programm nicht läuft, kannst
du auch nicht feststellen, ob eine Taste gedrückt ist. Das ist ja
bereits Teil von deinem Programm. Selbst wenn man das über
Pinchange-Interrupt macht, muß zuerstmal das Programm loslaufen und die
Interrupts konfigurieren. Erst dann kann ein Interrupt auftreten, wenn
sich ein Pin am Port ändert.
Du willst aber sicher eine bestimmte Funktion ausführen, wenn eine Taste
gedrückt wurde. Dazu gibt es beispielsweise hier einen Artikel:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten
Das ist natürlich nicht der einzige. Nimm mal die Suchfunktion, da
findest du sehr viele Beispiele.
Kann man es nicht irgendwie über Reset pin lösen? Wäre ungefähr so,
dass am anfang am Reset GND anliegt, dann durch Betätigen des in diesem
Fall notwendigen Tasters würde dann VCC anliegen usw...
Oder kann man es irgendwie besser lösen?
... schrieb:> Kann man es nicht irgendwie über Reset pin lösen? Wäre ungefähr so,> dass am anfang am Reset GND anliegt, dann durch Betätigen des in diesem> Fall notwendigen Tasters würde dann VCC anliegen usw...>> Oder kann man es irgendwie besser lösen?
Dann darfst du aber keinen Taster nehmen, sondern einen Schalter. Und
zwar einen, der nicht prellt. Da mußt du also die Entprellung schon
hardwaremäßig machen, zum Beispiel duch ein Flipflop.
Hier ist ein Beispiel:
http://www.mikrocontroller.net/articles/Entprellung#Wechselschalter
Bernd S. schrieb:> Dann darfst du aber keinen Taster nehmen, sondern einen Schalter. Und> zwar einen, der nicht prellt.
Für die Entprellung könnte man auch die Start-up Zeit für den Oszillator
missbrauchen. Die 64ms dürften dafür ausreichend sein.
Üblicherweise lässt man die Initialisierung IMMER ablaufen.
Viele Ressourcen existieren vorher gar nicht.
Nachdem dies geschehen ist, hindert Dich allerdings nichts daran VOR dem
Einsprung in die übliche Hauptschleife eine Abfrage zu platzieren.
Übrigens, wie willst Du ohne das übliche Prozedere einen Eingang,
vernünftig abfragen? Für eine Unterbrechung muss diese initialisiert
worden sein. Eine Entprellung benötigt üblicherweise auch einen Zeiter.
Fallobst schrieb:> missbrauchen. Die 64ms dürften dafür ausreichend sein.
Oft ja, und vor allem, wenn die Schalter neu sind. Ist aber keine
zuverlässige Lösung.
Ich hab schon Schalter gesehen, die schon im Neuzustand paar 100ms
geprellt haben. Ich möchte die nicht sehen, wenn die paar Jahre auf dem
Buckel haben ;-)
Mit Schalter+Kondensator gefällt mir am besten, da ziemlich einfach.
Ich wundere mich nur grad drüber, dass ich hier auch ein System habe,
dass genau das Gleiche tut, aber mit einem Taster! Hat jemand eine Idee
wie das funktionieren könnte? Mit einem Schalter kann ich zwischen GND
und VCC schalten, aber mit einem Taster??
Ein Taster ist nur so lange geschlossen, wie er gedrückt ist. Wenn du
ihn losläßt, geht er zurück.
Zeig mal das System, was du hast. Ich denke, daß dort auch das Programm
schon läuft, und dann die Eingänge abfragt. Und nur, wenn der Taster
gedrückt wurde, wird die Aktion ausgelöst. Also Taster-Abfrage in der
Software.
Bist du sicher, daß vor dem Druck des Tasters wirklich der Prozessor
steht? Oder macht er nur nach außen hin "scheinbar" nichts?
... schrieb:> Mit Schalter+Kondensator gefällt mir am besten, da ziemlich einfach.
Das scheint die beste Lösung zu sein, aaaber:
Ein Kondensator parallel zum Taster bewirkt auf die Dauer einen Abbrand
der Kontakte. Er wird ja jedesmal, wenn man den Kontakt schließt,
schlagartig entladen. Daran sollte man auch denken.
Bernd S. schrieb:> Zeig mal das System, was du hast. Ich denke, daß dort auch das Programm> schon läuft, und dann die Eingänge abfragt. Und nur, wenn der Taster> gedrückt wurde, wird die Aktion ausgelöst. Also Taster-Abfrage in der> Software.
Nee, da läuft vorerst noch kein Programm. Ich habe folgenden einfachen
Code ausprobiert:
1
intmain(void)
2
{
3
4
//LEDs
5
DDRC|=PINC4_SL1|PINC5_SL2|PINC6_SL3;
6
PORTC|=PINC4_SL1|PINC5_SL2|PINC6_SL3;
7
8
while(1)
9
{
10
}
11
12
}
Nach dem flashen des Programms brennen keine LEDs. Erst nach drücken des
Tasters wird main() ausgeführt...
Folgende Idee:
Auf dem µC wurde ein Bootloader draufgespielt. Kann es sein, dass dieser
hier irgendwie reinspuckt?
Bernd S. schrieb:> Ein Kondensator parallel zum Taster bewirkt auf die Dauer einen Abbrand> der Kontakte.
Hmmm ok.
amateur schrieb:> Kann es sein, dass Dein Liebling (Taster) am Reset-Pin herum hängt?
:D
Habe folgendes gefunden:
Der start/stop Taster hängt von der einen Seite an einem pulldown
Widerstand und an einem µC pin! Dieser pin wird später im Code auf
output direction und low level programmiert. Die andere Seite des
Tasters ist mit Reset pin verbunden.
-> Nach meinem Verständnis sollte also beim Drücken des Tasters ein
Reset durchgeführt werden. Das geschieht wohl auch. Das interessante
und für mich unverständliche ist, dass der µC im Reset verbleibt, bis
der Taster wieder betätigt wird. Und wie das möglich ist, ist mir
schleierhaft.
... schrieb:> Folgende Idee:> Auf dem µC wurde ein Bootloader draufgespielt. Kann es sein, dass dieser> hier irgendwie reinspuckt?>
Kommt drauf an, wie der Bootloader aussieht. Vielleicht fragt der
seinerseits den Taster ab. Bis zum Tastendruck ist er im
Programmiermodus. Beim Tastendruck startet der das Programm. Ist aber
ungewöhnlich.
Eigentlich macht man es so, daß man erst durch Tastendruck in den
Programmiermodus kommt. Oder man ist z.B. nach dem Reset 500ms im
Programmiermodus, und wenn dann keine Daten kommen, startet man das
"Hauptprogramm". Aber mögich ist theorestisch alles.
Vermutest du, daß ein Bootloader drauf ist, oder weißt du es? Wenn ja,
schmeiß ihn doch mal raus. Du flashst den Controller doch jetzt sowieso.
Und wenn du nicht über die RS232 oder CAN oder wie auch immer den
Bootloader ansprechen willst, kannst du ihn auch rauswerfen.
Dann verhält er sich wie ein "normaler" Controller.
Wenn du die Funktionsweise des vorhandenen (?) Bootloaders kennst, dann
mußt du ja auch wissen, wann er den Programmiermodus verläßt und das
eigentliche Programm startet.
Bernd S. schrieb:> Vermutest du, daß ein Bootloader drauf ist, oder weißt du es? Wenn ja,> schmeiß ihn doch mal raus.
Hab den Bootloader mal rausgeschmießen und siehe da, der start/stop
button funktioniert nicht mehr. Also war es der Bootloader.
Wie der Boatloader programiert wurde weiß ich nicht....
Na gut, dann muss ich mir also selbst was überlegen, wie ich den
start/stop button auch ohne Bootloader zum Laufen bringe....
Gut, dann wissen wir schon mal, daß es keine Hardware war (Reset z.B.).
Der Taster wurde also von der Software abgefragt.
Das kannst du doch in deinem Programm genauso machen, oder?
Beispiele dafür gibts viele, einschließlich Tastenentprellung.
Im Forum gibts eigentlich alles, was du dazu brauchst. Schau dich mal
um.
Und wenn du nicht weiter kommst, fragst du wieder, ok?
@... (Gast)
Deine Kombination scheint etwas eigen zu sein.
Ich hatte bis jetzt 5 verschiedene (USB-Flasch) Systeme auf dem Tisch.
Alle folgten folgender Logig:
-Wird die Taste beim Reset betätigt, so springt das Teil SOFORT in die
Warte-Auf-Daten-Schleife - notfalls bis zu St. Nimmerleins Tag.
-Wird der Taster nicht betätigt, wird SOFORT das Was-Auch-Immer-Programm
begonnen. Das konnte, natürlich nach der Übername der Kontrolle,
seinerseits diesen Taster abfragen.
Das ist dann aber eine explizit zu programmierende Funktion, die
natürlich mit der Doppeldeutigkeit der Startsituation leben muss.
amateur schrieb:> Deine Kombination scheint etwas eigen zu sein.
Meine Logik scheint diese zu sein:
- Flashspeicher wird programmiert, und dann wird µC sofort im Reset
gehalten. Dies geschieht so lange bis, der Start button gedrückt wird.
- Wird Start button gedrückt, dann wird das programm so lange
ausgeführt, bis der button nochmals betätigt ist.
- Wird button nochmals betätigt wird der µC sofort wieder im Reset modus
gehalten.
Bernd S. schrieb:> Gut, dann wissen wir schon mal, daß es keine Hardware war (Reset z.B.).> Der Taster wurde also von der Software abgefragt.
Wie der Taster abgefragt wurde, ist mir völlig unklar. Der Schaltplan
der Platine ist da mehr als dubios. Aber da bootloader weg ist,
interessiert es ja nicht mehr wirklich...
Meiner Ansicht nach habe ich nun 2 Möglichkeiten:
1) Entweder ich baue einen Schalter dazu, der einfach Reset pin und GND
verbindet. Ist meiner Ansicht nach die beste und einfachste Lösung oder?
^^
2) Ich frage über ein Pin einen Taster ab und resete dann den µC per
Software. Schreibarbeit und pinverbrauch ^^
Oder hab ich da was übersehen?
Übrigens, vielen Dank für deine Hilfe Bernd! :)
Der Anschluß des Tasters an den Prozessor muß doch irgendwie
rauszufinden sein, denke ich.
Wenn du einen neuen Taster anschließen willst, ist es am einfachsten, du
verbindest den Taster mit einem Pin des Prozessors und die andere Seite
des Tastes gegen GND. Im Prozessor aktivierst du nur den Pullup des Pins
und schaltest den Pin natürlich auf Eingang. Damit liegt bei offenem
Taster high am Pin und bei geschlossenem Taster eben low.
Diese beiden Zustände kannst du mit deinem Programm auswerten. Du
bleibst eben so lange in einer Schleife, bis der Pin low wird. Und erst
dann gehst du weiter zu deinem eigentlichen Programm.
Aber du kannst ja auch mal schreiben, was du eigentlich damit bezwecken
willst. Warum willst du verhindern, daß nach dem Programmieren des
Controllers dessen Programm losläuft? Erkläre das mal bitte. Dann können
wir auch weiter nachdenken, wie man dein Problem lösen kann. Aber im
Moment weiß ich nicht, warum du das so willst.
>Meine Logik scheint diese zu sein...
Die Teile, die in der Hand hatte, hatten gar nicht so viele Tasten - vor
allem keine die übrig waren.
Entweder insgesamt eine Taste oder Reset-Taster plus eine Taste.
amateur schrieb:>>Meine Logik scheint diese zu sein...>> Die Teile, die in der Hand hatte, hatten gar nicht so viele Tasten - vor> allem keine die übrig waren.>> Entweder insgesamt eine Taste oder Reset-Taster plus eine Taste.
Was für Teile hattest du denn in der Hand? Was hatte nur eine Taste?
Bis jetzt wurde noch nicht gesagt, um welche Hardware es sich handelt.
Nur, daß es um den ATmega32 geht. Oder hab ich was übersehen?
@Bernd:
Ich programmiere ein fahrendes System. Wenn ich es flashe dann steht es
bei mir auf dem Tisch und soll natürlich nicht sofort losfahren und vom
Tisch runterspringen. ^^ Erst wenn ich den Schalter umlege, dann soll es
losfahren und verschiedene Sachen machen... Habe ich was falsch
programmiert, dann will ich auch die Möglichkeit haben das Ding über den
Schalter zu stoppen.
Dass ich das Ding stoppe, indem ich den µC in Reset zustand halte finde
ich eigentlich top. Dann kann ich das Ding einfach nochmal von vorne
losfahren lassen oder mit einem anderen Programm beschreiben.
Wenn ich das so mache, dann brauche ich keine Tastenabfrage mehr und
auch keinen zusätzlichen Code. Sehe bis jetzt kein Nachteil darin Reset
pin über einen Schalter auf GND zu ziehen. ^^
... schrieb:> @Bernd:>> Ich programmiere ein fahrendes System. Wenn ich es flashe dann steht es> bei mir auf dem Tisch und soll natürlich nicht sofort losfahren und vom> Tisch runterspringen. ^^ Erst wenn ich den Schalter umlege, dann soll es> losfahren und verschiedene Sachen machen... Habe ich was falsch> programmiert, dann will ich auch die Möglichkeit haben das Ding über den> Schalter zu stoppen.>> Dass ich das Ding stoppe, indem ich den µC in Reset zustand halte finde> ich eigentlich top. Dann kann ich das Ding einfach nochmal von vorne> losfahren lassen oder mit einem anderen Programm beschreiben.>> Wenn ich das so mache, dann brauche ich keine Tastenabfrage mehr und> auch keinen zusätzlichen Code. Sehe bis jetzt kein Nachteil darin Reset> pin über einen Schalter auf GND zu ziehen. ^^
Okay, kann man machen... Du merkst, meine Begeisterung hält sich stark
in Grenzen :-)
Sowas mit dem Reset zu machen bedeutet, daß du z.B. niemals im Stand des
Gerätes auch nur die kleinste Aufgabe erledigen kannst. Das Gerät ist
einfach "tot". Wenn du sowas wie einen Not-Halt machen willst,
unterbrich einfach den Strom. Und das machst du dann wirklich nur im
Notfall.
Ansonsten soll das Gerät ja bestimmt nicht nur fahren, bis der Akku alle
ist, sondern auch zwischendrin mal stoppen, vorwärts und rückwärts
fahren, mit verschiedenen Geschwindigkeiten und vieles mehr. Das geht
doch alles sowieso nur, wenn der Prozessor auch läuft. Und auch bei
laufendem Prozessor den Motor am Programmanfang (also nach dem Flashen)
nicht loslaufen zu lassen, sondern erst, wenn du es willst, ist ja kein
Hexenwerk. Dafür ist ja der Prozessor da. Was soll er sonst mit seiner
Rechenzeit anfangen? Er langweilt sich ja sowieso schon...:-)) Wenn du
beim Strom einschalten und dann Taster drücken nur den Motor loslaufen
lassen willst, brauchst du keinen Prozessor. Da reicht ein Schalter, der
den Motor mit der Batterie verbindet.
Also überleg dir das nochmal. Es ist doch kein Problem, das Programm
ganz normal loslaufen zu lassen. Dabei dreht sich noch kein Motor. Den
steuerst du erst an, wenn du einen Tastendruck erkennst. Dann hast du
genau das Verhalten, was du beschrieben hast, kannst aber eben noch
viele andere Sachen machen. Eben weil der Prozessor läuft und nicht
steht.
Ich muß ganz ehrlich sagen, ich habe schon viele Jahre mit Prozessoren
zu tun und hatte bis jetzt noch nie (!) einen Grund, überhaupt einen
Reset-Taster an den Prozessor anzuschließen. Der einzige Grund, warum
der Reset-Pin nicht zu einem normalen Pin umprogrammiert wurde ist der,
daß man den Reset zum Flashen über ISP braucht.
Hi
Warum schaltest du den Controller nicht einfach aus. Dann hopst er dir
auch nicht vom Tisch....
Jetzt mal im ernst . Du willst ein Programm im Resetzustand halten bis
es dir genehm ist, das du es frei gibst? Was soll das ? Normal ist:
Programm starten
alles initialisieren
Programm-Schleife starten
Eingänge abfragen
weitere Inputs holen ( z.B. serielle Daten)
Information bearbeiten
Ausgaben aufbereiten
Ausgabe Freigabe
Ausgänge setzen
weitere Outputs setzen ( z.B. serielle Daten)
und von vorn.
Nichts hält dich doch davon ab, die Ausgaben erst freizugeben, wenn du
ein Bit dafür bereit stellst, egal wo es her kommt. Keíne Ausgabe, kein
gehopse vom Tisch. Und das Programm rennt immer. Warum auch nicht, es
wird ja nicht "verbraucht".
Gruß oldmax
oldmax schrieb:> Warum schaltest du den Controller nicht einfach aus. Dann hopst er dir> auch nicht vom Tisch....> Jetzt mal im ernst . Du willst ein Programm im Resetzustand halten bis> es dir genehm ist, das du es frei gibst? Was soll das ?
Nu mal ganz langsam. ^^ Controller ausschalten geht erstmal gar nicht,
weil ich ihn dann auch nicht mehr programmieren kann. Das Mindeste ist
hier ein start/stopp button. Ich sage ja nicht, dass es unbedingt ein
Schalter am Reset pin sein muss.
Bernd S. schrieb:> Okay, kann man machen... Du merkst, meine Begeisterung hält sich stark> in Grenzen :-)
Mit einem Start/Stop button ist es wohl eleganter gelöst. Werde ich
jetzt auch mal versuchen. :) Was meiner Meinung nach noch für reset pin
spricht: 1) Man spart den start/stop button pin und kann zumindest reset
pin irgendwie noch gebrauchen. ^^
2) So ein Hardware-Schalter ist immer sicherer wie irgendwelche
implementierte software, an der sogar noch irgendwelche Anfänger
rumprogrammieren. ^^ Man muss da aufpassen dass main(), ISR routinen
und so weiter alles sicher mit dem start/stop button abgefangen wird und
also tatsächlich nix mehr läuft usw...
Also Gedanken dieser Art kreisen mir grad im Kopf rum. :D
Ja, das ist richtig und gut, daß du dir darüber Gedanken machst.
Und solche einfachen Sachen wie losfahren und anhalten sollte man schon
programmtechnisch beherrschen. Da gibts eigentlich kaum Fehler zu
machen. Du kannst ja auch nicht alle anderen Programmfehler, die du
eventuell reinprogrammiert hast, dadurch "beseitigen", daß du den
Controller auf Reset ziehst.
Wie ich schon geschrieben hatte, für den Notfall kann man die
Spannungszufuhr unterbrechen. Also wenn z.B. ein Bauelement kaputt ist
und dadurch dein Motor weiterläuft, kannst du ja ruhig die Spannung
abschalten.
In dem Falle würde dir z.B. ein Reset auch nichts nützen, weil das
kaputte Bauteil hinter dem Controller liegt und durch seinen Fehler den
Motor weiter unter Strom hält.
Der Punkt mit dem Programmieren läßt sich ja dadurch umgehen, daß du
programmtechnisch dafür sorgst, daß der Motor nach dem Programmieren
eben nicht sofort anläuft, sonder erst nach einem Tastendruck.
Und wegen den Pins: Du schreibst:
> 1) Man spart den start/stop button pin und kann zumindest reset> pin irgendwie noch gebrauchen. ^^
Das verstehe ich jetzt nicht. Du willst einen anderen Pin einsparen und
dafür den Reset verwenden, weil du dann den Reset für was anderes
verwenden kannst? Denk nochmal über den Satz nach.
Und wenn du einen Mangel an Pins hast und noch einen brauchst, kannst du
auch den Reset-Pin noch als "normalen" Pin schalten (mit Fuses).
Allerdings kannst du dann nicht mehr mit ISP flashen, weil dazu ja der
Reset-Pin gebraucht wird.
Also wenn du das Programm ordentlich schreibst, so daß alles richtig
funktioniert ist das in Ordnung. Und wenn was nicht funktioniert, mußt
du den Fehler im Programm suchen und nicht einen Reset am Controller
machen.
Hardwaremäßig kannst du die Spannung (für den Notaus) entweder ganz
unterbrechen oder nur die Spannung für die Motoransteuerung (z.B.
H-Brücke). Dann fährt er auch nicht mehr, aber der Controller arbeitet
noch und kann auch geflasht werden.
Das "normale" Anhalten und Losfahren macht man aber softwaremäßig. Und
du hattest ja auch schon gesagt, daß du dich in der Richtung bemühen
willst.
Es ist besser so, glaube mir...
Und wenn du dafür dann Hilfe brauchst, kannst doch auch fragen, wo ist
das Problem?
Bernd S. schrieb:> Und wenn du dafür dann Hilfe brauchst, kannst doch auch fragen, wo ist> das Problem?
Nee, Fragen ist kein Problem. Wollte nur das Thema etwas erörtern, um
alle Seiten zu beleuchten. Ich danke dir für deine Hilfe! :)
Ich werde das Ding nun mal programmieren und sollte ich noch Fragen
haben, werde ich mich wieder melden.
Hi
@NN
Warum liest du nur einen kleinen Teil vom Thread ? Der Anfang war doch
nur ein wenig "geblubbert". Laß doch den Controller in seiner Schleife
kreisen und bau eine Freigabe für die Outputs in dein Programm. Was soll
da schiefgehen ?
Gruß oldmax.
Hi!
Also ich habe beides ausprobiert, sowohl Reset button als auch eine
Programmierschleife in main, die den start button abfrägt. Funktioniert
beides gut.
Danke nochmals für eure Hilfe. :)
gruß
NN