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