Themen:

AVR, avr-gcc, CAN, CPLD, Elektronik, Mikrocontroller, MSP430, PIC, Roboter, Schaltungen, Sensoren, Software, Testboards

Ansteuerung des UART mit avr-gcc

Tags: AVR, avr-gcc
Stand: 26. September 2006, 23:49
2 Kommentar(e)

UART

C:
#include <avr/io.h>
#include <inttypes.h>

// Sollte schon im Makefile definiert sein.
// In dem Fall hier einfach löschen.
#define F_CPU       7372800UL

#define BAUD        19200UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

// USART initialisieren
void uart_init(void)
{
    // Baudrate einstellen (Normaler Modus)
    UBRRH = (uint8_t) (UBRR_BAUD>>8);
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);

    // Aktivieren von receiver und transmitter
    UCSRB = (1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

int main(void)
{
    uint8_t buffer;

    // USART initialisieren
    uart_init();

    while (1)
    {
        // Warten bis Daten empfangen wurden
        while ( !(UCSRA & (1<<RXC)) )
            ;

        // Empfangsregister auslesen
        buffer = UDR;

        // Warten bis der Sendepuffer frei ist
        while ( !( UCSRA & (1<<UDRE)) )
            ;

        // Daten in den Puffer schreiben und damit senden
        UDR = buffer;
    }
}

Verwenden des UART mit Interrupts

C:
#include <avr/io.h>
#include <avr/interrupt.h>

// Sollte schon im Makefile definiert sein.
// In dem Fall hier einfach löschen.
#define F_CPU       7372800UL

#define BAUD        19200UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

void uart_init(void)
{
    // Baudrate einstellen (Normaler Modus)
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);

    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}


int main(void)
{
    // USART initialisieren
    uart_init();

    sei();

    // Nichts tun. Die Interrupts erledigten den Rest
    while (1)
        ;
}

// Interrupt wird ausgelöst sobald neue Daten im USART-Empfangspuffer liegen
SIGNAL(SIG_UART_RECV)
{
    unsigned char buffer;

    // Daten aus dem Puffer lesen ...
    buffer = UDR;

    // ... warten bis der Sendepuffer leer ist ...
    while ( !( UCSRA & (1<<UDRE)) )
        ;
    // ... und gleich wieder zurück schicken
    UDR = buffer;
}

Strings aus dem Flashspeicher ausgeben

C:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

// Sollte schon im Makefile definiert sein.
// In dem Fall hier einfach löschen.
#define F_CPU       7372800UL

#define BAUD        19200UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

// Für die bessere Lesbarkeit
#define TRUE    1
#define FALSE   0


volatile unsigned char daten_gesendet = TRUE;
const prog_char* volatile p_string;

// Zeichenkette im Flashspeicher
prog_char daten[] = "Hello World!\n";


// USART initialisieren
void uart_init(void)
{
    // Baudrate einstellen ( Normaler Modus )
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);

    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
    UCSRB = (1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

int main(void)
{
    // USART initialisieren
    uart_init();

    sei();

    while (1)
    {
        if (daten_gesendet)
        {
            // Flag zurücksetzen
            daten_gesendet = FALSE;

            // Pointer zeigt auf die Daten im Flashspeicher
            p_string = daten;

            /* Interrupt aktivieren, damit wird sofort zur
               Interruptroutine gesprungen und das erste Zeichen gesendet. */

            UCSRB |= (1<<UDRIE);
        }
    }
}

// Interrupt wird ausgelöst sobald der Sendepuffer leer ist
SIGNAL(SIG_UART_DATA)
{
    char buffer = pgm_read_byte(p_string++);

    /* Wenn nicht das Ende der Zeichenkette erreicht wurde,
       dann weiteres Zeichen senden */

    if ( buffer != '\0' ) {
        UDR = buffer;

    } else {
        // Flag setzen, das der String gesendet wurde
        daten_gesendet = TRUE;

        // Interrupt deaktivieren
        UCSRB &= ~(1<<UDRIE);
    }
}

Zum Anfang

Kommentare

# Jürgen Focke meinte am 12. Januar 2007, 22:47 dazu:

Hallo

ich arbeite mich derzeit in die Programmierung des Atmel Mega8 Controllers ein. Von früheren Projekten her kenne ich den Aufwand, den es kostet, in die elementaren Initialisierungen der Peripherie einzusteigen. Daher finde ich die gut dokumentierten Beispiele sehr hilfreich um eine Sammlung von Modulen zu bekommen, die ich in eigene Programme einbauen kann

Danke

Jürgen

# Thomas Schrein meinte am 17. August 2007, 10:32 dazu:

Finde ich prima, Deine Beispiele: arbeite mich, nach langer Pause (Jahre) wieder in das Thema Mikros ein und werde mit Deinen Beispielen als erstes üben. Danke und Gruß Thomas

Deine Meinung:

  • Textformatierung ist mit Markdown möglich.
  • HTML wird entfernt.
  • Kommentare werden moderiert und sind daher eventuell nicht sofort sichtbar.
  • Irrelevante Kommentare werden gelöscht.