www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR: Interrupt manuel auslösen


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin gerade am grübeln wie ich am besten einen Interrupt manuel 
auslöse/in die Interruptroutine springe. Programmiert in C, ausgeführt 
auf einem Mega88.

Hintergrund:
Zum Senden von Daten per UART gedenke ich ein globales Array und eine 
globale Zählvariable anzulegen.
Sollen Daten gesendet werden, füllt eine Funktion das geprüft leere 
Array und setzt die Zählvariable auf die Anzahl an Einträgen im Array.
Anschließend soll der TX-complete-Interrupt anlaufen.
Dieser lädt in seiner Interruptroutine ein Byte aus dem Array in UDR0 
und zählt den globalen Zähler um eins zurück.
In den nächsten Interrupts wiederholt sich der Spaß, bis der Zähler auf 
null steht, dann soll der Interrupt disabled werden.

Was ich mich nun frage:
Wenn ich im Register UCSR0A TXC0 (TX-Complete) setze und anschließend im 
UCSR0B mit TXCIE0 Interrupts aktiviere, dann müsste doch sofort die 
Interruptroutine anspringen oder?

In etwa ist das so gemeint:
volatile uint8_t txbuff[4];
volatile uint8_t txlength = 0;

int main( void ) {
    
    uint32_t daten = 0;
    
    initialisieren();
    sei();
    ...
    uart_senden( daten );
    ...
}
void uart_senden( uint32_t data ) {

    txbuff[0] = (uint8_t)(data>>24);
    txbuff[1] = (uint8_t)(data>>16);
    txbuff[2] = (uint8_t)(data>>8);
    txbuff[3] = (uint8_t)data;
    txlength = 3;

    UCSR0A |= (1<<TXC0);
    UCSR0B |= (1<<TXIE0);
    // und ab in die Interruptroutine, da gehts weiter mit dem Senden...
}

ISR( ... ){

    if ( txlength == 0 )
        UCSR0B &= ~(1<<TXIE0);

    UDR0 = txbuff[txlength];
    txlength--;
}

Sollte doch so funktionieren, oder?
ich kann das gerade nicht Testen, mein Programmiergerät ist noch im 
Postauto. Ausserdem interessiert mich eure Meinung dazu. Müll, oder 
brauchbar? Verbesserungsvorschläge?

Vielen Dank
Grüße Martin

Autor: slw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich gehe so ähnlich vor. Allerdings springe ich nicht in Interrupt per 
Hand rein, sonder schreibe den ersten Byte aus dem Array in UART Data 
Register, danach greift die ISR auf Array und ich singe nur noch das 
Lied von Lapaloma o.ä.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> Wenn ich im Register UCSR0A TXC0 (TX-Complete) setze

Das kannst Du nicht setzen.  Ganz im Gegenteil: wenn Du eine 1 
reinschreibst, wird es gelöscht.

Wenn Du es allerdings nie manuell löschst, kannst Du davon ausgehen, 
dass es gesetzt ist, wenn der Sender leer ist.  Es genügt dann also, 
TXCIE zu setzen, um in die Interruptroutine zu springen.  Ist der 
Sendepuffer leer, löschst Du TXCIE wieder.

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Martin schrieb:
>> Wenn ich im Register UCSR0A TXC0 (TX-Complete) setze
>
> Das kannst Du nicht setzen.  Ganz im Gegenteil: wenn Du eine 1
> reinschreibst, wird es gelöscht.

Ich glaube er spricht vom (AVR Studio) Simulator.

Gruß,
Magnetus

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Das kannst Du nicht setzen.  Ganz im Gegenteil: wenn Du eine 1
> reinschreibst, wird es gelöscht.

Hoppla, Danke! Datenbaltt lesen, da stehts tatsächlich so drin. Danke

Aber wie du schon schreibst, es müsste ja eh noch gesetzt sein.

Autor: slw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schon drüber nachgedacht, die ISR direkt aufzurufen?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
slw schrieb:
> schon drüber nachgedacht, die ISR direkt aufzurufen?

Naja so gut sind meine C-Kenntnisse wohl nicht. Wie geht das?

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> slw schrieb:
>> schon drüber nachgedacht, die ISR direkt aufzurufen?
>
> Naja so gut sind meine C-Kenntnisse wohl nicht. Wie geht das?

schon mal eine Funktion in C aufgerufen?

funktion();

Autor: slw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ganz normaler Funktionsaufruf. Du muß allerdings probieren, ob dein 
Compiler das kann.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>ganz normaler Funktionsaufruf.

Und wenn vorher noch das I-Flag gelöscht wird, auch identisch mit einem 
Interrupt.

MfG Spess

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lehrmann Michael schrieb:
>>> schon drüber nachgedacht, die ISR direkt aufzurufen?
>>
>> Naja so gut sind meine C-Kenntnisse wohl nicht. Wie geht das?
>
> schon mal eine Funktion in C aufgerufen?
>
> funktion();

funktionen aufrufen ist klar, soll dass dann bedeuten dass man mit
ISR( ..._vect );
eine Interruptroutine manuell ausführen kann?

Autor: Martin Z. (zilluss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pack doch einfach deine Interruptroutine in eine eigene Funktion also im 
Sinne von

ISR( ..._vect )
{
    DoAllStuff();
}

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

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.