PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Programmieren



Joern S.
15.04.2012, 21:41
Moin,
kennt sich einer mit der UART programmierung von µC aus?
Ich habe folgenden Programmcode aus Beispielen kopiert, soweit ohne Fehler, nur leider weiß ich nicht ob er funktioniert oder nicht. Mein PC gibt mir beim RS232 Anschluss keine Signale raus. Ich habe aber leider keine Ahnung zu dem Thema, nur benötige bald ein Programm womit ich Signale über Funk (RS232) verschicken kann. Als µC habe ich den Atmega 8515-PU genutzt. Falls mir noch so einer Tipps geben kann wäre ich sehr dankbar.
Mein Programm:

#include "uart.h"

#define BAUDRATE 38400UL//Definition als unsigned long, sonst gibt es Fehler in der Berechnung
#define F_CPU 8000000
void uart_init (void)
{
uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
UBRRL = ubrr; //Baudrate 38400
UCSRA|=2; //Doppelte Baudrate
UCSRB=0x18; //RX und TX erlaubt


// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
do
{
UDR;
}
while (UCSRA & (1 << RXC));
}

int main(void)
{
uart_init ();
while(1)
{
int a;
uart_putc(1001);
}

}


Die dazu benötigte UART.h:

#ifndef UART_H
#define UART_H

#include <avr/io.h>

extern void uart_init (void);

static inline int
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;

return 1;
}

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

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

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

#endif /* UART_H */

021aet04
16.04.2012, 07:53
Was verwendest du am PC?

MfG Hannes

Joern S.
16.04.2012, 12:30
Als PC verwende ich mein laptop mit Win 7 32 Bit (COm funktionert)
Als Programm verwende ich den 232 Analyzer mit der schnittstelle: http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=67&products_id=250
Wollte erst einmal so testen ob daten irgendwohin gesendet werden, befor ich mich dann mit Empfang bei einem µC beschäftige

