Hallo,
ich möchte gerne eine Treppenlichtsteuerung mit dem Pic 16F887
programmieren.
Ein Teil eines Programms habe ich fertiggestellt, doch nun kommen
Probleme die ich leider nicht mehr lösen kann ich bitte daher um Hilfe
=D.
Das Programm soll einzelnde LED's ansteuern die unter den Treppenstufen
angebracht sind. Diese sollen mit einer Lichtschranke eingeschaltet
werden und dann Treppenstufe für Treppenstufe hochdimmen.
Meine Frage ist nun wie binde ich eine Tabelle mit verschiedenen Werten
in das Programm ein, dass die LED unterschiedlich angesteuert.
Außerdem habe ich noch ein weiteres Problem und zwar muss man die Taste
gedrückt halten das die LED's hochdimme ich weiß leider nicht wie er
dies mit nur einem Tastendruck macht und sie dann automatisch
hochdimmen.
Es wäre sehr freundlich wenn mir jemand bei meinem Problem helfen kann
Im Anhang befindet sich das Programm
MfG Dennis
Dein Problem ist, daß Dein Programm einfach an einer Stelle anhält.
Für Ablaufsteuerungen nimmt man daher Statemachines, die ständig
durchlaufen werden und nirgends anhalten.
Und ist mal nichts zu tun, ändern sie einfach nur ihren State nicht.
Aber sämtliche Abfragen, die den State ändern könnten, laufen weiter.
Das "return" am Ende des Unterprogrammes Bereich ist mir schon
aufgefallen,
ändert aber nichts am Problem.
Mit dem Begriff Statemachine kann ich leider nichts anfangen hab ich so
auch noch nie benutzt und durch google werde ich auch nicht schlauer
MfG Dennis
Dennis Hoppen schrieb:> Außerdem habe ich noch ein weiteres Problem und zwar muss man die Taste> gedrückt halten das die LED's hochdimme ich weiß leider nicht wie er> dies mit nur einem Tastendruck macht und sie dann automatisch> hochdimmen.
Wenn ich dich richtig verstehe, musst du mit dem Drücken des Tasters
eine flag setzen. Dann dimmt alles hoch und wenn alles hochgedimmt ist,
wird die flag zurückgesetzt.
Danke erstmal für die schnellen und hilfreichen Antworten.
Max B. schrieb:> Wenn ich dich richtig verstehe, musst du mit dem Drücken des Tasters> eine flag setzen. Dann dimmt alles hoch und wenn alles hochgedimmt ist,> wird die flag zurückgesetzt.> int dimmen = 0;> ***Taster wird gedrückt***> dimmen = 1;> ***wenn hochgedimmt***> dimmen = 0;
kann man dies so in Assembler übernehmen, da ich dies nur von C kenne.
Dennis Hoppen schrieb:> Danke erstmal für die schnellen und hilfreichen Antworten.>> Max B. schrieb:>> Wenn ich dich richtig verstehe, musst du mit dem Drücken des Tasters>> eine flag setzen. Dann dimmt alles hoch und wenn alles hochgedimmt ist,>> wird die flag zurückgesetzt.>> int dimmen = 0;>> ***Taster wird gedrückt***>> dimmen = 1;>> ***wenn hochgedimmt***>> dimmen = 0;>> kann man dies so in Assembler übernehmen, da ich dies nur von C kenne.
Natürlich kannst du das in Assembler dem Prinzip nach genauso machen.
Ob Du jetzt in C schreibst oder in Assembler - Speicherzelle ist
Speicherzelle. Schreibst du einen Wert rein, dann behält sie den Wert
und der kann wieder geladen und abgefragt werden.
Häng dich nicht an der Syntax auf. Es geht um Prinzipien, unabhängig
davon wie die dann in der konkreten Programmiersprache formuliert
werden.
Wird eine Taste gedrückt, dann wird ein 'Flag' auf einen bestimmten Wert
gesetzt. In der zentralen Hauptschleife wird dieses Flag wieder
abgefragt und wenn es auf 'hochdimmen' steht, dann wird eben pro
Zeiteinheit der Dimmgrad deiner LED um zum Beispiel 1 erhöht. Oder dann
eben beim Drücken auf die andere Taste wird der Dimmgrad um 1
verringert.
Hier
1
Loop movf PORTA ;Hauptschleife
2
btfsc STATUS,Z ;Taste gedrückt?
3
goto Loop
ist deine zentrale Schleife.
Eine Möglichkeit ist es eben, die zu erweitern. Nach dem Muster
1
Loop
2
Ist eine Taste gedrückt?
3
Wenn ja -> Tastenasuwertung
4
5
steht das Flag (der Status) auf hochdimmen
6
Wenn ja -> Dimmgrad erhöhen
7
8
steht das Flag (der Status) auf runterdimmen
9
Wenn ja -> Dimmgrad erniedrigen
10
11
goto Loop
Ein Problem stellt natürlich dar, dass dieses Dimmen hier in einem
Affenzahn durchgeführt wird. Denn bis diese Schleife von 0 auf maximum
gedimmt hat, vergehen gerade mal ein paar µs. Da wirst du dir zum Thema
Zeitsteuerung etwas einfallen lassen müssen.
Dennis Hoppen schrieb:> kann man dies so in Assembler übernehmen, da ich dies nur von C kenne.
Karl Heinz hat es schon beantwortet.
Karl Heinz schrieb:> Natürlich kannst du das in Assembler dem Prinzip nach genauso machen.
Assembler habe ich mal programmieren (müssen), aber nur ganz wenig.
Daher mein Beispiel in C :)
Gruß Max
Karl Heinz schrieb:> gedimmt hat, vergehen gerade mal ein paar µs. Da wirst du dir zum Thema> Zeitsteuerung etwas einfallen lassen müssen.
Eine Möglichkeit dafür ist zb folgende Vorgehensweise:
Du legst das eigentliche Dimmen in deine sowieso schon vorhandene
Timer-getrieben Software-PWM mit rein. Denn da hast du ja bereits eine
Zeitsteuerung: Die Interrupt Routine wird in regelmässigen Zeitabständen
aufgerufen, auf die du dich auch verlassen kannst.
Du wandelst das Prinzip wie folgt um:
Mit den Tasten wird nicht mehr der tatsächliche Dimmgrad der LED
eingestellt, sondern ein Vorgabewert. D.h. wenn du zb auch 'Hochdimmen'
drückst, dann wird dieser Vorgabewert zb auf 255 gesetzt.
Das bedeutet NICHT, dass der tatsächliche Dimmgrad, der zur Anwendung
kommt, auch 255 ist. Der tatsächliche Dimmgrad wird nach wie vor mit
ihrem eigenen Wert über die Software-PWM realisiert. Aber: in der
Interrupt Routine wird dieser tatsächliche Wert mit der Vorgabe
verglichen. Ist er kleiner, dann wird der tatsächliche Wert erhöht, ist
er größer, dann wird er verringert. Das führt, über mehrere (viele)
Aufrufe der Interrupt Routine dazu, dass dieser tatsächliche PWM-Wert
langsam und in Schritten auf den Vorgabewert nachgeführt wird.
Eine eigene Frage?
Dieser Thread ist über 12 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.