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!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> 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.
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?
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 !!!!!!
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.
> 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 ;-)
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.
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!!
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.
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; >
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!!!!!!
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:)
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!
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
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!
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.
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!
ach ja das SIGNAL ist nicht so kurz, das hat bestimmt eine länge von 10 bis 50ms das wurde weiter oben mal gefragt.
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.