Ausgang bei Pegeländerung am Eingang ändern

#2208769
Lesenswert?

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.
#2209036
Lesenswert?

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.
#2209053
Lesenswert?

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
Gast #2209113
Lesenswert?

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...
#2209137
Lesenswert?

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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren