Transmit Pin für USART

Gast #4377371
Lesenswert?
• ▲
▼
Hallo in die Runde,

hätte mal eine kleine Frage, habe folgende Transmit Routine geschieben. 
Doch da ist noch ein "delay" drin. Geht das auch besser? Pin D2 muss auf 
High zum senden.
1
void USART_Transmit( unsigned char data )
2
{
3
  
4
  PORTD |= (1<<PORTD2);
5
  while ( !( UCSR0A & (1<<UDRE0)) )
6
  ;
7
  UDR0 = data;
8
        //das delay....
9
  _delay_ms(1);
10
  PORTD &= ~(1<<PORTD2);
11
  
12
}

Gruß

Oliver
#4377387
Lesenswert?
• ▲
▼
Klar geht das kürzer, einfach hinterher warten:
1
void USART_Transmit( unsigned char data )
2
{
3
  
4
  PORTD |= (1<<PORTD2);
5
  
6
  UDR0 = data;
7
        //das delay....
8
  while ( !( UCSR0A & (1<<UDRE0)) )
9
  ;
10
  PORTD &= ~(1<<PORTD2);
11
  
12
}


Aber falls mehr als 1 Byte am Stück gesendet wird möchte man eventuell 
keine Nadel-Impulse auf dem Transmit Pin haben...
Gast #4377576
Lesenswert?
• ▲
▼
Hallo,

Danke für den Tip,

Habe es mit "AVR306: Using the AVR UART in C on tinyAVR and megaAVR 
devices"
probiert, doch leider mache ich da was falsch.

Wo sollte mein Pin AN/Aus hin?
1
ISR(USART_UDRE_vect)
2
{
3
  unsigned char tmptail;
4

5
  /* Check if all data is transmitted */
6
  if ( USART_TxHead != USART_TxTail )
7
  {
8
    PORTD |= (1<<PORTD2);
9
    /* Calculate buffer index */
10
    tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
11
    USART_TxTail = tmptail;      /* Store new index */
12
    
13
    UDR0 = USART_TxBuf[tmptail];  /* Start transmition */
14
  }
15
  else
16
  {
17
    UCSR0B &= ~(1<<UDRIE0);         /* Disable UDRE interrupt */
18
    PORTD &= ~(1<<PORTD2);
19
  }
20
}

So schon mal nicht, und hier war auch ohne erfolg:
1
void USART0_Transmit( unsigned char data )
2
{
3
  PORTD |= (1<<PORTD2);
4
  unsigned char tmphead;
5
  /* Calculate buffer index */
6
  tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK; /* Wait for free space in buffer */
7
  while ( tmphead == USART_TxTail );
8

9
  USART_TxBuf[tmphead] = data;           /* Store data in buffer */
10
  USART_TxHead = tmphead;                /* Store new index */
11

12
  UCSR0B |= (1<<UDRIE0);                    /* Enable UDRE interrupt */
13
 PORTD &= ~(1<<PORTD2);
14
  
15
}


sorry, was mach ich da falsch?

Gruß

Oliver
Gast #4377587
Lesenswert?
• ▲
▼
Hallo,

also der USART ohne Interrupt geht ja, doch das delay ist schlecht. 
Jetzt bin ich dem Tip mit der Interruptroutine gefolgt. Dieser Code ist 
auch an RS232 ohne Tramsmit ON pin funktional. Jetzt ist nur das mit dem 
PD2 on /off
noch mein Problem!?

Cu Oliver
Gast #4377985
Lesenswert?
• ▲
▼
Hallo,

> Wo mache ich den Sende Enable pin An bzw aus?

Das SendEnable-Bit riecht sehr nach einem RS485-Treiberbaustein ...

Zum Thema: das Enable-Bit muss gesetzt werden, BEVOR das 
USART-Datenregister geschrieben wird, und muss zurückgesetzt werden, 
NACHDEM die Übertragung des Datenbytes abgeschlossen ist.
Dazu gibt es im Register "UCSRA" das Bit "TX_complete", das nach 
erfolgtem Aussenden gesetzt wird. Es kann auch einen Interrupt auslösen; 
ansonsten müsste man in der TX-Routine warten, bis dieses Bit gesetzt 
wird (und es danach zurücksetzen).
Nur so ist sichergestellt, dass nicht während des Sendens der Sender 
vorzeitig deaktiviert wird.
Gast #4378128
Lesenswert?
• ▲
▼
Hallo ist das so OK oder immer noch nicht richtig?
1
ISR(USART_UDRE_vect)
2
{
3
  unsigned char tmptail;
4

5
  /* Check if all data is transmitted */
6
  if ( USART_TxHead != USART_TxTail )
7
  {
8
    //PORTD |= (1<<PORTD2);
9
    /* Calculate buffer index */
10
    tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
11
    USART_TxTail = tmptail;      /* Store new index */
12
    
13
    UDR0 = USART_TxBuf[tmptail];  /* Start transmition */
14
  }
15
  else
16
  {
17
    UCSR0B &= ~(1<<UDRIE0);         /* Disable UDRE interrupt */
18
    PORTD &= ~(1<<PORTD2); // Enable abschalten !!!!!!!!!!!!!!
19
  }
20
}
21

