Hallo Ich will mit CodeVision ein Proramm schreiben welches immer Daten von der Seriellen Schnittstelle einliest und dabei den Programmablauf nicht beeinflusst. getchar() lässt das Programm warten und is daher unbrauchbar. Kann mir jemand den Umgang mit Interupts erklären. Den Quellcode den CodeVision erzeugt kappier ich nicht. Gibt es keine Einfachere Lösung nur zum Empfangen per Interrupt? Mfg DarkMarine
verwende doch den CodeWizard, bei Uart Receiver und Rx interrupt anmarkern, dazu noch eine Rx-Buffergrösse wählen, je nach Bedarf. Ankommende Zeichen werden in den Buffer geschrieben, davon merkst du nicht viel. Im Programm dann kannst du prüfen, ob rx_counter>0, wenn ja, einfach mit getchar Byte aus dem Buffer abholen.
na ja, manchmal lohnt es sich schon, die gesamte Hilfe durchzulesen, damit man mal weiß, welche Möglichkeiten man hat :-)
Ok das mit dem Interupt funktioniert aber ganz das wahre ist es nicht. Folgendes Problem: Ich schreibe ein Regelungsprogramm das nicht unterbrochen werden darf. Wenn jetzt ein Interupt kommt wird mein Programm unterbrochen und die Zeit des Regelungsprogrammes verändert sich was sich negativ auswirkt. Hat das Stk500/ATMega163 einen "Zwischenspeicher" der Daten, die ich nicht sofort abfragen kann, speichert sodass sie nicht verloren gehen?
schieb Es ist wirklich wichtig weiß wirklich keiner wie ich das lösen kann?
Hi, Also wenn Du einen Regler mit genauen Abtastmomenten benötigst, dann solltest Du das über einen Timer-Interrupt machen. Das ist in meinen Augen die sicherste Lösung. Eine andere Idee ist die Verarbeitung des UART in der Hauptschleife. Wenn ein Zeichen da ist, dann verarbeite das. Wenn keins da ist, dann mache solange NOPs, wie Deine Verarbeitungsroutine lang ist. Was ist eigentlich dieses Codevision? mfg, Stefan.
glaub ich im Leben nicht, dass dein Programm so zeitintensiv ist, dass es nicht unterbrochen werden darf - und wenn doch, also 100% Auslastung (und nur das wäre ein Grund "welches nicht unterbrochen werden darf"), hast du im Entwurf was falsch gemacht, also falschen Prozessor oder zumindest zu niedrigen Takt. Der STK500 macht/hat überhaupt nichts, ist eine dumme Platine, die verschiedene AVRs mit Takt und Strom versorgen kann, ein paar Taster, ein paar Leds, und als wichtigstes, den eingesetzten Prozessor programmieren kann. Damit erschöpfen sich die Möglichkeiten auch schon fast. Prinzipiell ist kein AVR in der Lage, mehrere Prozesse wirklich parallel zu verarbeiten, das funktioniert nur durch timesharing, verschiedenen Prozessen wird Prozessorzeit zugeteilt, entweder feste Zeitscheiben oder Ereignisgesteuert. Gehts an die Grenze der Prozessorleistung, ist diese Verteilung durchaus nicht mehr trivial, aber wie gesagt, meiner Meinung nach bist du meilenweit davon entfernt. Und ich verstehe dein Problem auch nicht wirklich, vielleicht wäre mal das Programm mit ein paar Anmerkungen, wo deiner Meinung nach Probleme auftauchen, sehr sinnvoll. Ich jedenfalls habe keine Lust, weiter im Dunkeln zu tauchen.
Ich glaube da verstehst Du was falsch. Für eine zeitdiskrete Regelung (bei digitalen Regelungen immer der Fall) ist es wichtig, daß die Abtastzeit konstant ist. Das sind sie nicht, wenn der Regler an zufälligen Zeitpunkten von einem Interrupt unterbrochen wird. Deshalb mein Vorschlag, die Regelung in einen Timer-Interrupt zu verlagern. Damit hast du eine konstante Abtastzeit und kannst im Hauptprogramm noch andere Sachen machen. Wenn ich es richtig verstehe, sollen Reglerparameter über UART gesetzt werden. Das sollte sogar ohne Hauptprogramm auskommen. Den Regler also in den Timer-Interrupt, das Verarbeiten und setzen der Parameter in den UART Rx Interrupt. Ist fast wie mehrere Prozesse. :-) mfg, Stefan.
@May stimmt alles was du geschrieben hast! Die Abtastung muss immer konstant sein und darf deshalb nicht unterbrochen werden. Das Regelungsprogramm steht in der Timer0 Overflow routine. Und die Regelparamter sollen über die RS232 übertragen werden. Nur zu meinem Verständniss: Kann der Timer0 Overflow interupt eigentlich durch einen anderen Interupt unterbrochen werden?. Ich füge mal den Aktuellen Quellcode ein. Zum Quellcode: Das was zur Zeit im Main Programm steht soll nicht mehr durch Taster auswählbar sein sondern eben per PC-Steuerbar. Diesen Teil möchte ich ersetzen. Dafür habe nehme ich die (vorgeferitgte) Interupt Routine von CodeVision zum Empfangen von Daten.(noch nicht integriert) Wenn der Timer0 Overflow ausgelöst wird sprich das Regelungsprogramm läuft darf es eben nicht mehr durch einen anderen Interupt gestört werden. -->Genau da liegt mein Problem: Wenn ich während dessen Daten sende unterbricht der RX-Interupt mein Programm und der Regler funktioniert nicht mehr einwandfrei. Zum Regler: Ich bin gerade beschäftigt ein Inverses Pendel zu bauen. Der uP soll einen Motor ansteuern der das Pendel dann ausbalciert sodass es nach oben steht. Hoffe das waren genug Infos um mein Progblem zu verstehen. CodeVision ist ein C-Compiler. Mfg und danke für eure bisherige Hilfe DarkMarine
Timer0 Overflow kann durch einen externen Interrupt, Reset und Watchdog unterbrochen werden. Den externen Interrupt kann man unterdrücken, ebenso den Watchdog. Reset ist aber unmöglich abzuschalten. :-) Aber jetzt wird das Problem klar. Die Lösung habe ich schon weiter oben skizziert. Die Regelung kommt in den Timer0 Interrupt rein, im UART Rx Interrupt werden die Reglerparameter gesetzt. Main besteht dann nur aus einer Endlosschleife, die einen Sleep enthalten kann. Achtung: Keinen Powerdown! Dann wacht der Controller nicht mehr auf. Du mußt folgendes beachten: Der Rx Interrupt sollte jederzeit durch Deinen Regler unterbrochen werden können. Wichtig ist dann, daß Du das überschreiben der Parameter dann lockst. Also so: cli(); parameter = neuerparameter; sei(); Ich bin mir jetzt nicht sicher, ob mit Eintritt der Interrupt-Routine alle Interrupts ausgeschaltet werden. Wenn ja, dann solltest Du den in Rx wieder einschalten, da Timer0 sonst nicht aktiv wird. Viel Spaß mit dem inversen Pendel. Ich habe das auch mal gemacht, allerdings mit Matlab und einem PC. Was Dir noch fehlt, ist die Normierung des Reglers. Du benutzt im Moment float, was Du unbedingt auf integer (am besten 8 Bit) umstellen solltest. Du kannst die Abtastzeit dann verringern, was die Ungenauigkeit der 8 Bit wieder ausgleicht. Für mehr Kommentare ist es jetzt schon zu spät. :-) Schreib mal, wie es weitergeht. mfg, Stefan.
Für mehr Kommentare ist es nie zu spät ich bin gerade erst am Anfang! Ich muss das Programm nämlich verbessern. Zur Zeit ist geplant die AD-Wandlung nicht mehr vom uP erledigen zu lassen sondern über einen Externen AD-Wandler. Mal schauen was ich noch verändern muss/kann. Thx für deine bisherige Hilfe! Mfg DarkMarine
Ich meinte mit spät eher die Zeit. Den Beitrag habe ich um 2:30 Uhr geschrieben.:-) Warum willst Du die Wandlung extern machen? Ist der interne A/D-Wandler nicht genau genug? Ich sehe einen externen Wandler eher als Nachteil. An Deiner Stelle würde ich den Regleralgorithmus noch verbessern. Die Berechnung der Stellgröße als float ist unnötig und belastet den Prozessor zu stark. Wie gesagt: Normiere Deine Reglerparameter und Du kannst mit 8 bit Integer (signed char) weiterrechnen. Ein bisschen Kritik noch am Schluß: Du solltest Deinen Regler VORHER! sorgfältig planen. Also wie man es in der Schule lernt: 1.) Modell bilden 2.) Das ganze normieren 3.) Reglerparameter berechnen Danach kommt erst die Implementation. Das ist eigentlich der einfachste Teil. Wenn es dann nicht funktioniert, dann ist was an Deinem Modell oder Deinen Reglerparametern faul. Es ist auch nicht verkehrt, das ganze vorher zu simulieren. Machst Du das ganze just for fun oder als Studienarbeit? Uni? Schule? mfg, Stefan. P.S. Eventuelle Unterstellungen bitte nicht persönlich nehmen. Ich spreche nur aus eigener Erfahrung, und da setzt man sich gerne erst mal an den Rechner und programmiert drauf los.
Und noch ein Link: http://www.cis.tugraz.at/regis/Welcome.html Dort wird ein inverses Pendel beschrieben, inkl. Java-Applet, ein paar Beispielfilmen und ein bisschen Systemtheorie. Könnte vielleicht ganz brauchbar sein. mfg, Stefan.
g aso verstehe. Zur Zeit wird das Winkelsignal über eine längere Strecke übertragen (~2m). Das Signal wird also durch Störungen (Motor,...) beeinflusst. Deshalb wird das Signal vorher Umgewandelt und anschliesend als digitales Signal übertragen. Die Stellgröße ist als Int definert. Ich verstehe auch nicht ganz was du mit Normierung meinst. Das gesammte Timing der Regelung wird als nächstes überarbeitet. Das ganze mache ich im Ramen einer Diplomarbeit an der HTL. (Weiterentwicklung) Wieso kenns du dich so gut in der Regelungstechnik aus? Eigeninteresse oder? Thx Mfg Michael
Hallo Michael, Ich habe Technische Informatik studiert. Da war Regelungstechnik eines der Hauptfächer. Folgendes zur Normierung: /* --- Positionswerte in Meter --- */ poswert[3] = pos()*(0.11/2000.0); // 11cm bei 2000 Pulsen Am Kommentar kannst Du schon erkennen, daß Du in der Einheit Meter rechnest. Wozu? Mein Regleungstechniksckript sagt dazu: "Um die folgenden Berechnungen nicht unnötig zu belasten, werden die Variablen, z.B. Druck, Füllstand, Weg, normiert, d.h. dimensionsfrei gemacht. Hierzu werden die Variablen auf ihre Nennwerte bzw. Maxmimalwerte bezogen. Beispiel Füllstandsregelung: Die Variable h kennzeichnet den Füllstand, der im Bereich 0<=h<=5m schwanken kann. Der maximale Füllstand hmax beträgt somit 5m. Die normierte Variable h* errechnet sich aus: h*(t) = h(t) / hmax." Auf Deine Anwendung bezogen: Du willst 2 Sachen Regeln. Zum einen die Position des Pendels. Diese Größe hast Du schon "normiert", indem Du mit der Anzahl der Pulse rechnest. Die andere Größe ist der Winkel. Diesen hast Du ebenfalls schon "normiert", indem Du einfach den ADC-Wert nimmst. Was ist eigentlich schon fertig und worauf baust Du Deine Diplomarbeit auf? Was ist denn Deine genaue Aufgabe? mfg, Stefan.
Hallo, Das Pendel ist schon fertig und funktioniert, ich noch jemand sollen es verbesserb. Meine Aufgabe: Steuerung über PC ermöglichen AD-Wandlung des Winkelsignals Verbesserung des Regelalgorithmus Programmieren eines Beobachters: Falls durch Störungen falsche Werte ausgegeben werden soll der Beobachter diese korrigieren. Das wären die Hauptaufgaben. Mit dem Regelaungsalgorithmus habe ich mich (wie du wahrscheinlich schon bemerkt hast ) noch fast gar nicht auseinandergesetzt. Bis jetzt habe ich an einem C++ Programm für Windows gearbeitet mit dem ich das Pendel steurn kann. Jetzt muss ich mich einmal in den Regelungs Code einarbeiten den ich vom Vorjahr übernommen habe. Bin für jede Hilfe sehr dankbar. Mfg Michael
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.