PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART benutzen - Bibliothek einbinden



runner02
10.01.2011, 15:44
Hallo an alle,

Ich würde furchtbar gerne den UART des AVRs nutzen lernen,,,,

Nun habe ich mich darüber im Tutorial schlau gemacht und das alles ist sehr hoch, mit vielen Interrupts,....


Gibt es dazu eine fertige Bibliothek, aus der ich einfach 'get UART' als Befehl bekomme (wie z.B. in BASCOM) und 'send UART' ??

Ich habe bis jetzt noch keine Bibliothek eingebunden, wie macht man sowas, und was kann man dabei falsch machen?


Ich nehme an, wenn es so eine Datei gibt, muss ich sie auf meiner Festplatte im Quellordner meines Compilers speichern, damit ich darauf zugreifen kann, und danach #includeUART.h oder so in jedes Programm einfügen??? :-k



Danke im Vorraus O:)

pc-fan
10.01.2011, 17:24
Hi runner02,

guck dir mal auf folgender Seite die UART library an:
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

Weitere Infos findest du hier:
http://www.rn-wissen.de/index.php/UART_mit_avr-gcc

Gruß
pc-fan

runner02
11.01.2011, 10:54
Dumme Frage: Ist die library schon im Compiler oder muss ich sie erst runterladen und hineinziehen??


Defines
#define UART_BAUD_SELECT(baudRate, xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
UART Baudrate Expression.

#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate, xtalCpu) (((xtalCpu)/((baudRate)*8l)-1)|0x8000)
UART Baudrate Expression for ATmega double speed mode.

#define UART_RX_BUFFER_SIZE 32
#define UART_TX_BUFFER_SIZE 32
#define UART_FRAME_ERROR 0x0800
#define UART_OVERRUN_ERROR 0x0400
#define UART_BUFFER_OVERFLOW 0x0200
#define UART_NO_DATA 0x0100
#define uart_puts_P(__s) uart_puts_p(PSTR(__s))
Macro to automatically put a string constant into program memory.

#define uart1_puts_P(__s) uart1_puts_p(PSTR(__s))
Macro to automatically put a string constant into program memory.



Functions
void uart_init (unsigned int baudrate)
Initialize UART and set baudrate.

unsigned int uart_getc (void)
Get received byte from ringbuffer.

void uart_putc (unsigned char data)
Put byte to ringbuffer for transmitting via UART.

void uart_puts (const char *s)
Put string to ringbuffer for transmitting via UART.

void uart_puts_p (const char *s)
Put string from program memory to ringbuffer for transmitting via UART.

void uart1_init (unsigned int baudrate)
Initialize USART1 (only available on selected ATmegas).

unsigned int uart1_getc (void)
Get received byte of USART1 from ringbuffer. (only available on selected ATmega).

void uart1_putc (unsigned char data)
Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega).

void uart1_puts (const char *s)
Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega).

void uart1_puts_p (const char *s)
Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega).



Das alles muss ich dann definier und verwenden??

Bei den Defines muss ich dann noch die Zahlen einfühen (CPU-Takt = 1000000L)??


ich nehme also alle defines (brauche ich die alle, oder werden die bei include mitgenommen?)

und folgendes:

Sender:
#include "uart.h"
#define....

main{
void uart_init(unsigned int 1000000)
void uart_putc
}

Empfänger:
#include "uart.h"
#define...

main{
void uart_init(unsigned int 1000000)
unsigned int uart_getc (void)
}

Und das wars???

pc-fan
11.01.2011, 15:31
Hallo runner02,

es gibt keine dummen Fragen! O:)

Am besten lädst du dir einfach mal die UART Library von Peter Fleury runter. Diese nutzt Interrupts, aber keine Angst, davon bekommst du gar nichts mit.
Was du brauchst sind die Dateien uart.c und uart.h diese kopierst du in dein Projektverzeichnis (Verzeichnisses des Programms an dem du gerade arbeitest).
In der main.c musst du noch die uart.h includen:


#include "uart.h"

Wichtig ist hier, dass du uart.h in Anführungszeichen schreibst!

Als nächstes musst du in der main.c die Baudrate definieren:


#define UART_BAUD_RATE 9600