22
void USART0_Transmit( unsigned char data )
23
{
24
  PORTD |= (1<<PORTD2); // Enable anschalten !!!!!!!!!!!!!!
25
  unsigned char tmphead;
26
  /* Calculate buffer index */
27
  tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK; /* Wait for free space in buffer */
28
  while ( tmphead == USART_TxTail );
29

30
  USART_TxBuf[tmphead] = data;           /* Store data in buffer */
31
  USART_TxHead = tmphead;                /* Store new index */
32

33
  UCSR0B |= (1<<UDRIE0);                    /* Enable UDRE interrupt */
34
  
35
  
36
}

Gruß

Oliver
Gast #4379861
Lesenswert?
• ▲
▼
Ok danke, doch Lieder habe ich kein tutorial gefunden dass mir das mit 
dem transmit complete näher bringt. Wo könnte ich sowas finden, bitte 
nicht nur Google schreiben. Denn gegoogelt habe ich schon.
Danke für die hilfe.

Gruß oliver

Ps: am Handy getippt. Und bin kein C Profi nur angefangener..
#4381201
Lesenswert?
• ▲
▼
Oliver schrieb:
> Ok danke, doch Lieder habe ich kein tutorial gefunden dass mir das mit
> dem transmit complete näher bringt. Wo könnte ich sowas finden

SO wie immer: Du weisst wie der Interrupt heisst, im Datenblatt findest 
du das Register und den Bitnamen um ihn freizuschalten, du weisst wie 
eine ISR geschrieben wird und in der ISR schaltest du den Pin 
entsprechend um.

Der Rest bleibt so wie er ist. Nur das hier
1
    PORTD &= ~(1<<PORTD2); // Enable abschalten !!!!!!!!!!!!!!
wandert in die ISR für den Transmit Complete Interrupt und ist dort die 
einzige Anweisung. Wozu brauchst du da jetzt ein Tutorial?
Gast #4387308
Lesenswert?
• ▲
▼
Hallo Gemeinde,

DANKE erstmal für die Hilfe, ja es hat gedauert, doch jetzt habe ich
folgendes und es scheint zu funktionieren.
1
void USART0_Init( unsigned int baudrate )
2
{
3
  unsigned char x;
4
  DDRD |= (1<<DDD2);
5

6
  /* Set the baud rate 115200 bei 18,432mHz*/
7
  UBRR0H = (unsigned char) (baudrate>>8);
8
  UBRR0L = (unsigned char) baudrate;
9
  
10
  /* Enable UART receiver and transmitter und TXCIE0 Transmit Complete*/
11
  UCSR0B = ( ( 1 << RXCIE0 ) | ( 1 << RXEN0 ) | ( 1 << TXEN0 ) | ( 1 << TXCIE0) );
12
  
13
  /* Set frame format: 8 data 1stop */
14
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);              
15
  
16
  /* Flush receive buffer */
17
  x = 0;
18

19
  USART_RxTail = x;
20
  USART_RxHead = x;
21
  USART_TxTail = x;
22
  USART_TxHead = x;
23
}
24

25
ISR(USART_TX_vect)
26
{
27
  PORTD &= ~(1<<PORTD2);
28
}
29

30
ISR(USART_UDRE_vect)
31
{
32
  unsigned char tmptail;
33

34
  if ( USART_TxHead != USART_TxTail )
35
  {
36
    PORTD |= (1<<PORTD2);
37
    PORTD |= (1<<PORTD2);
38
    
39
    tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
40
    USART_TxTail = tmptail;      
41
    
42
    UDR0 = USART_TxBuf[tmptail];  
43
  }
44
  else
45
  {
46
    UCSR0B &= ~(1<<UDRIE0);         
47
  }
48
}

Gruß

Oliver

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.