Forum: Mikrocontroller und Digitale Elektronik USART_TXC_vect mit software auslösen ?


von Daniel R. (zerrome)


Lesenswert?

Hallo zusammen,

ich hab da mal ne frage, gibt es die Möglichkeit USART_TXC_vect software 
seitig auszulösen?

Laut Datenblatt meines Atmega8 kann man nämlich das TXC flag, welches 
einen Transmit Complete Interrupt auslöst, im Register UCSRA setzen, 
dass allerdings setzt den Interrupt aber zurück...
Hab Lösungen für int0 oder so gesehen, aber USART_TXC_vect per software 
auslösen nicht.

Hat jemand ne Idee?

Vielen Dank schonmal

Grüße Zerrome

von Εrnst B. (ernst)


Lesenswert?

Wenn du statt dem TXComplete den UDRE-Irq verwendest (macht meistens eh 
mehr Sinn) kannst du den Interrupt einfach in software auslösen, in dem 
du (bei leerem UDR-Register) das UDRIE-Bit setzt.

Codebeispiel (Tiny2313, Receive-sachen rausgeschnitten):
1
#define SEND_BUF_BITS 4
2
#define SEND_BUF_SIZE (1<<SEND_BUF_BITS)
3
#define SEND_BUF_MASK (SEND_BUF_SIZE-1)
4
5
static volatile uint8_t send_buf_start;
6
static uint8_t send_buf_end;
7
static char send_buf[SEND_BUF_SIZE];
8
9
void uart_putc(char c)
10
{
11
  uint8_t next_pos=(send_buf_end+1)&SEND_BUF_MASK;
12
13
  // wait till we got space in buffer
14
  while ((SREG & _BV(SREG_I)) && (next_pos == send_buf_start));
15
16
  if (next_pos == send_buf_start) {
17
    // Interrupts are disabled and buffer is full. we loose this char.
18
    return;
19
  }
20
21
  send_buf[send_buf_end]=c;
22
23
  send_buf_end=next_pos;
24
25
  // Enable UDR interrupt. will immediatly call ISR if UDRE is set.
26
  UCSRB = _BV(TXEN) | _BV(RXEN) | _BV(UDRIE) | _BV(RXCIE);
27
}
28
29
ISR(USART_UDRE_vect) {
30
  if (send_buf_end == send_buf_start) {
31
    // No data to send, disable ISR.
32
    UCSRB = _BV(TXEN) | _BV(RXEN) | _BV(RXCIE);
33
  } else {
34
    UDR=send_buf[send_buf_start++];
35
    send_buf_start &=SEND_BUF_MASK;
36
  }
37
}

von Falk B. (falk)


Lesenswert?

@ Daniel Rau (zerrome)

>ich hab da mal ne frage, gibt es die Möglichkeit USART_TXC_vect software
>seitig auszulösen?

Nein. Das ist auch praktisch nicht notwendig. Für eine 
Interruptgesteuerte UART Übertragung nutzt man UDRE.

Interrupt.

MfG
Falk

von Daniel R. (zerrome)


Lesenswert?

Ah,

die Idee mit dem USART_UDRE_vect zu arbeiten hatte ich auch schon, 
allerdings war dann die Überlegung dass wenn keine Daten in meinem 
Ring-Puffer sind trozdem die ISR rattert. Was mir nicht gekommen war ist 
in dem Beispiel von  Ernst drin. Einfach abschlaten des Interrupt 
vectors...

Super, hat geholfen, Danke.

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.