Uart sendet nur 2 Befehle

Gast #1361066
Lesenswert?

Hallo zusammen,

ich habe ein kleiner Programm für eine UART-Schnittstelle geschrieben 
Leider wird über den TX-Pin nur 2 der 3 Zeichen gesendet. Es werden 
immer nur die ersten 2 Zeichen gesendet. Hier mal mein Quellcode:



#include <avr/io.h>
#include <string.h> // Für "strcmp"
#include <stdlib.h> // Für "itoa"
#include <util/delay.h>
#define  TAKT      16000000L
#define UART_BAUDRATE  9600
int i=0;



// Berechnung der Konfigurationsparameter
#define UART_SETTING  ((TAKT/16L/UART_BAUDRATE)-1)


void setup_uart()
{


  /* Baudrate einstellen */
  UBRR1H = (char) (UART_SETTING >> 8);
  UBRR1L = (char) (UART_SETTING);

  /* Empfänger und Sender einschalten */
  UCSR1B =(1<<RXEN1) | (1<<TXEN1);

  /* Asynchron, 8N1 */
  UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
}

void uart_send( uint8_t zeichen )
{
  while (!UCSR1A&(1<<UDRE1));  // Warte, bis Puffer frei ist
  UDR1 = zeichen;               // jetzt das Byte ins UDR schreiben
}


void uart_putstring(char *str)
{
  unsigned char i;

  for (i=0;i<255;i++) /* Maximal 255 Zeichen ausgeben ... */
  {
    if (str[i] != 0)
      uart_send(str[i]);
    else
      break; // Ende des Strings erreicht
  }
}

char uart_getchar()
{
  // Ist schon ein Zeichen im Buffer?
  if (bit_is_set(UCSR1A, RXC))
    return UDR1;
  else
    return -1;
}

void uart_readline(char *str)
{
  char c;
  unsigned char index;

  index = 0;

  while (1)
  {
    c = uart_getchar();
    if (c != -1)
    {
      if (c == 13) /* ASCII: NewLine */
      {
        /* Ende der Zeile erreicht,
           also String abschließen */
        str[index] = 0;

        /* Funktion beenden */
        return;
      }
      else /* Normales Zeichen, anhängen an die Zeichenkette */
      {
        str[index] = c;
        index++;
      }
    }
  }
}

int main(void)

{
    setup_uart();
  for(;;)
  {

if (i==3000)
{
    uart_send(0x04);
    uart_send(0x55);
    uart_send(0x42);
    i=0;
}
    i++;

    }

  return 0;
}

Also es wird nur die 0x04 und die 0x55 ausgegeben. Kann mir bitte jemand 
sagen woran das liegt?

Vielen Dank!

Gruß Roman
#1361173
Lesenswert?

Roman schrieb:
> Hey Maxxie,
>
> danke für die Antwort aber ich verstehe das nicht ganz.
> Wie würdest du diese Zeile schreiben??
>
> while (!UCSR1A&1<<UDRE1);


Erst mal

Schreib nicht alles Zeichen an Zeichen. Leerzeichen kosten nichts, 
können aber Klarheit bringen

zweitens

  while( ! (UCSR1A & ( 1<<UDRE1 ) ) )

ist was anderes als

  while( !UCSR1A & ( 1<<UDRE1 ) )

Im ersteren wird der Ausdruck    UCSRA1A & ( 1<<UDRE1 ) berechnet und 
dann negiert.
Im zweiten wird der Ausdruck UCSR1A berechnet, negiert und dieses 
Ergebnis dann mit 1<<UDRE1 verundet. Und da kommt dann ganz was anderes 
raus.

Du willst das erstere haben.
Gast #1361264
Lesenswert?

Hey danke Leute,

jetzt funktioniert es :). Super Danke!
Kenn ihr euch auch mit LIN-Transceivern aus?

Würde gerne nämlich über den UART einen LIN-Transceiver ansteuern.
Ich habe nur noch rin Problem mit dem Break-Field. Weiß nich wie ich das 
programmieren soll. Kann mir da einer weiterhelfen? Das Sync und ID 
Field habe ich programmiert.

gruß Roman
Gast #1361273
Lesenswert?

void lin_put_break(void)
{
    int16 run;
    // P2.4 als I/O Output konfigurieren
    clr_bit(P2SEL, BIT4);
    clr_bit(P2OUT, BIT4);
    for(run = 0; run <= 4000; run++){
        nop;
    }
    // P2.4 als UART Output konfigurieren
    set_bit(P2OUT, BIT4);
    set_bit(P2SEL, BIT4);
    for(run = 0; run <= 2000; run++){
        nop;
    }
}

ist etwas gewürg aber funktioniert. War mit einem MSP 430 und einem LIN 
Bus-Treiber
Gast #1362746
Lesenswert?

Hey Danke für den Tipp, hab da mal was selbst geschrieben. Aber es 
klappt leider nicht. Der TX-Pin wird nicht auf 0 gesetzt.



#include <avr/io.h>
#include <string.h> // Für "strcmp"
#include <stdlib.h> // Für "itoa"
#include <util/delay.h>


#define  TAKT      16000000L
#define UART_BAUDRATE  11200
int h=0;
#define             CLR_TX     ( PORTD &=~ (1<<PD3))
#define             SET_TX  (    PORTD |=  (1<<PD3))
#define NOP     asm volatile ("nop" ::)
// Berechnung der Konfigurationsparameter
#define UART_SETTING  ((TAKT/16L/UART_BAUDRATE)-1)


void setup_uart()
{


  /* Baudrate einstellen */
  UBRR1H = (char) (UART_SETTING >> 8);
  UBRR1L = (char) (UART_SETTING);

  /* Empfänger und Sender einschalten */
  UCSR1B =(1<<RXEN1) | (1<<TXEN1);

  /* Asynchron, 8N1 */
  UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
}

void uart_send( uint8_t zeichen )
{
  while( ! (UCSR1A & ( 1<<UDRE1 ) ) );  // Warte, bis Puffer frei ist
  UDR1 = zeichen;               // jetzt das Byte ins UDR schreiben
}


void uart_putstring(char *str)
{
  unsigned char i;

  for (i=0;i<255;i++) /* Maximal 255 Zeichen ausgeben ... */
  {
    if (str[i] != 0)
      uart_send(str[i]);
    else
      break; // Ende des Strings erreicht
  }
}

char uart_getchar()
{
  // Ist schon ein Zeichen im Buffer?
  if (bit_is_set(UCSR1A, RXC))
    return UDR1;
  else
    return -1;
}

void uart_readline(char *str)
{
  char c;
  unsigned char index;

  index = 0;

  while (1)
  {
    c = uart_getchar();
    if (c != -1)
    {
      if (c == 13) /* ASCII: NewLine */
      {
        /* Ende der Zeile erreicht,
           also String abschließen */
        str[index] = 0;

        /* Funktion beenden */
        return;
      }
      else /* Normales Zeichen, anhängen an die Zeichenkette */
      {
        str[index] = c;
        index++;
      }
    }
  }
}

int main(void)

{
  int a=0;
  DDRD=0xFF;
  for(;;)
  {

    CLR_TX;
    _delay_ms(5);


    setup_uart();
    uart_send(0x00);
    uart_send(0x55);
    uart_send(0x42);



  }

  return 0;
}


Nur wenn ohne das "setup_uart();" schreibe wird der Pin auf 0 gelegt.

Kann mir bitte jemand sagen woran das liegt??

Vielen lieben Dank!
Gruß Roman

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren