Ich möchte am Ausgang einen fix definierten Zustand ausgeben (LO), der allerdings geändert werden soll, wenn an einem bestimmten Eingang eine Pegeländerung stattgefunden hat. Also wenn beim Einschalten der Eingang HI oder LO ist soll am Ausgang ein LOW ausgegeben werden. Ändert sich jedoch der Eingang entweder auf LO oder auf HI, je nachdem was vorher war, soll am Ausgang ein HI ausgegeben werden, sollange sich der Pegel am Eingang nicht ändert. Das ganze in C für einen ATMEGA.
Ja und? Eingangszustand merken, wenn veraendert, dann Ausgang auf High setzen. citb
Ja, soweit war ich auch schon. Nur wo merken? Wenn ich das ganze in den Timer Interrupt schmeiße wird der gemerkte Zustand ja ständig überschrieben. Gleichzeitig muß ich ja permanent den Zustand abfragen. Wie mach ich das?
Ja, warum sollte es in Assembler nicht gehen? Wenn, dann dort sowieso.
Also, niemand einen Tip für mich? Es geht ja nicht nur um den Einschaltzustand, sondern immer dann wenn sich das Bit ändert.
Also ich habs jetzt mal so versucht:
1 | if(LICHT_EIN != lichtval) |
2 | {
|
3 | lichtCount = 25; // LICHTAUSGANG für 150ms auf HI |
4 | lichtval = LICHT_EIN; |
5 | }
|
Läuft aber nicht so ganz. Ausgang bleibt ständig auf HI, obwohl die Variable lichtval gleich LICHT_EIN gesetzt wird.
1 | #define SCHALTER_PORT PORTD
|
2 | #define WRITE 0x10
|
3 | #define LICHT_EIN (PINC & 1 << PC3)
|
4 | |
5 | static int16_t lichtCount = 0; |
6 | static int8_t lichtval; |
7 | |
8 | ISR(TIMER0_OVF_vect) |
9 | {
|
10 | if(lichtCount > 0) |
11 | {
|
12 | SCHALTER_PORT |= (WRITE); |
13 | lichtCount--; |
14 | if(lichtCount == 0) |
15 | lichtval = LICHT_EIN; |
16 | }
|
17 | |
18 | if(LICHT_EIN != lichtval) |
19 | {
|
20 | lichtCount = 25; // LICHTAUSGANG für 150ms auf HI |
21 | }
|
22 | if(LICHT_EIN == lichtval) |
23 | {
|
24 | SCHALTER_PORT &= ~(WRITE); // LICHTAUSGANG = LOW |
25 | }
|
26 | }
|
Also im Normalzustand soll der Ausgang immer auf LO sein. Nur bei einem Flankenwechsel soll er für 150ms auf HI gehen.
Hi, is zwar Assembler für'n Pic aber vielleicht hilft's Dir ja auf die Sprünge :) Steht so bei mir in der Interruptroutine.
1 | Sekunde BCF INTCON,T0IF ; alle 1/125 Sec. |
2 | bcf Sec_Flag |
3 | btfsc DCF_Port |
4 | goto DCFPortHI |
5 | goto DCFPortLO |
6 | DCFPortHI
|
7 | btfsc DCF_Port_Flag |
8 | goto DCFPortEND ; DCF_PORT war Hi |
9 | bsf DCF_Rise_Flag ; DCF_PORT ist Hi geworden |
10 | bsf DCF_Port_Flag |
11 | goto DCFPortEND |
12 | DCFPortLO
|
13 | btfss DCF_Port_Flag |
14 | goto DCFPortEND ; DCF_PORT war bereits Lo |
15 | bsf DCF_Sink_Flag ; DCF_PORT ist Lo geworden |
16 | bcf DCF_Port_Flag |
17 | DCFPortEND
|
18 | incf DCF_Timer |
19 | DECFSZ Clock125 |
20 | goto INT_END |
21 | MOVLW D'125' |
22 | MOVWF Clock125 |
23 | bsf Sec_Flag |
Leider, damit fang ich gar nichts an. Aber ich hab noch einen Fehler entdeckt. Das SCHALTER_PORT |= (WRITE); gehört natürlich noch weg. Funkt aber immer noch nicht. Bleibt immer auf LO der Ausgang.
Manfred W. schrieb: > Leider, damit fang ich gar nichts an. Du benötigst eine Hilfs-Var. wo Du Dir merkst was für ein zustand beim letzten Test am Port war, um entscheiden zu können ob ein Pegel Wechsel stattgefunden hat!
Ja, in meinem Fall die "lichtval" Diese wird mit dem aktuellen Zustand gefüttert.
Hmm, könnte es vielleicht an der zweiten If-Abfrage liegen. Angenommen Du erkennst "LICHT_EIN != lichtval" und setzt den counter auf 25. Im nächsten durchlauf wird counter zwar um eins runtergezählt, es gilt jedoch weiterhin "LICHT_EIN != lichtval", weshalb die If-Abfrage den counter wieder auf 25 setzt (und so weiter und sofort...). Wie gesagt möglicherweise, eventuell, vielleicht (ich bin nicht wirklich in der Materie verhaftet) :-) Nur so als idee...
Du hast recht. Abgesehen davon gehört das:
1 | SCHALTER_PORT |= (WRITE); |
doch rein. Sonst geht der Ausgang ja nie auf HI. So läufts nun:
1 | #define SCHALTER_PORT PORTD
|
2 | #define WRITE 0x10
|
3 | #define LICHT_EIN (PINC & 1 << PC3)
|
4 | |
5 | static int16_t lichtCount = 0; |
6 | static int8_t lichtval; |
7 | |
8 | ISR(TIMER0_OVF_vect) |
9 | {
|
10 | if(lichtCount > 0) |
11 | {
|
12 | SCHALTER_PORT |= (WRITE); |
13 | lichtCount--; |
14 | if(lichtCount == 0) |
15 | lichtval = LICHT_EIN; |
16 | }
|
17 | |
18 | if((LICHT_EIN != lichtval) && (lichtCount == 0)) |
19 | lichtCount = 25; // LICHTAUSGANG für 150ms auf HI |
20 | if(LICHT_EIN == lichtval) |
21 | SCHALTER_PORT &= ~(WRITE); // LICHTAUSGANG = LOW |
22 | }
|
Danke dir für den Hinweis!
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.