Hallo liebe Gemeinde,
Ich beschäftige mich gerade mit einem Demoprogramm (compact-c) mit dem
compiler IDE für ein Projectboard MEGA32.
Ich würde gerne auch schon antworten auf ein paar Frage geben, aber ich
bin noch unerfahren im uC-Bereich.
Bei folgendem Code hab ich schon zwei Fragen:
Wenn von einem Programm(z.B. Matlab) über die serielle Schnittstelle zum
Zeitpunkt X ein Byte geschrieben wird, heisst das dann, das der
Interrupt wieder neu bei der Funktion "Serial_Init_IRQ" beginnt, oder
woher weiss ich wenn die Sache im Interrupt modus arbeitet, ab welcher
Aktion der code wieder abgearbeitet wird.
Vielen Dank für eure Hilfe
gruss Luiz
1 | #define PORT 0
| 2 | //oimaul defina, dann isch s guat
| 3 |
| 4 | // 35 bytes send + receive buffer + 6 bytes internal FIFO management
| 5 | byte buffer[41]; // Array declaration
| 6 |
| 7 |
| 8 | //------------------------------------------------------------------------------
| 9 | // Main program
| 10 | //
| 11 | void main(void)
| 12 | {
| 13 | char Text1[40]; // Arrays declaration
| 14 | char output[40];
| 15 | byte count;
| 16 | int sz;
| 17 |
| 18 | Text1="Test Text\r\n";
| 19 |
| 20 | //Initialize RS232: 19200 bps, 8 Bit, 1 Stop, NP
| 21 | // 20 bytes receive buffer - 15 bytes send buffer
| 22 | Serial_Init_IRQ(PORT,buffer,20,15,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);
| 23 |
| 24 | Serial_Write(PORT,'\r'); // control character for carriage return is sent via RS232 interface
| 25 | Serial_Write(PORT,'\n'); // control character for line feed is sent via RS232 interface
| 26 | Serial_WriteText(PORT,Text1); // output text via RS232 interface
| 27 |
| 28 |
| 29 | AbsDelay(10000); // 10 seconds waiting time
| 30 | // Until receive buffer is full, all received data are buffered
| 31 |
| 32 |
| 33 | count=Serial_IRQ_Info(PORT,RS232_FIFO_RECV); // Investigates, how many characters have been received
| 34 |
| 35 | Msg_WriteWord(count); // The number of characters is displayed as message
| 36 | output=" Characters received by IRQ\r";
| 37 | Msg_WriteText(output);
| 38 |
| 39 | while(true)
| 40 | {
| 41 | sz=Serial_ReadExt(PORT); // Get value out of receive buffer
| 42 | if(sz==0x100) break; // If the value is 0x100, the receive buffer is empty
| 43 | Msg_WriteChar(sz); // Display received character as message
| 44 | Serial_Write(PORT,sz); // Output received character on the RS232 interface
| 45 | }
| 46 | AbsDelay(500); // Wait for output to complete
| 47 | // Consider, sending data continues while interrupt is present
| 48 | }
|
Hmmm.....wird eigentlich die schleife auch dann nochmal aufgerufen, wenn
ich z.B. ne Stunde später auch nochmal n byte schicke.... weil das Ende
Kriterium ja nur für ein Wort gilt ?????
Daniel Mayr schrieb:
> Bei folgendem Code hab ich schon zwei Fragen:
Die Fragen zeigen, dass du nicht bei diesem Beispiel einsteigen
solltest, sondern bei einfacheren Beispielen z.B. Serielle Übertragung
mit Polling statt mit Interrupt.
> Wenn von einem Programm(z.B. Matlab) über die serielle Schnittstelle zum
> Zeitpunkt X ein Byte geschrieben wird, heisst das dann, das der
> Interrupt wieder neu bei der Funktion "Serial_Init_IRQ" beginnt,
Natürlich nicht. Dein Programm oben bewegt sich nach den
Initialisierungen anwenderseitig innerhalb des Anweisungsblocks des
while.
> oder
> woher weiss ich wenn die Sache im Interrupt modus arbeitet, ab welcher
> Aktion der code wieder abgearbeitet wird.
Der Interrupt unterbricht deine Anweisungen in der while-Schleife. Nach
der Unterbrechung geht es aber an der gleichen Stelle weiter.
Während des Interrupts wird ein Empfangspuffer gefüllt, dessen Inhalt
dann deine Anwesiungen im while lesen können.
Wie gesagt, das ist 1. nicht für Anfänger und 2. sieht man in deinem
Programm nur ca. 50% des eigentlichen Programms. Viele Funktionen, die
zum Verständnis hilfreich sind, hast du nicht aufgelistet.
Hi Stefan,
vielen Dank für die Antwort. Ich gebe offen zu, dass ich davon keine
Ahnung hab, und das Beispiel eig. zu schwer ist. Aber die Schule lässt
mir keine andere Wahl.
Deine Ausführungen haben mir schon sehr weiter geholfen.
Ich versteh jedoch nicht, welche Ausführungen fehlen sollen, das is ein
Demoprogramm... also ein vollständiger Code?!
Hmm.....ich werde mal ein selber programmiertes Code Beispiel
reinstellen. 1 | // 35 byte Sende + Empfungspuffer + 6 byte interne FIFO Verwaltung
| 2 | byte buffer[41]; // globale Variable buffer
| 3 | float PID_output;
| 4 |
| 5 | #define PORT 0
| 6 | void InterruptServiceRoutine(void)%wie der Name schon sagt
| 7 | { int help;
| 8 | help=0;
| 9 | if(Serial_IRQ_Info(PORT, RS232_FIFO_RECV)!=0)//wieviele Bytes sind //angekommen?
| 10 | {
| 11 | help=Serial_ReadExt(PORT);//den Port auslesen
| 12 |
| 13 | // Hier könnte COde für die Weiterverarbeitung des Interrupts stehen
| 14 |
| 15 | }
| 16 | }
| 17 | byte buffer[41]; // globale Variable buffer
| 18 | void main(void)
| 19 | {
| 20 |
| 21 | word data;
| 22 | byte i;
| 23 | i=0;
| 24 | PID_output=0.8;
| 25 |
| 26 | Serial_Init_IRQ(0,buffer,20,15,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);
| 27 | while(true)
| 28 | Timer_T1PWM(492,PID_output,PS_1); // PWM starten mit PID_output als //On/off Verhältnis
| 29 | }
|
3 Fragen:
1.) Wenn die main fkt verlassen wird, hat der uC sein Programm
abgearbeitet?
2.) Die Pwm läuft jetzt in einer Endlosschleife mit dem Timer. Wenn
jetzt der Interrupt kommt, springt der controller in die
InterruptServiceRoutine.
Und dort kann er dann von der RS232 lesen, oder ?
3.) Du hattest gesagt, man frägt den Buffer ab. Könnte ich jetzt für das
tastverhältnis in der PWM (PID_output) folgenden code schreiben
1 | ...
| 2 | while(true)
| 3 | PID_output=Buffer[0];
| 4 | Timer_T1PWM(492,PID_output,PS_1);
| 5 | }
|
Würde jetzt PID_output immer bei einem empfangenen Byte seinen Wert
ändern, wenn dieses Byte den Interrupt auslöst?
Danke schon mal für euere Hilfe!! Des hilft hier echt weiter!
gruss Luiz
Daniel Mayr schrieb:
Vieles von deinem Code ist unverständlich.
Offensichtlich stützt du dich auf bereits vorhandene Funktionalität, die
wir hier nicht kennen.
Aber macht nichts. Hier der Versuch deine Fragen so gut es geht zu
beantworten.
> 1.) Wenn die main fkt verlassen wird, hat der uC sein Programm
> abgearbeitet?
Genau.
Und exakt dazu solltest du es nie kommen lassen. Was dann genau passiert
kannst du nicht mehr beeinflussen
> 2.) Die Pwm läuft jetzt in einer Endlosschleife mit dem Timer. Wenn
> jetzt der Interrupt kommt, springt der controller in die
> InterruptServiceRoutine.
> Und dort kann er dann von der RS232 lesen, oder ?
So wie ich deinen Code interpretiere: Ja
> 3.) Du hattest gesagt, man frägt den Buffer ab. Könnte ich jetzt für das
> tastverhältnis in der PWM (PID_output) folgenden code schreiben
>
> 1 | > ...
| 2 | > while(true)
| 3 | > PID_output=Buffer[0];
| 4 | > Timer_T1PWM(492,PID_output,PS_1);
| 5 | > }
| 6 | >
|
niemand hindert dich daran. 'Können' tust du immer. Ob es das macht, was
du erwartest, ist eine andere Frage.
Aber mangels Wissen darüber, was die Timer und RS232 Funktionen machen
lässt sich das von hier nicht entscheiden.
Übrigens: Du solltest die PWM nur dann neu setzen, wenn du auch wirklich
ein Zeichen empfangen hast.
> Würde jetzt PID_output immer bei einem empfangenen Byte seinen Wert
> ändern, wenn dieses Byte den Interrupt auslöst?
So siehts wohl aus.
Es ist aber sicher nicht schlau, sich das Zeichen aus buffer zu holen.
So wie ich das sehe, ist buffer Teil einer FIFO Veraltung. Wo daher
genau das neue Zeichen gespeichert wird, weißt du nicht.
Aber wenn ich das richtig sehe, dann holt ja Serial_ReadExt(PORT); das
neue Zeichen ab. Du musst es dir nur noch zurechtlegen, dass es an die
PWM übergeben werden kann.
Wieso nicht einfach hier das gcc-Tutorial durchackern?
Danach sollte man das mit RS232 und Interrupt eigentlich verstanden
haben.
Hallo zusammen,
danke für den Tip, werd ich machen.....aber leider drängt die
Zeit....und deshalb wird s wahrscheinlich noch ein paar dümmere Fragen
geben.
(Außerdem hab ich daheim nur die Entwicklungsumgebung, und nicht den
Controller, der steht leider in der Schule... deswegen is des ein bissl
schwierig.
Karl heinz Buchegger schrieb:
> Aber wenn ich das richtig sehe, dann holt ja Serial_ReadExt(PORT); das
> neue Zeichen ab. Du musst es dir nur noch zurechtlegen, dass es an die
> PWM übergeben werden kann.
Wobei ich mich frage, was denn nun das Problem ist.
So wie es aussieht, ist doch im Programm im Eröffnungsposting ohnehin
schon alles enthalten. Dieses Programm schickt ein erhaltenes Zeichen
zurpck, du willst es jetzt zum Verstellen einer PWM benutzen. Wo liegt
jetzt da das Problem?
das problem liegt darin, dass die Anpassung der PWM nicht funktioniert
und weiterhin:
Der Controller wird über usb als emultierter COM port betrieben. Wenn
ich nun im Debug modus bin, kann ich natürlich nicht mit matlab auf den
gleichen Comport zugreifen, weil der ja durch den Compiler belegt ist.
Und jetzt steh ich vor dem Problem, dass ich als Anfänger meine Zeichen
von Matlab senden kann, aber natürlich nicht debuggen kann, um zu sehen,
wie er die zeichen verarbeitet bzw. wie der interrupt läuft...
Dann musst du dir andere Debugmethoden ausdenken - das ist ein übliches
Geschäft. Und soviel wie möglich des Debuggens auf dem AVR durch
Planung/Vordenken beim Programmieren und Simulation auf dem PC ersetzen.
Anderes Debuggen kann im einfachen Fall heissen, ein paar IO-Pins als
Status-LEDs zu "opfern" und sich dort Debuganzeigen ausgeben zu lassen.
Eine Anzeige könnte z.B. sein, dass alle Sendungen von Mathlab aus mit
bestimmten Werten beginnen und/oder enden. Dein AVR prüft auf diese
Werte und schaltet eine Erfolg-LED oder eine Fehler-LED. Ob sich der AVR
in der ISR befindet kann man ebenfalls durch eine LED anzeigen lassen.
Hier kann es dann sinnvoll die Baudrate zu verkleinern, damit das
Flackern der LED gut sichtbar ist/bleibt.
Wenn du mehr Pins zur Verfügung hast, kann es sich lohnen ein LCD für
Debugmeldungen anzuschliessen. Ich weiss aber nicht so recht, ob ich dir
das empfehlen soll, weil du jetzt schon knapp an Zeit bist und
anscheinend große Teile des Tutorials noch nicht kennst.
Ja danke mal für die ganzen tollen Antworten, ich bin jetzt mal mit ein
paar hilfen von der ganzen seite am Programmieren, werde das schon
irgendwie lösen, die Nacht geht heute drauf und dann meld ich mich
morgen nochmal.
DANKE und frohe Weihnachten
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|