Hallo,
ich weiß, dass dieses Feld schon reichlich beackert wurde, aber ich habe
zu meinem Problem tatsächlich keine passende Lösung gefunden.
Mein Atmega8 mit MAX232 empfängt zuverlässig Daten vom PC, aber beim
Versand kommt am PC nichts an. Das Kabel ist mit 'nem Modem geprüft.
Ich habe mein Testprogramm nun völlig auf den Rahmen des im Datenblatts
angegebenen Codes zurückgebaut:
1
#include<stdint.h>
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<avr/signal.h>
5
#include<util/delay.h>
6
#define F_CPU 3686400
7
8
voidUSART_Init(unsignedintbaud)
9
{
10
/* Set baud rate */
11
UBRRH=(unsignedchar)(baud>>8);
12
UBRRL=(unsignedchar)baud;
13
/* Enable Receiver and Transmitter */
14
UCSRB=(1<<RXEN)|(1<<TXEN);
15
/* Set frame format: 8data, 2stop bit */
16
UCSRC=(1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
17
}
18
19
voidUSART_Transmit(unsignedchardata)
20
{
21
/* Wait for empty transmit buffer */
22
while(!(UCSRA&(1<<UDRE))){
23
}
24
/* Put data into buffer, sends the data */
25
UDR=data;
26
}
27
28
unsignedcharUSART_Receive(void)
29
{
30
/* Wait for data to be received */
31
while(!(UCSRA&(1<<RXC)));
32
/* Get and return received data from buffer */
33
returnUDR;
34
}
35
36
voidUSART_Flush(void)
37
{
38
unsignedchardummy;
39
while(UCSRA&(1<<RXC)){
40
dummy=UDR;
41
}
42
}
43
44
intmain(void){
45
USART_Init(95);//2400 BAUD bei 3686400
46
DDRD=12;
47
PORTD=0;
48
while(1){
49
/*if(USART_Receive() == 8){
50
PORTD ^= 4;
51
}
52
else if(USART_Receive() == 16){
53
PORTD ^= 8;
54
}*/
55
_delay_ms(100);
56
USART_Transmit('A');
57
PORTD^=4;
58
}
59
}
Der auskommentierte Teil ist der Empfangsteil, der tadellos funktioniert
(lässt 2 unterschiedliche LEDs an und ausgehen, durch das "==" gehe ich
mal von einem stabilen Empfang aus).
Aber das Senden klappt absolut nicht. Ich habe mittlerweile auch schon
verschiedene Terminalprogramme, inkl. eines Selbstgeschriebenen
verwendet, aber es kommt absolut nichts an.
BAUD-Raten habe ich auch Verschiedene getestet, daran dürfte es nicht
liegen (auch hier auf Basis der im Datenblatt angegebenen Werte).
Ich werde beinahe verrückt, kann mir jemand weiterhelfen und sagen woran
es noch liegen könnte?
Gruß
Julian
wenn möglich schau dir mal das Ausgangssignal an, wenn du kein oszi hast
kannst du auch endlos 0xaa senden, dann soltte etwa die halbe Spannung
anliegen
Falk: Danke für die Checkliste, aber ich kann da jetzt erstmal keinen
Punkt entdecken der bei mir zutrifft. Zumal das Empfangen ja stabil
funktioniert.
Walter: Habe weder Oszi noch Multimeter, aber kann mir sicher die Tage
mal eines leihen, so dass ich zumindest mal die Spannungen auf'm TX
checken kann, danke für den Tipp.
Julian Schmitz schrieb:
> ...> void USART_Transmit( unsigned char data )> {> /* Wait for empty transmit buffer */> while ( !( UCSRA & (1<<UDRE)) ){> }> ...> }>> unsigned char USART_Receive( void )> {> /* Wait for data to be received */> while ( !(UCSRA & (1<<RXC)) );> ...> }
Vl optimiert der compiler die Warteschleife beim senden weg, da sie
wirklich leer ist. Mach sie mal so wie beim Receive also while(); oder
gib ein asm volatile("nop\n\t" ::); rein.
An der Leerschleife lag es nicht. Wäre mir aber auch neu, dass eine
While-Schleife ohne Körper, vom Compiler anders behandelt als eine mit
leerem Körper.
Ich hab's mittlerweile auch auf dem baugleichen Board eines Kollegen
getestet mit exakt gleichem Ergebnis.
Ich bin immer noch für weitere Vorschläge offen.
Lass die UDRE-Abfrage einfach mal ganz weg, mit dem 100ms-Delay sollte
das vorige Zeichen ja garantiert schon weg sein :-/
BTW:
Hängt der uC an der UDRE-Abfrage fest, oder blinkt die LED an
>> PORTD ^= 4;
Die LED blinkt, er hängt also nicht in der Warteschleife.
Ich habe diese jetzt auch mal weggelassen, ohne Erfolg.
Wie verhält sich der MAX232 eigentlich wenn von außen ein Signal auf TX
ankommt?
Btw. vielen Dank für die große Resonanz.
könnte es daran liegen, dass du DDR setzt nachdem du den uart init
machst?
in deinem code setzt du ja das DDRD für pin 0-4 (dec. 12) wo auch der
UART dranhängt (pin0 & pin1).
Julian Schmitz schrieb:
> Walter: Habe weder Oszi noch Multimeter, aber kann mir sicher die Tage> mal eines leihen, so dass ich zumindest mal die Spannungen auf'm TX> checken kann, danke für den Tipp.
In der Zwischenzeit kannst du auch mal ein LED an den Ausgang hängen
(mit Vorwiderstand). Das Blinzeln der LED wirst du sehen können. Zur Not
einfach mit der Baudrate runtergehen. Bei 300 Baud sieht man eine LED
schon wunderbar blinken.
Also bei mir funktionniert das Programm. Muss wohl an der Verkabelung
liegen.
Ich hab nur #define F_CPU als erste Zeile stehen (für delay.h), #include
<avr/delay.h> (avr libc 1.2.5) und den entsprechenden UBRR Wert für 2400
bps bei 16 MHz eingetragen.
Weiters ist _delay_ms(100) auch bei 3 MHz nicht möglich. "The maximal
possible delay is 262.14 ms / F_CPU in MHz." Dadurch kommen die Zeichen
aber einfach nur schneller daher.
Hab mit
Ach, der delay ist nur schnell reingesetzt, normalerweise arbeite ich
mit _delay_loop2 in Schleifen.
Also ich habe jetzt mal mit 'ner LED geguckt ob da überhaupt irgendwas
rausgeht. Es geht nichts raus :S
Gibt es vielleicht irgendeine Form von Flußkontrolle, also z.B. CTS/RTS?
Julian Schmitz schrieb:
> Falk: Danke für die Checkliste, aber ich kann da jetzt erstmal keinen> Punkt entdecken der bei mir zutrifft. Zumal das Empfangen ja stabil> funktioniert.>
Das heisst das du die Checkliste nicht durchgearbeitet hast. Würde ich
an deiner Stelle aber machen, bei mir läuft dein Programm einwandfrei,
schreibt schöne A ins Terminalfenster.
Julian Schmitz schrieb:
> Also ich habe jetzt mal mit 'ner LED geguckt ob da überhaupt irgendwas> rausgeht. Es geht nichts raus :S
Wo hast du kontrolliert?
Halt die LED einfach mal an den Prozessorpin.
Wenns dort wackelt, dann verfolg das Signal über die Platine, bis du
letztendlich am Kabelanschluss angelangt bist. Irgendwo dazwischen geht
es verloren.
Hallo ich habe exakt das gleiche Problem gehabt,
ich möchte zwar ungerne ein Beitrag aus 2009 wieder hochholen, da Ihr
nicht zu einer Lösung gekommen seid, denke ich mal wäre es nicht
schlecht, für anderen ein weiteren Info hier reinzutun, bevor da ein
neuer Beitrag erstellt wird.
Bei mir lag es daran, dass ich den TXEN beim init() nicht mit
eingeschaltet habe.
1
//SO IST NUR DER EMPFANGPIN RX EINGESCHALTET
2
//UCSRB |= (1<<RXEN);
3
4
//NUN SIND BEIDE PINS EINGESCHALTET UND EMPFANGEN SOWIE SENDEN KLAPPT //EINWANDFREI
5
UCSRB|=(1<<RXEN)|(1<<TXEN);
Ich hoffe, dass es irgendwann mal jemanden helfen, der genau den
gleichen dummen Fehler wie ich gemacht hat.
Liebe Grüße =)