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


von Martin (Gast)


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

von slw (Gast)


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.ä.

von Hc Z. (mizch)


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.

von Magnus M. (magnetus) Benutzerseite


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

von Martin (Gast)


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.

von slw (Gast)


Lesenswert?

schon drüber nachgedacht, die ISR direkt aufzurufen?

von Martin (Gast)


Lesenswert?

slw schrieb:
> schon drüber nachgedacht, die ISR direkt aufzurufen?

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

von Lehrmann M. (ubimbo)


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();

von slw (Gast)


Lesenswert?

ganz normaler Funktionsaufruf. Du muß allerdings probieren, ob dein 
Compiler das kann.

von spess53 (Gast)


Lesenswert?

Hi

>ganz normaler Funktionsaufruf.

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

MfG Spess

von Martin (Gast)


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?

von Martin Z. (zilluss)


Lesenswert?

Pack doch einfach deine Interruptroutine in eine eigene Funktion also im 
Sinne von

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

von Michael H. (michael_h45)


Lesenswert?


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
Noch kein Account? Hier anmelden.