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 betrifft zwar nicht direkt Deine Frage, aber: Falsch (es fehlt ein "return" am Ende):
1 | Bereich movlw 0xFF |
2 | ... |
3 | goto ist_Max |
4 | return |
5 | ist_Null incf Dimmer,F |
6 | return |
7 | ist_Max decf Dimmer,F |
Richtig ("goto ist_Max" ist hier unnötig):
1 | Bereich movlw 0xFF |
2 | ... |
3 | decf Dimmer,F |
4 | return |
5 | ist_Null incf Dimmer,F |
6 | return |
Gruß Dietrich
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: > Mit dem Begriff Statemachine kann ich leider nichts anfangen hab ich so > auch noch nie benutzt und durch google werde ich auch nicht schlauer http://www.mikrocontroller.net/articles/Statemachine
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.
1 | int dimmen = 0; |
2 | ***Taster wird gedrückt*** |
3 | dimmen = 1; |
4 | ***wenn hochgedimmt*** |
5 | dimmen = 0; |
Gruß Max
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.
1 | Interrupt Routine: |
2 | |
3 | ... Software-PWM basierend auf 'Dimmer' |
4 | |
5 | wenn 'Dimmer' kleiner als 'Dimmer_Vorgabe' |
6 | inkrementiere 'Dimmer' |
7 | |
8 | wenn 'Dimmer' größer als 'Dimmer_Vorgabe' |
9 | dekrementiere 'Dimmer' |
10 | |
11 | .. |
12 | return |
13 | |
14 | |
15 | |
16 | .... |
17 | Taste_Aufdimmen: |
18 | setze 'Dimmer_Vorgabe' auf 255 |
19 | return |
20 | |
21 | Taste_Abdimmen: |
22 | setze 'Dimmer_Vorgabe' auf 0 |
23 | return |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.