021aet04
17.04.2012, 08:05
Ich habe den gleichen USB RS232 Wandler allerdings von ELV (http://www.elv.at/output/controller.aspx?cid=74&detail=10&detail2=28776&flv=1&bereich=&marke=). Da ich Probleme mit Labview gehabt habe habe ich auch ein Terminalprogramm gesucht. Ich habe das Programm "Terminal by Br@y++" (https://sites.google.com/site/terminalbpp/) verwendet. Habe alles gleich eingestellt wie mit dem µC und es hat funktioniert. Hast du schon versucht RX und TX zu verbinden und und zu prüfen ob du so etwas empfängst? Du kannst, wenn du ein Oszi hast, schauen ob Daten über die Schnittstelle gesendet werden. Du kannst auch eine Led anschließen und die Übertragungsrate herunterstellen (z.B. 600Baud oder 1200Baud).

MfG Hannes

Joern S.
17.04.2012, 12:12
sorry irgendwas will bei mir nicht funktionieren.
Mein Analyseprogramm empfängt imemr daten, auch wenn ich rx/tx getrennt habe und deines keine daten^^

Kannst du mal den Programmcode bei dir testen, ob du damit empfang hast?

021aet04
18.04.2012, 08:01
Testen kann ich es leider nicht da ich keinen Atmega8515 habe. Ich habe Atmega 88, 1280, einen Atmega8 bzw Attiny 44, 45 und 2313.

Bei deiner UART.h sind Berechnungen eingebaut. Normalerweise macht man das nicht. In die UART.h würde man nur Definitionen einbauen (schau einmal die Headerdateien an die bei AVR Studio dabei sind). Programmcode kommt in eine C-Datei. Das hat aber nichts mit der Funktion zu tun. Man macht es nur nicht.

Habe den Code durchgeschaut. Beim Hauptprogramm steht in "void uart_init (void)" in der ersten Zeile " uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);". Was soll das bedeuten? Das wird zu keinem Ergebnis führen. Besser ist es wenn man die Berechnung per Hand ausrechnet und diese als Variable hinschreibt.

Damit man den Code besser lesen kann sollte man nicht z.B. "UCSRA |= 2;" schreiben sondern "UCSRA |= (1<<U2X);". So sieht man auf einen Blick was man gesetzt und was man nicht gesetzt hat.
UCSRC passt?

Probier einmal die von mir gepostete Zeile zu ändern. Ansonsten müsste ich weiter schauen.

MfG Hannes

Joern S.
18.04.2012, 11:33
Hab es umgeändert und da ich das STK600 habe und dem COmport vom PC nicht ganz vertraue, habe ich den PORTD (welcher beim 8515 der UART bereich ist) an die vorhandenen LED's gehängt. Wenn ich ein Zeichen schicke, (uart_putc("C");) dann leuchtet die 2. LED auf, wenn ich nichts schicke dann leuchtet sie nicht auf.
Kann ich dann davon ausgehen, dass das Programm soweit funktioniert?
Zur Info, die LED's leuchten bei einem Low Pegel auf, weiß nicht ob es bei anderen Boards anders geregelt wird.

021aet04
18.04.2012, 12:58
Wenn die Leds leuchten sieht es nicht schlecht aus. Hast du die Baudrate heruntergestellt oder auf die 38400Baud gelassen? Normalerweise sollte die Led flackern, das kann man aber bei einer hohen Baudrate nicht erkennen. Oszi wäre optimal.

Du kannst jetzt versuchen die Schaltung mit dem PC zu verbinden. Achte auch auf die Fehler mit den Baudraten (ist eine Tabelle mit Taktfrequenzen und Baudraten). Die Fehlerrate sollte nicht zu groß sein (optimal wäre 0%). Je höher der Fehler desto unsicherer wird die Verbindung.

MfG Hannes

Joern S.
18.04.2012, 13:25
ja wenn ich die Baud auf 70 runterschraube dann kann man ein flackern erkennen..
Wenn ich jetzt mit einem anderen µC verbinde und die Daten empfangen will, kann ich dann schreiben


char test;
test= uart_getc_nowait();//Dies ist im uart.h deklariert


Und wenn ich dann ein "C" sende steht dann in der test-Variable ebenfalls ein "C"
Wie gesagt ich kenne mich damit nicht großartig aus

021aet04
19.04.2012, 09:05
Du kannst 2 µC einfach miteinander verbinden (RX mit TX und TX mit RX). Wenn du die Baudraten gleich hast kannst du senden. Hast du schon eine Verbindung mit dem PC? Empfängst du etwas?
Auf Microkontroller.net ist ein gutes AVR GCC Tutorial. U.A. findet man auch die UART Verbindung. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART
Dort sieht man genau was man machen muss wenn man ein bestimmtes Zeichen senden will oder wie man Variablen überträgt.

Der UART, den es im RN-Wissen gibt kennst du vermutlich schon, Trotzdem noch der Link http://www.rn-wissen.de/index.php/UART_mit_avr-gcc

MfG Hannes

Joern S.
19.04.2012, 17:46
Nee mein PC empfängt ncihts, muss aber nicht daran liegen, dass das Programm nicht läuft, ich vermute eher das die Schnittstelle mal was abbekommen hat.
Habe sowieso vor nachher das von µC zu µC zu schicken.
Die Seite von RN-Wissen kannte ich schon, davon habe ich das Programm kopiert, nur nicht verstanden^^, die von mokrocontroller kannte ich noch nicht, hatte da nur Assambler beispiele gefunden

021aet04
20.04.2012, 08:48
Wenn du von µC zu µC Daten sendest brauchst du nur auf die gleichen Kommandos achten. Z.B. wenn du beim µC zum schreiben "UDR = 'c';" schreibst musst du beim Empfangenden µC auch auf " 'c' " achten.

Wie du die Daten in das UDR Register schreibst ist eigentlich egal. Ob etwas ankommt kannst du auch mit einem Interrupt bzw Interruptflag überprüfen (es gibt einen Interruptvektor der sich "USART_RXC" nennt).

Dann weißt du ob Daten empfangen werden.

MfG Hannes

Joern S.
21.04.2012, 22:17
ich dank dir für die Hilfe,
hab es gerade mit dem Senden der Infos von µC zu µC ausprobiert, und mit einer kleinen änderung für den Empfänger funktioniert es auch wunderbar.
falls es einem interresiert wie es mit dem empfang ist:


uart_getc_nowait();
PORTB=UDR;//Empfangenes Signal wird an 8LEDS getest


Nun kann ich mich mit dem nächsten schritt befassen und das signal via Funk übertragen

021aet04
22.04.2012, 11:20
Glückwunsch das es funktioniert. Weiterhin viel Erfolg.

MfG Hannes