Forum: Mikrocontroller und Digitale Elektronik externer Interrupt Problem


von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

Hallo C-Kollegen,

habe ein wahrscheilich simples problem das mich in den wahnsinn treibt.

möchte ein digitales Signal eines Stromzählers(Photovoltaik) per 
externem interrupt int1 einlesen und verwerten und auf GLCD ausgeben.

int1 ist so eingestellt dass er bei high auslöst.

komischerweise löst das ding aber immer irgendwann im low-zustand aus.
also quasi in der nacht!!!(->photovoltaik)
zu meinem größten entsetzen passiert anscheinend immer noch irgendwas 
wenn ich das Signalkabel auf masse lege.
hab jetzt sogar einen pulldown eingebaut war keine große besserung.
signal ist zu 100% top.

hier ein ausschnitt des codes:
//#################################################################
sei();      // Interrupts zulassen (für timer.c wichtig)
MCUCR = 0b00001100;
GICR = 0b10000000  //interrupt1 ein




SIGNAL (SIG_INTERRUPT1)
{
  umdrehungen=umdrehungen+1;
  led_gn_on;      //grüne Led ein
  _delay_ms(5);
  led_gn_off;      //grüne Led aus
}
//###############################################################

mit den umdrehungen wird quasi später weitergerechnet.
wenn ich den interrupt ausschalte (GiCR=0;) dann spinnt er nicht.


naja bitte überlegts euch und versucht mir weiterzuhelfen sonst dreh ich 
noch dodal durch und schmeis die scheise ausm fenster naus!!

danke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> int1 ist so eingestellt dass er bei high auslöst.
> ...
> MCUCR = 0b00001100;

Die Aussage kann man mit den Angaben nur glauben aber nicht 
kontrollieren, weil der µC Typ nicht angegeben ist.

von ozo (Gast)


Lesenswert?

ruhig Brauner!

Für eine gescheite Antwort sind deine Informationen ein bisschen dürfti 
(oder ich hab sie überlesen)
Welcher Controller? Den ganzen Code oder ein Minimalbeispiel, in dem der 
Fehelr noch auftritt, wären auch ganz doll...
Ansonsten frei von der Leber:
warten in der isr? Ernsthaft?
gemeinsame Variable (isr/prog) als volatile deklariert?

von Martink11 M. (Firma: google) (martink11) Flattr this


Angehängte Dateien:

Lesenswert?

hallo

also der controller ist ein atmega16
das mit den registern müsste eigentlich schon stimmen nur vielleicht 
habe ich auch ein weiteres register noch vergessen das weiß ich nicht

ich weis das ich im interrupt warte aber wie soll ich sonst ein 
blinksignal generieren. das ist praktisch das zählersignal des 
stromzählers.

und was ozo damit meint versteh ich nicht:

gemeinsame Variable (isr/prog) als volatile deklariert?

ich möchte euch nur sagen dass ihrs hier mit einem C-anfänger zu tun 
habt.


ps: ich lege mal den gesamten code bei aber nicht erschrecken!!


muss mich entschuldigen aber das macht mich fertig weil das einfach 
schon so lange dauert
trotzdem danke euch !!!!!!

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo nochmal ich

ich habe auch noch wo gelesen dass es einen unterschied macht ob man
ISR   oder   INTERRUPT    oder   SIGNAL   benutzt.

bitte kann mich mal einer aufklären weil so recht versteh ich das nicht.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> ATMEGA16
> MCUCR = 0b00001100;
                 ^
1 Bit (ISC10) stimmt nicht.
Datenblatt Tabelle 34

Tipp: Tue dir und uns einen Gefallen und benutze die symbolischen 
Bitnamen statt der absoluten Werte. Das erleichtert einen eventuellen 
Controllerwechsel und das Debuggen hier im Forum ;-)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Martin K. schrieb:
> hallo nochmal ich
>
> ich habe auch noch wo gelesen dass es einen unterschied macht ob man
> ISR   oder   INTERRUPT    oder   SIGNAL   benutzt.
>
> bitte kann mich mal einer aufklären weil so recht versteh ich das nicht.

http://www.nongnu.org/avr-libc/user-manual/deprecated.html

Kurzfassung

SIGNAL ist veraltet und jetzt durch ISR ersetzt. Die neuen Vektornamen 
findet man hier 
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

