Forum: Mikrocontroller und Digitale Elektronik erkenne das problemm nicht beim interrupt INT0 bzw INT1!


von Kaveh D. (kaveh)


Lesenswert?

hallo erstmal,
ich habe eine kleine steuerung mit einem ATmega32 realisiert, mit dem 
ich ein Relias ansteuere, das wiederrum ein 230v ventil ansteuert.
das Ventil soll über zwei wege angesteuert werden.
1-
automatisch: es sind zwei schwimmerschalter, die in einem wassertank 
angebracht sind. der erste schalter schaltet das Relias ein und der 
zweite schalter schaltet dies wieder aus (Ausgang PORTD,6).
2-
Manuel: dies bedeutet das Relias über einen taster (S1) einzuschalten 
bzw über einen zweiten taster (S2) wieder auszuschalten. obwohl PORTd,6 
über den zweiten schwimmerschalter im Automatikbetrieb ausgeschaltet 
ist. und da liegt mein problemm.
ich habe den manuelbetrieb über INT0 für einschalten und INT1 für das 
ausschalten realisiert und es funktioniert nur einmal. das heißt, ich 
kann PORTD,6 mit taster S1 einschalten und mit Taster S2 wieder 
ausschalten, aber dann reagiert das programm nicht mehr und es kann 
nicht mehr manuel wieder eingeschaltet werden. die tastern sind 
wirkungslos. es sei denn ich übertrage den programmcode erneut in den 
controller und kann es nur einmal einschalten und das problemm taucht 
wieder ein. da möchte ich euch zur hilfe bieten.
danke kaveh


.include"m32def.inc"
rjmp     main

.org INT0addr     ;Interrupt0 INT0 INT1
rjmp INT0_einschalten  ;manuele ein bzw ausschalten vom Ventil 1 über 
Interrupt
.org INT1addr
rjmp INT1_ausschalten

.def  temp=r16

main:
ldi    temp,high(ramend)
out    sph,temp
ldi    temp,low(ramend)
out    spl,temp
;interrupts
ldi    temp,0b11000000
out    GICR,temp
ldi    temp,0b00001010;Interrupt auf fallende Flanke auslösen
out    MCUCR,temp
sei             ;Interrupt erlauben
;eingänge
cbi    DDRC,6      ; SW2 als Eingang konfig.
sbi    PORTC,6     ; Pull-Up widerstand.

cbi    DDRC,5      ; SW3 als Eingang konfig.
sbi    PORTC,5      ; Pull-Up widerstand.
;ausgänge
sbi    DDRD,6      ; Relais-1 als Ausgng konfig.

mainloop:
;--------Automatik
sbic    pinc,6
sbi     portd,6
sbic    pinc,5
cbi     portd,6
rjmp    mainloop

;-----------------------------Manuel
INT0_einschalten:
push    temp
in     r18,SREG
rcall          Ventil_1M
out    SREG,r18
pop    temp
reti

ventil_On:
push    temp
in    r18,SREG

Loop1M: sbi  PORTD,6
        sbic  PIND,3
        rjmp  Loop1M
        out  SREG,r18
        pop  temp
        ret

INT1_ausschalten:
    push  temp
    in  r18,SREG
    cbi  PORTD,6
    out  SREG,r18
      pop temp
    reti

von Karl H. (kbuchegg)


Lesenswert?

> rcall          Ventil_1M

Ich vermisse das Label Ventil_1M und den Code der da dazugehört.

von Karl H. (kbuchegg)


Lesenswert?

Und ich frag mich warum du da für die Taster INterrupts nimmst. Sieh 
doch deine Taster als ganz normale Eingänge an, so wie es die 
Schwimmschalter auch sind, und pack den Code dafür in die main-Schleife.

Deine mainloop wird in weniger als 15µs einmal durchlaufen. Kein Mensch 
kann einen Taster derartig schnell drücken und wieder loslassen, als das 
du dieses Ereigniss im Programm verpassen würdest.

Als Faustregel: Alles was dein Benutzer mit Tastern oder sonstige 
Eingabegeräte macht, ist für einen µC extreme Zeitlupe! In dem Zeitraum, 
den du als Mensch einmal zum blinzeln brauchst, löst dein µC viele viele 
quadratische Gleichungen.

von Karl H. (kbuchegg)


Lesenswert?

> 1-
> automatisch: es sind zwei schwimmerschalter, die in einem wassertank
> angebracht sind. der erste schalter schaltet das Relias ein und der
> zweite schalter schaltet dies wieder aus (Ausgang PORTD,6).
>
> 2-
> Manuel: dies bedeutet das Relias über einen taster (S1) einzuschalten
> bzw über einen zweiten taster (S2) wieder auszuschalten.

Und der interesante Fall entsteht dann, wenn der SChwimmschalter ein 
sagt und der Mensch aus. Bzw. umgekehrt: der Mensch ein sagt aber der 
SChwimmschalter aus.

von Kaveh D. (kaveh)


Lesenswert?

oh entschuldiege ich muss mich hier korrigieren,
richtig ist so:

INT0_einschalten:
push           temp
in             r18,SREG
rcall          ventil_On
out            SREG,r18
pop            temp
reti

ventil_On:     push       temp
               in      r18,SREG
Loop1M:        sbi  PORTD,6
               sbi  PORTA,0
               sbic  PIND,3
               rjmp  Loop1M
               out  SREG,r18
               pop  temp
               ret

INT1_ausschalten:
              push  temp
              in  r18,SREG
              cbi  PORTD,6
              cbi  PORTA,0
              out  SREG,r18
              pop temp
              reti

von Karl H. (kbuchegg)


Lesenswert?

Wie gesagt:
Nimm die Taster-Logik mit in die mainloop.
Einen µC im Interrupt in einer Schleife festhalten macht man sowieso 
nicht.

von Kaveh D. (kaveh)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wie gesagt:
> Nimm die Taster-Logik mit in die mainloop.
danke für den Tipp. ich habe es mit einem unterprogramm in mainloop 
realisiert und es funktioniert.

> Einen µC im Interrupt in einer Schleife festhalten macht man sowieso
> nicht.
da hast Du Recht, in dem fall sollte man den Finger vom Interrupt 
lassen.
in dem sinne
einen schönen Tag

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
Noch kein Account? Hier anmelden.