www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C PRogramm verstehen (Interrupt RS232)


Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
#define PORT 0
//oimaul defina, dann isch s guat

// 35 bytes send + receive buffer + 6 bytes internal FIFO management
byte buffer[41];                                // Array declaration


//------------------------------------------------------------------------------
// Main program
//
void main(void)
{
    char Text1[40];                             // Arrays declaration
    char output[40];
    byte count;
    int sz;

    Text1="Test Text\r\n";

    //Initialize RS232: 19200 bps, 8 Bit, 1 Stop, NP
    // 20 bytes receive buffer - 15 bytes send buffer
    Serial_Init_IRQ(PORT,buffer,20,15,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);

    Serial_Write(PORT,'\r');                       // control character for carriage return is sent via RS232 interface
    Serial_Write(PORT,'\n');                       // control character for line feed is sent via RS232 interface
    Serial_WriteText(PORT,Text1);                  // output text via RS232 interface


    AbsDelay(10000);                             // 10 seconds waiting time
                                                 // Until receive buffer is full, all received data are buffered


    count=Serial_IRQ_Info(PORT,RS232_FIFO_RECV); // Investigates, how many characters have been received

    Msg_WriteWord(count);                       // The number of characters is displayed as message
    output=" Characters received by IRQ\r";
    Msg_WriteText(output);

    while(true)
    {
        sz=Serial_ReadExt(PORT);                // Get value out of receive buffer
        if(sz==0x100) break;                    // If the value is 0x100, the receive buffer is empty
        Msg_WriteChar(sz);                      // Display received character as message
        Serial_Write(PORT,sz);                  // Output received character on the RS232 interface
    }
    AbsDelay(500);                              // Wait for output to complete
                                               // Consider, sending data continues while interrupt is present
}

Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?????

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
// 35 byte Sende + Empfungspuffer + 6 byte interne FIFO Verwaltung
byte buffer[41]; // globale Variable buffer
float PID_output;

#define PORT 0
void InterruptServiceRoutine(void)%wie der Name schon sagt
{ int help;
  help=0;
 if(Serial_IRQ_Info(PORT, RS232_FIFO_RECV)!=0)//wieviele Bytes sind //angekommen?
 {
        help=Serial_ReadExt(PORT);//den Port auslesen
     
// Hier könnte COde für die Weiterverarbeitung des Interrupts stehen

}
}
byte buffer[41]; // globale Variable buffer
void main(void)
{

word data;
byte i;
i=0;
PID_output=0.8;

Serial_Init_IRQ(0,buffer,20,15,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);
while(true)
Timer_T1PWM(492,PID_output,PS_1);  // PWM starten mit PID_output als //On/off Verhältnis
}

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
...
while(true)
PID_output=Buffer[0];
Timer_T1PWM(492,PID_output,PS_1);  
}
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
>
>
> ...
> while(true)
> PID_output=Buffer[0];
> Timer_T1PWM(492,PID_output,PS_1);
> }
> 

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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso nicht einfach hier das gcc-Tutorial durchackern?
Danach sollte man das mit RS232 und Interrupt eigentlich verstanden 
haben.

Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dan My (luizaranha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.