mikrocontroller.net

Forum: Compiler & IDEs AVR Mega32 Umschalten UART Geschwindigkeit


Autor: Nick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich muss eine LIN Komunikation ans laufen bringen.
UART sollte so konfiguriert werden:
 LIN überträgt die Daten byteweise. Die Bytes werden als UART-Zeichen 
übertragen. Die dabei verwendete Kodierung ist 8-N-1,1Startbit, 8 
Datenbits, kein Paritybit, 1 Stoppbit. Das Startbit ist eine logische 0, 
das Stoppbit ist eine logische 1. Die Daten werden mit der niedrigsten 
Stelle zuerst gesendet (LSB first). Damit besteht das LIN-UART4-Zeichen 
aus 10 Bits.

ich habe es mal so versucht:

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL     /* Quarz mit 8 Mhz  */
//#include <avr/delay.h>      /* definiert _delay_ms() ab avr-libc Version 1.2.0 */



#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART1 Receiver buffer
#define RX_BUFFER_SIZE1 8


volatile int msg_index=0;            //uart rx index
volatile char rx_buffer1[RX_BUFFER_SIZE1];
volatile unsigned char tx_can[8];
volatile unsigned char rx_wr_index1,rx_rd_index1,rx_counter1;
// This flag is set on USART1 Receiver buffer overflow
// bit rx_buffer_overflow1;
volatile char rx_buffer_overflow1;                      //Kläre BIT 
volatile char new_RX;




void seriell_int_9600(void)
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;

UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);

UBRRH=0x00;
UBRRL=0x33;

}

void seriell_int_19200(void) {
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 19200
UCSRA=0x00;
UCSRB=0x18;

UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);

UBRRH=0x00;
UBRRL=0x19;
}

void putchar_LIN(uint8_t c)
{
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
UDR=c;
}
int main (void)
{  

uint8_t c;  
uint16_t i;
uint16_t a;
uint16_t b;


  while (1)

  {
        
    for (i=0; i<=0xFF; ++i)
     {

    seriell_int_9600();
    c = 0x00;
    putchar_LIN(c);

    seriell_int_19200();
    c = 0x55;
    putchar_LIN(c);
    c = i;
    putchar_LIN(c);

    for (a=0; a<=0xFF; ++a)
      {
      for (b=0; b<=0xFF; ++b)
        {
        asm volatile ("nop");
        }
      }
     }


  }


  //never goes here!
  return 0;      
}

Der UART schaltet nicht zwischen 9600 und 19200 hin und her was aber 
notwenidig ist um das Sync Break zu schicken, das mindestens 13 
Bitzeiten lang sein soll.
auf dem Oszi sehe ich das 0x55 geschrieben wird auch mit 19200 auch das 
3. byte wird geschrieben auch mit 19200 nur das erste (0x00) ist nicht 
mit 9600 geschrieben.

Da scheinbar UCSRC im Debugger nicht rigtig angezeigt wird, stimmt die 
einstellung 1 start 8 daten 1 stop keine parity?
und wieso wird die geschwindigkeit nicht umgeschalten?

THX

Autor: Nick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch ne kleine Anmerkung wenn ich im Debugger durchsteppe dann ist das 
ertse Zeichen länger als die nächsten zwei, sobald ich aber RUN mache 
dann sind alle drei gleich lang?????? also 19200

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das seriell_int_xxx muß natürlich erst warten, bis das Sendenendebit 
gesetzt ist, sonst ziehst Du ja dem laufenden Byte die Baudrate weg.


Peter

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... bin mir aus dem Stegreif gerade nicht sicher ob man mit 8 MHz Takt 
die Baudraten 19200 und 9600 mit ausreichend kleiner Abweichung 
hinbekommt. Sollte mit einem Blick ins Datenblatt überprüft werden

Autor: Nick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der Tipp mit dem warten ist nicht schlecht da bin ich nicht druaf 
gekommen.
Baudrate sollte kein Problem sein
19200 @8Mhz UBRR = 0x19   0,16%ERR
9600  @8Mhz UBRR = 0x33   0,16%ERR
nach AVR Fp Calc and Timer Tool

ob das schreiben des UCSRC richtig ist weis ich immer noch nicht ;-(
1 Startbit, 8 Datenbits, kein Paritybit, 1 Stoppbit sollte es sein
Ich versuche es ja mit:
UCSRA=0x00;
UCSRB=0x18;

UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);

UBRRH=0x00;
UBRRL=0x19;
was bedeutet das _BV ?


komplett siehts grad so aus:
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART1 Receiver buffer
#define RX_BUFFER_SIZE1 8


volatile int msg_index=0;            //uart rx index
volatile char rx_buffer1[RX_BUFFER_SIZE1];
volatile uint16_t i;


void warte (uint16_t i)
{
  uint16_t b;
      for (b=0; b<=i; ++b)
        {
          static unsigned char volatile dummy;
              (void) (dummy = b);
          PORTB ^= 1 << PORTB1;
        }

}



void seriell_int_9600(void)
{
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;

UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);

UBRRH=0x00;
UBRRL=51;

}

void seriell_int_19200(void) {
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 19200
UCSRA=0x00;
UCSRB=0x18;

UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);

UBRRH=0x00;
UBRRL=25;
}

void putchar_LIN(uint8_t c)
{
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
UDR=c;
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
}


int main (void)
{  

uint8_t c;  
uint16_t i;
PORTB=0x00;
DDRB=0xFF;

// PORTB |= (1 << 0);    /* setzt Bit 0 an PortB auf 1 */
// PORTB &= ~(1 << 0);   /* loescht Bit 0 an PortB */

  while (1)

  {
        
    for (i=0; i<=0xFF; ++i)
     {
    PORTB = 0x01;
    warte(0x3fff);

    seriell_int_9600();
    c = 0x00;
    putchar_LIN(c);

        warte(0xff);

    seriell_int_19200();
    c = 0x55;
    putchar_LIN(c);

        warte(0xff);
    c = i;
    putchar_LIN(c);

    warte(0x2fff);
     
    PORTB = 0x00;
    warte (0x7fff);
    }

  }


  //never goes here!
  return 0;      
}

  

Autor: FBI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
_BV ist ein define in einer der Header Dateien von avr-libv
#define _BV(bit) (1 << (bit))

CU

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.