Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Laderegler Test Tueftler Seite

(Einen String senden)
(Ohne Interrupts)
Zeile 1: Zeile 1:
= Ohne Receive-Interrupt =
+
= Ohne Interrupts =
 +
 
 +
Hier eine der einfachsten Möglichkeiten, den Harware-[[UART]] von [[AVR]] zu nutzen. Die Empfangs- und Sendefunktionen sind so kurz, daß sie am besten als inline-Funktionen definiert werden. Auf Zeichen bzw. Ereignisse zu warten bezeichnet man auch als "''polling''".
  
Hier eine der einfachsten Möglichkeiten, den Harware-[[UART]] von [[AVR]] zu nutzen. Die Empfangs- und Sendefunktionen sind so kurz, daß sie am besten als inline-Funktionen definiert werden.
 
 
== C-Datei ==
 
== C-Datei ==
  
Der USART wird Initialisiert als UART mit dem Datenformat 8N1 (8 Datenbits, kein Parity, 1 Stopbit). Teilweise haben die Register andere Namen, etwa wenn mehr als ein USART vorhanden ist. Dann Gibt es Register UBRR0L, UBRR1L, etc.
+
Der USART wird Initialisiert als UART mit dem Datenformat 8N1 (8 Datenbits, kein Parity, 1 Stopbit).  
 +
 
 +
Teilweise haben die Register andere Namen, etwa wenn mehr als ein USART vorhanden ist. Dann Gibt es Register UBRR0L, UBRR1L, etc.
 
<pre>
 
<pre>
#include <avr/io.h>
 
 
#include "uart.h"
 
#include "uart.h"
  
Zeile 15: Zeile 17:
 
     uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
 
     uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
 
      
 
      
     UBRRH = (unsigned char) (ubrr>>8);
+
     UBRRH = (uint8_t) (ubrr>>8);
     UBRRL = (unsigned char) (ubrr);
+
     UBRRL = (uint8_t) (ubrr);
 
    
 
    
 
     // UART Receiver und Transmitter anschalten
 
     // UART Receiver und Transmitter anschalten
Zeile 26: Zeile 28:
 
     do
 
     do
 
     {
 
     {
         unsigned char dummy;
+
         uint8_t dummy;
 
         (void) (dummy = UDR);
 
         (void) (dummy = UDR);
 
     }
 
     }
Zeile 37: Zeile 39:
 
Im Header <tt>uart.h</tt> werden die Funktionen veröffentlicht und stehen in anderen Modulen zur Verfügung:
 
Im Header <tt>uart.h</tt> werden die Funktionen veröffentlicht und stehen in anderen Modulen zur Verfügung:
 
;<tt>extern void uart_init()</tt>: Initialisiert den UART und aktiviert Receiver und Transmitter.
 
;<tt>extern void uart_init()</tt>: Initialisiert den UART und aktiviert Receiver und Transmitter.
;<tt>static inline void uart_putc (const char c)</tt>: Sendet das Zeichen <tt>c</tt> über den UART.
+
;<tt>static inline void uart_putc (const uint8_t c)</tt>: Sendet das Zeichen <tt>c</tt> über den UART.
;<tt>static inline int uart_getc_wait()</tt>: Wartet bis zum nächsten Empfang bzw. liefert das empfangene Zeichen im Wertebereich 0...255.
+
;<tt>static inline uint8_t uart_getc_wait()</tt>: Wartet bis zum nächsten Empfang bzw. liefert das empfangene Zeichen.
 
;<tt>static inline int uart_getc_nowait()</tt>: Schaut nach, ob ein Zeichen empfangen wurde und liefert dieses gegebenenfalls als <tt>int</tt> zurück (Wertebereich ist 0...255). Wurde nichts empfangen, wird <tt>-1</tt> geliefert.
 
;<tt>static inline int uart_getc_nowait()</tt>: Schaut nach, ob ein Zeichen empfangen wurde und liefert dieses gegebenenfalls als <tt>int</tt> zurück (Wertebereich ist 0...255). Wurde nichts empfangen, wird <tt>-1</tt> geliefert.
 
Die Defines <tt>F_CPU</tt> und <tt>BAUDRATE</tt> geben die Taktrate des AVR sowie die Baudrate an. Dabei hat <tt>F_CPU</tt> nur rein informativen Character, es ''ändert'' die CPU-Frequenz nicht! Der Define für <tt>F_CPU</tt> kann man in die Quelle dazu schreiben, oder man gibt einen Wert per Kommandozeile/[[make|Makefile]] an mit <tt>-DF_CPU=...</tt>
 
Die Defines <tt>F_CPU</tt> und <tt>BAUDRATE</tt> geben die Taktrate des AVR sowie die Baudrate an. Dabei hat <tt>F_CPU</tt> nur rein informativen Character, es ''ändert'' die CPU-Frequenz nicht! Der Define für <tt>F_CPU</tt> kann man in die Quelle dazu schreiben, oder man gibt einen Wert per Kommandozeile/[[make|Makefile]] an mit <tt>-DF_CPU=...</tt>
Zeile 50: Zeile 52:
  
 
static inline void  
 
static inline void  
uart_putc (const char c)
+
uart_putc (const uint8_t c)
 
{
 
{
 +
    // Warten, bis UDR bereit ist für einen neuen Wert
 
     while (!(UCSRA & (1 << UDRE)))
 
     while (!(UCSRA & (1 << UDRE)))
 
         ;
 
         ;
     
+
 
 +
    // UDR schreiben startet die Übertragung     
 
     UDR = c;
 
     UDR = c;
 
}
 
}
  
