PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : usart lt. rn-wissen



Christoph2
28.06.2009, 21:15
Hi!

Ich bin ein totaler usart-neuling, will dass mein roboter endlich mal mit dem pc kommuniziert.

Im rn-wissen bereich habe ich gleich das passende tutorial gefunden:
http://www.rn-wissen.de/index.php/UART_mit_avr-gcc

Ich hab das einfach mal so nachgemacht (die variante mit interrupts).

roboter.c


#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <fifo.h>
#include <uart.h>

// USART KOMMUNIKATION
// Empfangene Zeichen werden in die Eingabgs-FIFO gespeichert und warten dort
SIGNAL (SIG_UART_RECV)
{ _inline_fifo_put (&infifo, UDR);
}
// Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben
// Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert
// Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ.
SIGNAL (SIG_UART_DATA)
{
if (outfifo.count > 0)
UDR = _inline_fifo_get (&outfifo);
else
UCSRB &= ~(1 << UDRIE);
}

int main(void)
{
...
uart_init();
...
while(1) //Hauptschleife
{ ...
}
}

Die datein uart.c, uart.h, fifo.c und fifo.h wurden 1:1 aus dem tutorial entnommen.

Da habe ich jetzt noch nichts übertragen, nur mal initialisiert. Trotzdem erhalte ich schon fehler:
infifo undecleared
outfifo undecleared

infifo und outfifo kommen in der Interruptroutine vor, und die kennt er anscheinend nicht.
Die beiden Variablen sind aber in der Datei uart.c definiert.
Das struct (fifo_t) ist in der Datei fifo.h definiert.


#include <avr/io.h>
#include <avr/interrupt.h>
#include <uart.h>
#include <fifo.h> // erklärt im Artikel "FIFO mit avr-gcc"

#define BAUDRATE 38400UL //Definition als unsigned long, sonst gibt es Fehler in der Berechnung

// FIFO-Objekte und Puffer für die Ein- und Ausgabe

#define BUFSIZE_IN 0x40
uint8_t inbuf[BUFSIZE_IN];
fifo_t infifo;

#define BUFSIZE_OUT 0x40
uint8_t outbuf[BUFSIZE_OUT];
fifo_t outfifo;

void uart_init()
{...
}


Wieso wieso kennt er outfifo und infifo nicht?
Liegt das daran dass die variablen in der Interruptroutine vorkommen?
müssen infifo und outfifo vielleicht globale variablen sein?

lg Christoph

Hubert.G
29.06.2009, 12:01
Ich verwende seit langem ohne Probleme den Code von P.Fleury http://jump.to/fleury
Da gibt es auch eine sehr gute LCD lib.

Christoph2
29.06.2009, 20:38
Danke für den Tipp, ich hab jetzt auch mal die pfleury libary ausprobiert.

jetzt bekomme ich zwar keine errors, dafür habe ich andere probleme.

Ich habe eine zählvariable, die alle 200us (per interrupt) um 1 erhöht wird. wenn dieser zähler den wert 800 (nach ca. 150ms) erreicht, wird er zurückgesetzt, und dem schrittmotorcontroller wird der befehl gegeben, dass er 32 schritte weiter drehen soll. das hat er immer brav getan.

Seit ich die libary drinnen hab tut er das nicht mehr. ich habe am anfang nur das .h und das .c file eingebunden, und am anfang des hauptprogrammes uart_init(); ausgeführt. Da hat noch alles funktioniert.

zum test habe ich einen sharp entfernungssensor so programmiert, dass er, wenn die entfernung weniger als 60cm ist, eine zeichen mit uart_putc('\r'); sendet.

Wenn ich jetzt die hand ca. 40cm vor den entfernungssensor halte, wird der schrittmotor ganz langsam, er bewegt sich nur noch alle 300ms weiter, also nur halb so schnell...

der sendebefehl legt also alles lahm...

woran kann das liegen? muss ich etwas anpassen an der libary?

lg Christoph

Hubert.G
29.06.2009, 23:19
Das kann ich mir schon vorstellen wenn du das Zeichen laufend sendest. Ein Interrupt braucht etwa 70 Takte zum sichern und wieder herstellen, dazu noch das was er in der ISR tun muss. Da kann es schon sein das die UART ISR deinen 200µs Interrupt blockiert.

Christoph2
30.06.2009, 22:56
Ich sende das zeichen ja nicht im 200us sekkunden takt, sondern nur ca. alle 150ms... das sollte doch reichen...

lg Christoph

Hubert.G
30.06.2009, 23:32
Dann kann der UART aber nicht das Problem sein, auch wenn es so aussieht. Kann es sein das du einen Motorbefehl verschluckst wenn du ein Zeichen ausgibst.

Christoph2
30.06.2009, 23:52
naja normalerweise sollte nichts verschluckt werden, weil ja alles interruptgesteuert ist. oder verstehe ich nicht was du meinst?

die uart übertragung funktioniert ja leider nicht, am pc wird am hyperterminal einfach nichts angezeigt. Einmal hatte ich es schon so weit, dass es immer wenn ich ein zeichen zum uC geschickt habe, er immer ein 'p' zurückgeschickt hat. (es war das uart-testprogramm von peter fleury am avr. es schickt einfach jedes empfangene zeichen zurück).

Ich weiß aber nichtmehr warum er das getan hat, wie ich diesen Zustand erreicht habe, und ich schaffe es auch nicht, dass überhaupt irgendwas angezeigt wird. bei mir ist das hyperterminal momentan weiß...

Eingestellt hatte ich
- Bits pro Sekunde: 9600 (wie im programm am uC)
- Datenbits: 8
- Parität: Keine
- Stopbits: 1
- Flusssteuerung: Keine

Die hardware ist eine umsetzung auf rs232 pegel mit dem max232 und dann auf usb mit einem DELOCK USB->DB9 Umsetzer.

Zur hardware habe ich noch eine frage:
Das RX signal vom uC geht auf einen Eingang am max232. Dort wird es umgewandelt und kommt an einem anderen pin wieder heraus. Geht es dann auf den RX oder den TX Pin vom Seriellen Stecker?
Also soll es eine Crossover- oder eine Straight-Through Verbindung sein?

lg Christoph

Hubert.G
01.07.2009, 13:59
Du gehst vom TX des µC auf den TxIN des MAX, TxOUT an Pin2 des Stecker
RX des µC auf RxOUT des MAX, RxIN auf Pin 3 des Stecker.
Ein einfacher HW-Test ist den Kontroller aus der Fassung nehmen, wenn möglich, RX auf TX brücken, Im Terminal ein Zeichen eingeben, das sollte dann als Echo zurück kommen.

Um festzustellen ob sich ein Wurm in deinem Programm befindest müsste man es sehen. Dazu noch welcher Kontroller, welcher Compiler.