INTERRUPT ist ebenfalls veraltet. Es war früher ein Weg, um 
unterbrechbare Interruptroutinen zu schreiben. Leute die sowas wollen, 
sollen andere Wege nutzen. Vermutlich gab es zu viel Schindluder mit dem 
INTERRUPT von Leuten, die INTERRUPT und SIGNAL nicht auseinanderhalten 
konnten.

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo stefan

ich hab aber grade nachgeschaut da steht doch folgendes
-----------------------------------------------------------------------
Table 34. Interrupt 1 Sense Control
ISC11 ISC10   Description
  0     0     The low level of INT1 generates an interrupt request.
  0     1     logical change on INT1 generates an interrupt request.
  1     0     The falling edge of INT1 generates an interrupt request.
  1     1     The rising edge of INT1 generates an interrupt request.
-----------------------------------------------------------------------

> MCUCR = 0b00001100;

also stimmt es doch oder "the rising edge -> die steigende flanke"

tut mir leid wenn ichs jezt nicht auf anhieb kapir!!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sorry habe ich falsch gelesen bzw. im Kopf, dass du bei HIGH => LOW INT1 
willst.

Dann sind es vielleicht prellende Signale. Wo eine Flanke kommt, kommen 
gerne auch Impulsfolgen.

Ein Flanke wird noch gespeichert, wenn zur Laufzeit deiner ISR die 
Interrupts gesperrt sind. Noch weitere gehen verloren. Wenn du dann aus 
der ISR (nach dem in µC Maßstäben ewig langen Blinken) rauskommst, 
schlägt das gespeicherte Interruptereignis zu.

Abhilfe wäre zum Ende der ISR eventuell anstehende Interrupts im INTF1 
Flag zu löschen.

von Robert B. (goldcap) Benutzerseite


Lesenswert?

Hallo,

Stefan meint du möchtest doch bitte symbolische Namen verwendet und 
nicht die bit-orgie manuell angeben.
1. Erspart dass das Suchen im Datenblatt
2. Wenn du einen anderen Controller benutzt funktionierts auch

also:
1
MCUCR = ((1<<ISC11) | (1<<ISC10))
Martin K. schrieb:

> ich hab aber grade nachgeschaut da steht doch folgendes
> -----------------------------------------------------------------------
> Table 34. Interrupt 1 Sense Control
> ISC11 ISC10   Description
>   0     0     The low level of INT1 generates an interrupt request.
>   0     1     logical change on INT1 generates an interrupt request.
>   1     0     The falling edge of INT1 generates an interrupt request.
>   1     1     The rising edge of INT1 generates an interrupt request.
> -----------------------------------------------------------------------
>
>> MCUCR = 0b00001100;
>

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo

hab jetzt mal anstatt "INTERRUPT (INT1_vect)" mal "ISR (INT1_vect)" 
geschrieben und hätte gedacht jetzt hab ichs.
aber nix wars.

dann hab ich auch noch am ende der ISR das FLAG vom INT1 mit "1" 
gelöscht
  "GIFR |= (1<<INTF1);  //interrupt-flag register löschen"
wieda nix!

sobald mein signal eigentlich weg ist kommt so nach circa 5min oder es 
kann auch 30min dauern noch mal ein signal was eigentlich nicht sein 
kann.

hab auch schon mal mein oszi mit "Single-Funktion (Einzelschuss)" 
darangehängt ->>  ergibt dass auf meinem signalkabel kein high mehr 
kommt sonst hätte das oszi ja ausgelöst.

der fehler muss innerhalb des prozessors abspielen ich denke meine 
leitung ist "stabil"

hm...

denkt mal bitte drüber nach ich steh wirklich auf dem schlauch (und der 
wird langsam immer dicker :)  )

danke!!!!!!

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

muss man eigentlich aus nem interrupt wider zurückkehren?

hab im google gefunden da gibt es einen befehl "reti" (return from 
interrupt)

muss man vielleicht so etwas verwenden?
hab ich aber noch in keinem (beispeil)programm gesehen!

hilfe:)

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

servus alle miteinander

sooooo  jetzt erzähl ich euch mal was...

ich habe euch bis jezt verschwiegen das meine kabellänge die 10m marke 
überschreitet.

ich sitze vorm pc und stöbere im netz nach "interrupt selbstauslösung" 
(wie doof) und das kabel liegt am boden.