static inline int
+
static inline uint8_t
 
uart_getc_wait()
 
uart_getc_wait()
 
{
 
{
 +
    // Warten, bis etwas empfangen wird
 
     while (!(UCSRA & (1 << RXC)))
 
     while (!(UCSRA & (1 << RXC)))
 
         ;
 
         ;
 
+
 
     return (int) UDR;
+
    // Das empfangene Zeichen zurückliefern 
 +
     return UDR;
 
}
 
}
  
Zeile 70: Zeile 76:
 
uart_getc_nowait()
 
uart_getc_nowait()
 
{
 
{
 +
    // Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst
 
     return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
 
     return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
 
}
 
}

Version vom 3. März 2006, 09:20 Uhr

Ohne Interrupts

Hier eine der einfachsten Möglichkeiten, den Harware-UART von AVR zu nutzen. Die Empfangs- und Sendefunktionen sind so kurz, daß sie am besten als inline-Funktionen definiert werden. Auf Zeichen bzw. Ereignisse zu warten bezeichnet man auch als "polling".

C-Datei

Der USART wird Initialisiert als UART mit dem Datenformat 8N1 (8 Datenbits, kein Parity, 1 Stopbit).

Teilweise haben die Register andere Namen, etwa wenn mehr als ein USART vorhanden ist. Dann Gibt es Register UBRR0L, UBRR1L, etc.

#include "uart.h"

#define BAUDRATE 38400

void uart_init()
{
    uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
     
    UBRRH = (uint8_t) (ubrr>>8);
    UBRRL = (uint8_t) (ubrr);
   
    // UART Receiver und Transmitter anschalten
    // Data mode 8N1, asynchron
    UCSRB = (1 << RXEN) | (1 << TXEN);
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

    // Flush Receive-Buffer
    do
    {
        uint8_t dummy;
        (void) (dummy = UDR);
    }
    while (UCSRA & (1 << RXC));
}

Benutzer-Schnittstelle und Header

Im Header uart.h werden die Funktionen veröffentlicht und stehen in anderen Modulen zur Verfügung:

extern void uart_init()
Initialisiert den UART und aktiviert Receiver und Transmitter.
static inline void uart_putc (const uint8_t c)
Sendet das Zeichen c über den UART.
static inline uint8_t uart_getc_wait()
Wartet bis zum nächsten Empfang bzw. liefert das empfangene Zeichen.
static inline int uart_getc_nowait()
Schaut nach, ob ein Zeichen empfangen wurde und liefert dieses gegebenenfalls als int zurück (Wertebereich ist 0...255). Wurde nichts empfangen, wird -1 geliefert.

Die Defines F_CPU und BAUDRATE geben die Taktrate des AVR sowie die Baudrate an. Dabei hat F_CPU nur rein informativen Character, es ändert die CPU-Frequenz nicht! Der Define für F_CPU kann man in die Quelle dazu schreiben, oder man gibt einen Wert per Kommandozeile/Makefile an mit -DF_CPU=...

#ifndef _UART_H_
#define _UART_H_

#include <avr/io.h>

extern void uart_init();

static inline void 
uart_putc (const uint8_t c)
{
    // Warten, bis UDR bereit ist für einen neuen Wert
    while (!(UCSRA & (1 << UDRE)))
        ;

    // UDR schreiben startet die Übertragung      
    UDR = c;
}

static inline uint8_t
uart_getc_wait()
{
    // Warten, bis etwas empfangen wird
    while (!(UCSRA & (1 << RXC)))
        ;

    // Das empfangene Zeichen zurückliefern   
    return UDR;
}

static inline int 
uart_getc_nowait()
{
    // Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst
    return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
}

#endif /* _UART_H_ */

Mit Receive-Interrupt

Weitere Routinen

Einen String senden

Übergeben wird die Start-Adresse des Strings. Die Zeichenkette wird solange durchlaufen und die Zeichen ausgegeben, bis eine '\0' (Stringende-Marke) gelesen wird.

#include "uart.h"

void uart_puts (const char *s)
{
    do
    {
        uart_putc (*s);
    }
    while (*s++)
}

// Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will
// Winwows: "\r\n"
// Linux  : "\n"
// MacOS  : "\r"

char text[] = "Hallo Welt.\r\n";

int main()
{
    uart_init();

    uart_puts (text);
    uart_puts ("Hallo Welt!\r\n");

    return 0;
}

Einen konstanten String senden

Unveränderliche Strings brauchen kein Platz im SRAM zu verschwenden, man lässt sie im Flash (wo sie sonst ebenfalls stehen für die SRAM-Initialisierung).

#include <avr/pgmspace.h>
#include "uart.h"

void uart_puts_P (PGM_P s)
{
    while (1)
    {
        unsigned char c = pgm_read_byte (s);
        s++;
        if ('\0' == c)
            break;
        uart_putc (c);
    }
}

// Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will
// Winwows: "\r\n"
// Linux  : "\n"
// MacOS  : "\r"

const prog_char text_p[] = "Hallo Welt.\r\n";

int main()
{
    uart_init();

    uart_puts_P (text_p);
    uart_puts_P (PSTR("Hallo Welt!\r\n"));

    return 0;
}

Siehe auch

WebLinks


LiFePO4 Speicher Test