Hi,
Ich kann auf dem HyperTerminal alle gesendeten Strings, Zeichen etc.
korrekt sehen, das Senden klappt also. Aber wenn ich was in den
HyperTerminal tippe, kann mein ATmega32 nichts empfangen. Hab den
Standard-code aus dem Manual ausprobiert.
1
unsignedcharUSART_receive(void)
2
{
3
/* Wait for data to be received */
4
while(!(UCSRA&(1<<RXC)))
5
;
6
/* Get and return received data from buffer */
7
returnUDR;
8
}
9
10
voidUSART_transmit(unsignedchardata)
11
{
12
/* Wait for empty transmit buffer */
13
while(!(UCSRA&(1<<UDRE)))
14
;
15
/* Put data into buffer, sends the data */
16
UDR=data;
17
}
18
19
intmain(void)
20
{
21
UCSRB|=(1<<RXEN)|(1<<TXEN);// Turn on the transmission and reception circuitry
22
UCSRC|=(1<<URSEL)|(3<<UCSZ0);// Use 8N1
23
24
UBRRL=BAUD_PRESCALE;// Load lower 8-bits of the baud rate value into the low byte of the UBRR register
25
UBRRH=(BAUD_PRESCALE>>8);// Load upper 8-bits of the baud rate value into the high byte of the UBRR register
26
27
UCSRB|=(1<<RXCIE);// Enable the USART Recieve Complete interrupt (USART_RXC)
28
29
sei();// Enable the Global Interrupt Enable flag so that interrupts can be processed
30
31
32
charReceivedByte;
33
34
for(;;)// Loop forever
35
{
36
USART_transmit('_');//klappt
37
ReceivedByte=USART_receive();//klappt nicht :(
38
}
39
}
Kann es sein, das evtl. der rx-teil des Kabels defekt ist oder sowas?
Gruß,
Jimmy
@ Jimmy (Gast)
>HyperTerminal tippe, kann mein ATmega32 nichts empfangen. Hab den>Standard-code aus dem Manual ausprobiert.
Dein Quelltext sieht OK aus.
>Kann es sein, das evtl. der rx-teil des Kabels defekt ist oder sowas?
Möglich. Klemm einfach mal das TX Pin des MAX232 vom AVR ab und verbinde
es mit dem RX Pin. Dann müssten die Zeichen zurückkommen. Wenn nicht ist
dein Kabel oder Pegelwandler defekt.
MFG
Falk
UCSRB|=(1<<RXCIE);// Enable the USART Recieve Complete interrupt (USART_RXC)
3
sei();
4
// ...
Jimmy, wo ist dein Interrupthandler? Bzw. was soll dieser Code, wenn
dein USART_receive ein stinknormales RS232-Polling macht?
Und im Code oben fehlen noch Teile (mindestens die Includes und ein paar
Defines).
Und woran meinst du genau zu erkennen, dass auf dem Atmega32 keine
Zeichen empfangen werden?
Mhhja, soll eigentlich interrupt gesteuert funktionieren, da aber das
Empfangen nicht ging, hab ich den "einfachsten" Code ausprobiert. Nun
ja, war wirklich ein Kabeldefekt. Empfangen funktioniert jetzt prima,
danke für die Mühe, Jungs.
Hallo Jimmy,
ich habe jetzt das gleiche Problem wie du,
könntest du mir bitte dein Code senden, damit ich Senden und Empfangen
mit USART schaffen kann.
DANKE.
1) Rücke deinen Code ein!
2) entscheide dich, ob du den Empfang mittels Interrupt oder mittels
Polling machen willst und wirf den jeweils anderen Code raus. Auf
Dauer verwirrt das, wenn beide Möglichkeiten im Code vorhanden sind.
3) Rücke deinen Code ein
Berücksichtige ich Punkt 1) und Punkt 3), dann lande ich bei
1
intmain(void)
2
{
3
//DDRD = 0xFF;
4
//PORTD = 0xFF;
5
uart_init();
6
//sei();
7
8
while(1)
9
{
10
uart_puts(uart_string);
11
uart_puts("\n");
12
_delay_ms(5);
13
}
14
}
Ein kurzer Blick in die uart_init Funktion zeigt mir
1
voiduart_init(void)
2
{
3
UCSR1A|=(1<<U2X1);
4
UCSR1B|=(1<<RXEN1)|(1<<TXEN1);//|(1<<RXCIE1); // UART RX, TX und RX Interrupt einschalten
dass Interrupts nicht eingeschaltet sind, was ok ist. Das bedeutet aber
auch, du musst die Funktion uart_gets aufrufen, damit irgendein Code
einen empfangenen String in das Array uart_string schreibt. Wieder
zurück in die main() Funktion: Wo genau ist denn da jetzt der Aufruf der
Funktion uart_gets? Ich kann keinen entdecken.
Sagte ich schon, dass du deinen Code einrücken sollst? Code
übersichtlich anzuordnen ist ein nicht ganz unwesentlicher Baustein,
wenn es darum geht zu analysieren, wass denn eigentlich der Code macht,
bzw. nicht macht. Dazu gehören Einrückungen genauso, wie es Leerzeilen
sind, die man nach funktionalen Blöcken einfügt (zb wenn die
Initialisierung in main() beednet ist und die Hauptschleife beginnt) um
dort dem Gehirn einen optischen Trenner zu präsentieren. Das schlimmste
was du tun kannst: Code in einer Wurscht ohne irgendwelcher Trenner und
alles am linken Rand runterzuschreiben. Denn dann erkennt man genau gar
nicjts mehr. Vor allen Dingen dann nicht, wenn man noch keine Übung hat.
Vergleiche das hier
1
voiduart_gets(char*Buffer,uint8_tMaxLen)
2
{
3
uint8_tNextChar;
4
uint8_tStringLen=0;
5
NextChar=uart_getc();// Warte auf und empfange das nächste Zeichen
6
// Sammle solange Zeichen, bis:
7
// * entweder das String Ende Zeichen kam
8
// * oder das aufnehmende Array voll ist
9
while(NextChar!='\n'&&StringLen<MaxLen-1)
10
{
11
*Buffer++=NextChar;
12
StringLen++;
13
NextChar=uart_getc();
14
}
15
// Noch ein '\0' anhängen um einen Standard
16
// C-String daraus zu machen
17
*Buffer='\0';
18
}
mit dem hier
1
voiduart_gets(char*Buffer,uint8_tMaxLen)
2
{
3
uint8_tNextChar;
4
uint8_tStringLen=0;
5
6
NextChar=uart_getc();// Warte auf und empfange das nächste Zeichen
7
8
// Sammle solange Zeichen, bis:
9
// * entweder das String Ende Zeichen kam
10
// * oder das aufnehmende Array voll ist
11
while(NextChar!='\n'&&StringLen<MaxLen-1)
12
{
13
*Buffer++=NextChar;
14
StringLen++;
15
NextChar=uart_getc();
16
}
17
18
// Noch ein '\0' anhängen um einen Standard
19
// C-String daraus zu machen
20
*Buffer='\0';
21
}
In welcher Version wird die Struktur deutlicher, nämlich dass die
Funktion im wesentlichen aus einer Schleife besteht in der die
Einzelzeichen gesammelt und zusammengesetzt werden, garniert von ein
bischen Code davor und danach? In welcher Version erkennt man schneller,
was eigentlich alles innerhalb der Schleife steht?
Tobias schrieb:> Ich bedanke mich Herr Karl Heinz Buchegger für die Hilfe aber leider> konnte ich nicht weitergehen.> Ich habe mein LCD in PortA angeschlossen aber leider ich kann nur auf> mein Hyperterminal "Test" senden und auf mein LCD nichts empfangen.
Und wo genau ist da jetzt in deinem Code der Aufruf von uart_gets()?
Kein Aufruf, kein Empfang. Ist doch nicht so schwer zu verstehen.
Tobias schrieb:> Ja das stimmt aber auch wenn ich uart_gets() aufrufe zeigt, dass es> wenig Argumete gibt.
Dann musst du das im AUfruf eben korrigieren.
Das ist deine uart_gets()
void uart_gets( char* Buffer, uint8_t MaxLen )
das zeigt, dass uart_gets 2 Argumente haben will. Der erste ist das char
Array, in dem uart_gets die empfangene Zeile ablegen soll, der zweite
ist die Größe dieses Arrays.
Also muss der Aufruf lauten
uart_gets( uart_string, uart_maxstrlen );
denn uart_gets soll die empfangene Zeile in uart_string ablegen und das
Array uart_string ist uart_maxstrlen Zeichen gross.
Dann hast du die korrekte Anzahl an Parametern. (Dass es da jetzt eine
Warnung wegen dem volatile geben wird, kannst du fürs erste ignorieren)
Tut mir leid. Aber um C lernen wirst du nicht rumkommen. Durch
Zusammenkopieren von fremden Code hat noch keiner eine
Programmiersprache (überhaupt die erste) gelernt.