#############################################################
da geht mein papa am zimmer vorbei und betätigd den lichtschalter....
....zack.....der interrupt löst aus.
#############################################################

dieses dumme kabel fängt irgend eine INDUKTION auf und die lässt mich 
seit jezt schon 5 oder mehr tagen nicht ruhig schlafen.
mist.

na ich kenn jezt wenigstens wieder ein problem mehr in der elektronik.
man lernt nie aus!

danke für eure beiträge
martin!

von Peter D. (peda)


Lesenswert?

Martin K. schrieb:
> möchte ein digitales Signal eines Stromzählers(Photovoltaik) per
> externem interrupt int1 einlesen und verwerten und auf GLCD ausgeben.

Wie lang ist denn das Signal?
Ist es denn nur wenige ns lang, daß es ein externer Interrupt sein muß?

Der externe Interrupt ist sauschnell (50ns), da kann man sich sehr gut 
alle möglichen Störungen einfangen.
Insbesondere, wenn es noch über ne lange Leitung geht.

Je nach Signaldauer muß man entprellen (entstören).
Für Tastenbetätigungen nimmt man deshalb vorzugsweise den Timerinterrupt 
und keinen externen Interrupt.


Peter

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo

du meinst bestimmt diese COUNTER (T0, T1, T2)

das wäre gut aber das hab ich bei der planung der platine verpennt,
hab das ding geätzt und jetzt hängt an allen dreien das Grafikdisplay 
dran.

ich wollte also (oder musste bis jetzt) mit den normalen ext. interrupts 
auskommen.

wie könnte ich denn die leitung abgesehen von einem geschirmten kabel 
noch schützen oder entstören?????

könnte vielleicht ein Netzwerkkabel (LAN) das Problem lösen 
(bessern)????


danke!

von Gast (Gast)


Lesenswert?

Um den Pin über einen Timer einzulesen statt über einen externen 
Interrupt, musst Du an der Platine überhaupt nichts ändern. Die 
Modifikationen betreffen nur die Software.

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo

wie soll denn das gehen per software
etwa mit einem stinknormalen timer wie OC1A oder B

auserdem hab ich den OC2 schon für PWM für Display-Helligkeit
und den OC1 für einen Sekundentakt da ich auf der Platine kein Uhren-IC 
hab musste ich mir die Uhr selbst basteln.

ich hatte, bevor ich den ext. Interrupt benutzte über den OC1B 
gearbeittet.
das ging so dass ich in jeder halben secunde einen prozessorpin 
abgefragt habe aber das war totaler müll das ging nicht gescheit.
das signal kommt maximal so im SEKUNDENTAKT.

aber falls du etwas anderes im sinn hast könntest du mir das erklären?
ich glaube du meinst eine andere möglichkeit als das?

das könnst du nochmal erläutern mit der Software!

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

ach ja das SIGNAL ist nicht so kurz, das hat bestimmt eine länge von 10 
bis 50ms

das wurde weiter oben mal gefragt.

von Karl H. (kbuchegg)


Lesenswert?

Martin K. schrieb:
> hallo
>
> wie soll denn das gehen per software
> etwa mit einem stinknormalen timer wie OC1A oder B

OC hat damit nicht wirklich etwas zu tun.

Du nimmst einen Timer und lässt dir so ca. alle 10ms einen Interrupt 
auslösen. Den wirst du wahrscheinlich sowieso schon haben, da du ja 
schreibst, dass du eine Uhr in Software gebaut hast.

Dein Tastersignal gilt nur dann, wenn es zb. 4 mal hintereinander in 
dieser ISR auf demselben Pegel erwischt wurde.

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

(NB: ob deine ISR alle 10ms oder alle 5ms auslöst, oder gar alle 20ms 
spielt keine allzugroße Rolle)

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

da ich das nicht so schnell kapiere und das jetzt auch nicht 
umprogrammieren will, meine frage:

kann ich das nicht hardwaremäßig lösen (wenig platzbedarf!)

ich dachte da an etwa einen TIEFPASS oder so etwas
der tiefpass verbessert das ganze schon hab ich getestet,
Verbesserung von 8V Spitze-Impuls auf 2V Spitze.

der interrupt löst mir aber immer noch ab und zu aus
so bei einem von 15 lichtschaltvorgängen :)

ich müsste nur eine kleine entstörschaltung zusammenschustern dann wäre 
mein projekt fertig!!

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.