AVR UART

Transcrição

AVR UART
27.03.2011
AVR UART
1. Einleitung
In dieser Anleitung soll beispielhaft gezeigt werden, wie die serielle Kommunikation zwischen
einem AVR Mikroprozessor und dem PC aufgebaut wird. Hierbei wird erst der einfache Fall
behandelt, in dem nur Daten vom Mikroprozessor zum PC gesendet werden, um Messdaten
zu erfassen. Der zweite Teil beschreibt anschließend, wie sich Befehle zum Prozessor senden
lassen und per Interrupt verarbeitet werden können, um den zu steuernden Aufbau zu
kontrollieren.
2. Hardware
Diese Anleitung beschränkt sich auf die kleineren Prozessoren der AVR Familie vom
Hersteller Atmel. Die unten verwendeten Bibliotheken wurden auf einem Atmega16
Prozessor getestet, welcher für viele Anwendungszwecke mehr als ausreichend ist. Die
folgende Schaltung soll als Beispielaufbau dienen. Die Pegelwandlung auf den vom PC
verwendeten seriellen Anschluss wird im Beispiel über einen MAX232 IC realisiert. Dies kann
jedoch auch einfacher über einen UART zu USB Controller gebaut werden, da moderne PCs
nur noch selten einen herausgeführten COM Port verfügen.
Hier links zu Fertigbausteinen:
ELV Modul:
http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=28776&flv=1&berei
ch=&marke=
FTDI Kabel:
http://de.farnell.com/ftdi/ttl-232r-3v3/kabel-usb-ttl-level-ser-konverter/dp/1329311
Eine Suche nach den Schlagworten UART TTL USB Converter sollte jedoch für jeden
Anwendungsfall eine passende Fertiglösung bieten.
Diese UART TTL zu USB Konverter erlauben eine einfache und wenig fehleranfällige
Verbindung zwischen MCU und PC. Sie werden an den Pins PD0(RXD) und PD1(TXD)
angeschlossen und ersetzen die Pegelwandlerschaltung des MAX232 ICs.
1
27.03.2011
!!!Pinbelegung für Atmega16 im TQFP Gehäuse!!!
!!!Für eigene Schaltung bitte selbst prüfen!!!
Abbildung 1: Beispielschaltung Atmega16 (Pinbelegung für TQFP Gehäuse!) mit MAX232
Abbildung 2: RS232 Stecker
Bei der Verbindung vom Stecker zum Pegelwandler müssen RX und TX vertauscht werden, d.h. PIN1
im Schaltplan auf PIN2 am Stecker, PIN2 im Schaltplan PIN3 und PIN 3 im Schaltplan auf PIN5.
Die Verbleibenden Pins können offen gelassen werden (wenn keine Flusssteuerung gewünscht ist,
Normalfall).
2
27.03.2011
3. Software
Um die UART Schnittstelle der MCU verwenden zu können, muss sie erst initialisiert werden.
Dies wird durch Einstellen der verwendeten Baudrate (9600Baud sollte immer gehen) im
Headerfile des Projekts und durch den Aufruf der Funktion void uart_init(void) vor der
Verwendung erledigt.
To Do:
a. CPU Takt definieren (AVR Studio, Rechtsklick aufs Projekt, Edit Configuration
Options, Frequency in Hz eintragen)
b. Einfügen der Baudratenberechnung ins Headerfile
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
//USART DEFS
#define BAUD 9600UL
// Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
c. Einfügen der Datei usart.c ins Projekt (.c Datei aus Quellcode unten erstellen)
d. Aufrufen der Funktion uart_init(void); im Hauptprogramm
e. Sollen auch Daten empfangen werden können, muss noch folgende ISR (Interrupt
Service Routine) eingebaut werden (vor dem Hauptprogramm) und der Interrupt
global eingeschalten werden mit der Funktion sei();. Sie liefert die empfangenen
Werte als String in uart_string[].
#define uart_maxstrlen 10
// Definiere maximale Laenge für Empfang
volatile uint8_t uart_str_complete=0;
volatile uint8_t uart_str_count=0;
volatile char uart_string[uart_maxstrlen+1]="X";
ISR(USART_RXC_vect)
{
unsigned char buffer;
}
buffer = UDR;
if ( uart_str_complete==0 )
{
if (buffer!='\n' && buffer!='\r' && uart_str_count<uart_maxstrlen-1)
{
uart_string[uart_str_count]=buffer;
uart_str_count++;
} else {
uart_string[uart_str_count]='\0';
uart_str_count=0;
uart_str_complete=1;
}
}
Rücksetzen der Variable
uart_str_complete in main(), wenn
der String empfangen wurde.
3
27.03.2011
Die Datei usart.c enthält folgende Funktionen die für die Projekte relevant sind:
•
•
•
uart_init(); wird benötigt, um UART zu initialisieren
uart_putc(); sendet einzelnes Zeichen an PC
uart_puts(char* s); sendet String an PC bis Null erreicht wird
Die folgenden Funktionen sollten besser über die Interrupt Lösung realisiert werden:
•
•
uart_getc(); empfängt einzelnes Zeichen vom PC
uart_gets(char* Buffer, uint8_t MaxLen); empfängt String
Um den einfachen Fall zu betrachten, wird nun eine Terminal Verbindung aufgebaut. Da
Windows Vista / 7 nicht mehr über das bekannte HyperTerminal mehr verfügen, wird
empfohlen sich folgende Programme anzusehen.
Termite:
http://www.compuphase.com/software_termite.htm
HTerm:
http://www.der-hammer.info/terminal/index.htm
Im hier gezeigten Beispiel wird das Terminal Programm Termite verwendet.
4
27.03.2011
4. Verbindungsaufbau und Datenübertragung
Diese kleine Demo soll zeigen, wie die oben gezeigten Funktionen in einem Aufbau
funktionieren.
Die folgende Abbildung zeigt schematisch den Aufbau
RX
TX
ISP bzw. JTAG
ELV USB
Konverter
Atmega16
Versorgungsspannung (5V)
RX
TX
NICHT ÜBER USB VERSORGEN
UND AUSLESEN GLEICHZEITIG
Abbildung 3: Schematischer Aufbau und Testaufbau
5
USB
PC
27.03.2011
Nun kann die Entwicklungsumgebung gestartet und das Testprojekt erstellt werden. In
diesem Fall wird AVR Studio 4.18 SP1 verwendet und als Programmer der AVR Dragon.
Ist AVR Studio gestartet, wird ein neues AVR GCC Projekt angelegt und die für das System
entsprechenden Einstellungen für den Prozessor und Debugger festgelegt (Atmega16 und
AVR Dragon).
mit einem Klick auf Finish wird das Projekt erstellt.
8 Mhz eintragen und mit OK bestätigen.
6
27.03.2011
Nun folgendes Testprogramm in die UART_ELV_MODUL.c Datei einfügen
#include
#include
#include
#include
<avr/io.h>
<inttypes.h>
<avr/interrupt.h>
<util/delay.h>
#define F_CPU 8000000UL
//USART DEFS
#define BAUD 9600UL
// Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define uart_maxstrlen 25
// Definiere maximale Laenge für Empfang
volatile uint8_t uart_str_complete=0;
volatile uint8_t uart_str_count=0;
volatile char uart_string[uart_maxstrlen+1]="Test";
ISR(USART_RXC_vect)
{
unsigned char buffer;
buffer = UDR;
if ( uart_str_complete==0 )
{
if (buffer!='\n' && buffer!='\r' && uart_str_count<uart_maxstrlen-1)
{
uart_string[uart_str_count]=buffer;
uart_str_count++;
} else {
uart_string[uart_str_count]='\0';
uart_str_count=0;
uart_str_complete=1;
}
}
uart_str_complete=0;
}
void uart_init(void)
{
UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); // UART RX, TX und RX Interrupt einschalten
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}
int uart_putc(unsigned char c)
{
while (!(UCSRA & (1<<UDRE)))
{
}
UDR = c;
return 0;
}
7
27.03.2011
void uart_puts (char *s)
{
while (*s)
{
uart_putc(*s);
s++;
}
}
uint8_t uart_getc(void)
{
while (!(UCSRA & (1<<RXC)))
;
return UDR;
}
// warten bis Zeichen verfuegbar
// Zeichen aus UDR an Aufrufer zurueckgeben
void uart_gets( char* Buffer, uint8_t MaxLen )
{
uint8_t NextChar;
uint8_t StringLen = 0;
NextChar = uart_getc();
// Warte auf und empfange das nächste Zeichen
// Sammle solange Zeichen, bis:
// * entweder das String Ende Zeichen kam
// * oder das aufnehmende Array voll ist
while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
*Buffer++ = NextChar;
StringLen++;
NextChar = uart_getc();
}
// Noch ein '\0' anhängen um einen Standard
// C-String daraus zu machen
*Buffer = '\0';
}
int main (void)
{
uart_init();
sei();
while(1)
{
uart_puts(uart_string);
uart_puts("\n");
_delay_ms(500);
}
}
In dem oben angegebenen Programm wurden Teile des auf www.mikrocontroller.net
veröffentlichten Tutorials verwendet.
8
27.03.2011
Im Anschluss kann das Projekt kompiliert und auf das Zielgerät (Atmega16) übertragen
werden.
Programmiermodus wählen und Signatur abgleichen.
9
27.03.2011
Nun FUSES setzen.
LOW FUSE auf 0xE4 setzen den HIGH FUSE auf default (nicht JTAG abschalten !).
HEX Datei wählen aus dem Ordner Default des Projekt. ACHTUNG, wird nicht automatisch
aus aktuellem Projekt gewählt!!!
Flashen mit klicken auf Programm.
10
27.03.2011
Nun kann AVR Studio geschlossen und das Terminal Programm Termite gestartet werden.
Mit Settings nun Parameter einstellen
Kann im Gerätemanager eingesehen
werden
Ist die Verbindung, korrekt sollte der Teststring ankommen.
11
27.03.2011
Um den Interrupt zu testen, senden wir nun einen String, den der Prozessor wie im
Programm definiert, wieder als Endlosschleife zurück sendet.
HIER TEXT EINGEBEN und Senden!
Zur Messwertübertragung weitere brauchbare Funktionen sind:
itoa:
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/
atoi:
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
dtostrf(float,int,int,char*)
float -> string
Viel Spaß bei den Projekten!
Hilfe zum Thema:
[email protected]
12

Documentos relacionados