Nun musst du die Schnittelle initialisieren, dies geschieht in der Hauptschleife deines Programms (Das hinter int main(void) { ... in der main.c):


int main(void)
{
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
}


Jetzt musst du noch Interrupts erlauben, dies geschieht mit:


sei();


Ein kleine Beispiel main.c, von Peter Fleury, die die Empfangenen Daten einfach wieder zurücksendet sieht wie folgt aus:


/************************************************** ***********************
Title: example program for the Interrupt controlled UART library
Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
File: $Id: test_uart.c,v 1.4 2005/07/10 11:46:30 Peter Exp $
Software: AVR-GCC 3.3
Hardware: any AVR with built-in UART, tested on AT90S8515 at 4 Mhz

DESCRIPTION:
This example shows how to use the UART library uart.c

************************************************** ***********************/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>

#include "uart.h"


/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 4000000UL
#endif

/* 9600 baud */
#define UART_BAUD_RATE 9600


int main(void)
{
unsigned int c;
char buffer[7];
int num=134;


/*
* Initialize UART library, pass baudrate and AVR cpu clock
* with the macro
* UART_BAUD_SELECT() (normal speed mode )
* or
* UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
*/
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

/*
* now enable interrupt, since UART library is interrupt controlled
*/
sei();

/*
* Transmit string to UART
* The string is buffered by the uart library in a circular buffer
* and one character at a time is transmitted to the UART using interrupts.
* uart_puts() blocks if it can not write the whole string to the circular
* buffer
*/
uart_puts("String stored in SRAM\n");

/*
* Transmit string from program memory to UART
*/
uart_puts_P("String stored in FLASH\n");


/*
* Use standard avr-libc functions to convert numbers into string
* before transmitting via UART
*/
itoa( num, buffer, 10); // convert interger into string (decimal format)
uart_puts(buffer); // and transmit string to UART


/*
* Transmit single character to UART
*/
uart_putc('\r');

for(;;)
{
/*
* Get received character from ringbuffer
* uart_getc() returns in the lower byte the received character and
* in the higher byte (bitmask) the last receive error
* UART_NO_DATA is returned when no data is available.
*
*/
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
uart_puts_P("Buffer overflow error: ");
}
/*
* send received character back
*/
uart_putc( (unsigned char)c );
}
}

}

Die Kommentare in der uart.h sind ebenfalls sehr hilfreich.

Viel Glück und Gruß
pc-fan

PS: Wenn noch etwas unklar ist, kannst du ja einfach nochmal Fragen. Dann wäre es allerdings hilfreich zu wissen was für einen AVR du verwendest und mit was für einem Quarz.

runner02
11.01.2011, 19:23
Bis jetzt programmiere ich mit ATtiny13.

Originalgefused auf 1 Mhz.

Die Baudrate sollte deutlich unter der Taktfrequenz (hier <1Mhz) sein, denke ich mal... Ist die größe egal (wenn beide Chips die selbe haben)??


Danke für deinen Aufwand... Werde das gleich ml probieren, hoffe es klappt (nach möglichst wenig Kinderkrankheiten) ;)

pc-fan
11.01.2011, 19:45
Hallo runner02,

laut http://www.kreatives-chaos.com/artikel/baudraten-tabelle-fuer-avrs kommst du mit den 1 MHz bei akzeptablem Fehler auf maximal 4800 baud.
Wenn du deine Daten schneller übertragen möchtest, solltest du eine schnellere Taktquelle verwenden, z.B. einen externen Quarz. Wie du in der Tabelle hinter dem obigen Link siehst, gibt es auch bestimmte Quarze mit "krummen" Frequenzen (z.B. 1,8432 MHz), das sind so genannte Baudratenquarze. Welchen du letztendlich verwendest, musst du entscheiden.

Gruß
pc-fan

EDIT:
Apropos Baudratenquarz, weitere Infos dazu findest du auch noch hinter folgendem Link:
http://www.mikrocontroller.net/articles/Baudratenquarz

runner02
12.01.2011, 12:43
Als blutjunger Anfänger :D möchte ich alles so simpel wie möglich gestalten.

Also F_CPU 1Mhz ; Baudrate 4800....

Danke übrigens fürs Nachsehen....



Wenn das erstmal so klappt, kann ich mich ja später noch mit umfusen, externen Quarz, etc. spielen ;)

runner02
12.01.2011, 20:05
Wo rein muss ich die beiden Datein nochmal ziehen??

Da gibt es so viele Ordner im Ordner

C:\Programme\myAvrWorkpadPlusDemo
-> \WinAVR

da gibt es wiederrum source, mfile, sample, lib, libexec, avr, utils.... uvm....

hardware.bas
12.01.2011, 20:47
Da das ein "compilerunabhängiges" Problem ist, kann ich ja was dazu
bemerken. Wenn Du wirklich die UART richtig kennenlernen willst und
damit ausgedehnte Experimente machen willst, dann sind die wenigen
Cent für einen Baudraten-Quarz und 2 Cs zu 22pF dringend empfehlens-
wert. Du sparst Dir Ärger. Bei liefen mit freilaufenden Oszillator auch
schon 4800 schlecht und 2400 mit Aussetzern. Es ist auch sehr
temperaturabhängig. VG Micha

pc-fan
20.01.2011, 14:38
Hi runner02,

sorry, dass ich mich erst jetzt wieder melde.

Die Dateien musst du einfach in das Verzeichnis kopieren, wo auch die main.c von deinem aktuellen Projekt liegt.

Viel Glück!
pc-fan

runner02
21.01.2011, 18:17
sorry, dass ich mich erst jetzt wieder melde.

Kein Problem,

Hatte in der Zwischenzeit sowieso einen Haufen Arbeit mit einem Temperatursensor ;)



von deinem aktuellen Projekt
Also gibt es da keinen globalen Ordner für die defines, sondern ich muss sie bei jedem Projekt einzeln einfügen?

Mfg

pc-fan
21.01.2011, 18:23
Hallo runner02,


Also gibt es da keinen globalen Ordner für die defines, sondern ich muss sie bei jedem Projekt einzeln einfügen?

Jain, es geht so weit ich weiß beides, aber jetzt machs erst mal global.

Gruß
pc-fan