PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schaut euch mal bitte diesen Code an:



jagdfalke
26.11.2005, 18:31
#include <avr/io.h>
#include <avr/sfr_defs.h>

#define F_CPU 8000000 // 8MHz Taktfrequenz
#define BAUD_RATE 9600 // gewünschte Baud-Rate für UART


void uart_put(char c) {
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
}

void uart_puts(char *s) {
while(*s) {
uart_put(*s);
s++;
}
uart_put('\n');
uart_put('\r');
}

uint8_t uart_get(void) {
loop_until_bit_is_clear(UCSRA, RXEN);
return UDR;
}

void uart_init(int tx, int rx) {
UBRRL = (F_CPU/(BAUD_RATE*16l)-1);
if(tx == 1) {
UCSRB |= (1<<TXEN);
}
if(rx == 1) {
UCSRB |= (1<<RXEN);
}
}

int main (void) {
uart_init(1, 1);

while(1)
{
char c = uart_get();
uart_put(c);
uart_put('\n');
uart_put('\r');
}

return 0;
}



Das Programm soll ein Zeichen empfangen und es gleich wieder ausgeben. Es funktioniert soweit ganz gut, aber wenn er einmal angefangen hat ein Zeichen auszugeben hört er nicht mehr auf damit. Woran liegt das?

mfg
jagdfalke

recycle
26.11.2005, 18:48
Ich kann zwar kein c, aber dass while(1) eine Bedingung ist die immer zutrifft gilt vermutlich in jeder Sprache.
D.h. du hast da eine Endloschleife gebaut und in der Schleife gibt es nirgendwo einen Befehl der das Programm veranlassen könnte diese Schleife wieder zu verlassen.

michaelb
26.11.2005, 19:08
Hi Jagdfalke,
ich bin der gleichen Meinung wie recycle! Auch wenn du kein Zeichen mehr an den AVR sendest sendet dein µC das letzte an den PC denn er bleibt in der Einlese und Senderoutine!

Ich würde das so lösen:
1. Lösung mit Interrupt:
-> in der Main läuft ne Endlosschleife
-> den UART Empfang als nen Interrupt schalten
-> sobald das Programm die ISR gesprungen ist das empfangene Byte auslesen und zurück schicken

2. Lösung mit If Auswertung:
-> in der Main läuft ne Endlosschleife
-> innerhalb dieser Schleife überprüfen ob das RXC Bit im UART Status Register gesetzt ist
-> trifft das zu Daten einlesen und wieder ausgeben

Gruß Michi

jagdfalke
26.11.2005, 19:12
Also ich habs rausgefunden:
RXC ist gesetzt, wenn ungelesene Daten da sind. Dh ich hab RXEN mit RXC verwechselt und loop_until_bit_is_clear muss mit loop_until_bit_is_set ausgetauscht werden.

Das while soll schon so sein, da er ja immer wenn ein Zeichen kommt es ausgeben soll.

Trotzdem danke für die Mühe. mfg
jagdfalke

michaelb
26.11.2005, 19:19
Hi,
aber die Variable c wird ja immer gesendet!! egal ob nun ein neues Zeichen oder kein neues drinsteht!
Gruß Michi

jagdfalke
26.11.2005, 19:41
nö, weil in uart_get ist ja ein loop_unti_bit_is_set
Hier mal der geupdatete funktionierende code:


#include <avr/io.h>
#include <avr/sfr_defs.h>

#define F_CPU 8000000 // 8MHz Taktfrequenz
#define BAUD_RATE 9600 // gewünschte Baud-Rate für UART

void uart_println(char *s, int len) {
while(len--) {
loop_until_bit_is_set(UCSRA, UDRE);
UDR = *s;
s++;
}
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '\n';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '\r';
}

uint8_t uart_readChar(void) {
loop_until_bit_is_set(UCSRA, RXC);
return UDR;
}

void uart_init(int tx, int rx) {
UBRRL = (F_CPU/(BAUD_RATE*16l)-1);
if(tx == 1) {
UCSRB |= (1<<TXEN);
}
if(rx == 1) {
UCSRB |= (1<<RXEN);
}
}

int main (void) {
uart_init(1, 1);

while(1)
{
char c = uart_readChar();
char result[2];
result[0] = c;
result[1] = 0;
uart_println(result, 1);
}

return 0;
}

michaelb
26.11.2005, 19:49
ups sorry hab ich übersehen! 8-[ 8-[
Gruß Michi