AVR: Interrupt manuel auslösen

Gast #1899208
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:
1
volatile uint8_t txbuff[4];
2
volatile uint8_t txlength = 0;
3

4
int main( void ) {
5
    
6
    uint32_t daten = 0;
7
    
8
    initialisieren();
9
    sei();
10
    ...
11
    uart_senden( daten );
12
    ...
13
}
14
void uart_senden( uint32_t data ) {
15

16
    txbuff[0] = (uint8_t)(data>>24);
17
    txbuff[1] = (uint8_t)(data>>16);
18
    txbuff[2] = (uint8_t)(data>>8);
19
    txbuff[3] = (uint8_t)data;
20
    txlength = 3;
21

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

27
ISR( ... ){
28

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

32
    UDR0 = txbuff[txlength];
33
    txlength--;
34
}

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
Gast #1899221
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.ä.
#1899231
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.
Gast #1899476
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?

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.