Hallo,
ich habe hier eine Anfängerfrage. Ich wollte über Terminal etwas(zb.
'k') schicken und das gleich zurück bekommen. Kann mir jemand einen Tipp
geben was ich ändern soll und/oder wo der Fehler ist.
Danke
Mark schrieb:> void Usart_Transmit (void)> {> //Daten senden> while (!(UCSR0A & (1<<UDRE0)));> UDR0=data;> }
Es wäre sicher sinnvoll, der Sendefunktion auch das Zeichen zu
übergeben, das gesendet werden soll - z.B. so:
1
voidUsart_Transmit(unsignedchardata)
2
{
3
//Daten senden
4
while(!(UCSR0A&(1<<UDRE0)));
5
UDR0=data;
6
}
Die nächste gute Idee ist es, das Zeichen, das die Empfangsfunktion
liefert, auch zu benutzen:
1
while(1){
2
Usart_Transmit(Usart_Receive());
3
}
Wenn du stattdessen die globale Variable data benutzen willst, musst du
sie zumindest mit dem return Wert von Usart_Receive füllen und dann
deine alte Usart_Transmit aufzurufen.
> Wenn du stattdessen die globale Variable data benutzen willst, musst du> sie zumindest mit dem return Wert von Usart_Receive füllen und dann> deine alte Usart_Transmit aufzurufen.
meinst du so
Hallo,
also ich sitze den ganzen Tag an dem Code. Es funktioniet leider nicht
und ich finde den Fehler nicht. Ich wollte jetzt ASCII '1','2' und '3'
senden und am Terminal empfangen. Anstatt die Hex-Werte 31, 32 und 33 zu
erhalten, bekomme ich die Hex-Werte 67 ,B3, 06.
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<avr/interrupt.h>
4
#define F_CPU 16000000UL
5
//Usart
6
#define Baud 9600UL
7
#define UBRR_Val ((F_CPU/(16*Baud))-1)
8
9
voidUsart_Init(void);
10
voidUsart_Transmit(unsignedchardata_tx);
11
unsignedcharUsart_Receive(void);
12
13
unsignedchardata=0;
14
intmain()
15
{
16
//Ausgang
17
DDRD|=(1<<PD1);
18
//Eingang
19
DDRD&=~(1<<PD0);
20
Usart_Init();
21
//unsigned char data;
22
while(1)
23
{
24
Usart_Transmit('1');
25
Usart_Transmit('2');
26
Usart_Transmit('3');
27
//Usart_Transmit(Usart_Receive());
28
_delay_ms(5000);
29
//
30
}
31
return0;
32
}
33
//-----------------------------------
34
//Usart
35
voidUsart_Init(void)
36
{
37
//Baudrate einstellen
38
UBRR0H=(unsignedchar)(UBRR_Val>>8);
39
UBRR0L=(unsignedchar)UBRR_Val;
40
//Frame-Format:8 Bit Nutzsignal
41
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
42
//Sender und Eampfenger initialisieren
43
UCSR0B=(1<<RXEN0)|(1<<TXEN0);
44
}
45
//---------------------------------
46
47
voidUsart_Transmit(unsignedchardata_tx)
48
{
49
//Daten senden
50
//wurde vorherige Byte erfolgreich gesendet wurde und ob der UDR Puffer leer ist
51
while(!(UCSR0A&(1<<UDRE0)));
52
//sende Byte
53
UDR0=data_tx;
54
}
55
//------------------------------------
56
unsignedcharUsart_Receive(void)
57
{
58
unsignedchardata_Rx;
59
//Ein Zeichen (1Byte) ist über die seielle Schnittstelle in Usart angekommen
Mark schrieb:> Anstatt die Hex-Werte 31, 32 und 33 zu> erhalten, bekomme ich die Hex-Werte 67 ,B3, 06
Sowas ist zu 99% ein Problem mit der Taktfrequenz, denn das Programm
sollte so klappen. Also checke die Fuses (ext. High Frequency Crystal
wäre hier richtig) - nicht den internen RC Oszillator, denn der läuft
mit 8MHz.
Du kannst auch mal direkt 0d103 in UBRR0L schreiben (UBRR0H bleibt auf
null), das sollte auch die 9600 bit/s ergeben. Stelle auf jeden Fall
sicher, das auch der Host auf 9600 Baud steht.
Wenn du aus Versehen mit dem internen Oszillator arbeitest, sollte es
bei UBRR0L = 0d51 laufen.
Matthias S. schrieb:> Mark schrieb:>> Anstatt die Hex-Werte 31, 32 und 33 zu>> erhalten, bekomme ich die Hex-Werte 67 ,B3, 06>> Sowas ist zu 99% ein Problem mit der Taktfrequenz, denn das Programm> sollte so klappen. Also checke die Fuses (ext. High Frequency Crystal> wäre hier richtig) - nicht den internen RC Oszillator, denn der läuft> mit 8MHz.>> Du kannst auch mal direkt 0d103 in UBRR0L schreiben (UBRR0H bleibt auf> null), das sollte auch die 9600 bit/s ergeben. Stelle auf jeden Fall> sicher, das auch der Host auf 9600 Baud steht.> Wenn du aus Versehen mit dem internen Oszillator arbeitest, sollte es> bei UBRR0L = 0d51 laufen.
Also ich verwende Arduino Uno. Sorry für die Frage (ich bin ein
Anfänger), aber ich verstehe nicht was mit dem Fuses gemeint ist. Wie
soll ich die Fuses checken?
VG
Mark schrieb:> Wie> soll ich die Fuses checken?
Gegenfrage: Wie programmierst du den Uno denn? Wenn du da einen ISP
Programmer benutzt, kann der auch Fuses auslesen. Wenn du den Arduino
Bootlaoder nimmst, dann geht das nicht.
Der Uno ist normalerweise aber schon richtig auf den 16MHz Quarz
gefused, so das du da nicht ran musst.
1
// illuminate the Uno/Duemilanove LED for exactly 1 second
2
DDRB|=(1<<PB5);
3
PORTB|=(1<<PB5);
4
_delay_ms(1000);
5
PORTB&=~(1<<PB5);
Zum Test der Frequenz sollte mit obigem Beispiel die LED auf dem Board
für genau 1 Sekunde leuchten.
Da du den Mikrocontroller über ISP programmierst (nicht über Bootloader)
sollte die BOOTRST Fuse aus sein.
In deinem Fall ist sie an, das bewirkt, dass dein Mikrocontroller
irgendeinen unbekannten Code ausführt, bevor dein eigentliches Programm
gestartet wird. Und dieser Code bewirkt möglicherweise die Fehlfunktion.
Die anderen Fuses sehen Ok aus.
Eine kleine Erklärung zu Fuses: Betrachte sie als
Konfigurationsparameter, die vor dem Programmstart aktiviert werden und
nicht Bestandteil des Programmes (*.hex Datei) sind. Quasi so wie Jumper
auf einer PC Komponente.
Matthias S. schrieb:>> Du kannst auch mal direkt 0d103 in UBRR0L schreiben (UBRR0H bleibt auf> null), das sollte auch die 9600 bit/s ergeben.
Der Wert 103 ist doch ein Dezimal-Wert. Warum 0x103?
Stefan U. schrieb:> Da du den Mikrocontroller über ISP programmierst (nicht über> Bootloader)> sollte die BOOTRST Fuse aus sein.
Den hacken am BOOTRST ist jetzt weg, BOOTRST ist also aus. Zudem habe
ich den Programmteil umgeschrieben gemäß:
1
voidUsart_Init(void)
2
{
3
//Baudrate einstellen
4
UBRR0H=0x00;
5
UBRR0L=103;
6
7
//Frame-Format:8 Bit Nutzsignal
8
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
9
//Sender und Eampfenger initialisieren
10
UCSR0B=(1<<RXEN0)|(1<<TXEN0);
11
}
Damit hat sich leider das Problem nicht gelöst. Wie im Bild zusehen ist,
erhalte ich immer noch die falschen Hex-Werte.
Schreibe das Programm mal so um, dass es einfach fortlaufend 'A' Sendet,
mit einigen hundert Millisekunden Pause zwischen jedem Buchstaben.
Kommen dann am PC 'A' an, oder was anderes?.
Mark schrieb:>> Du kannst auch mal direkt 0d103 in UBRR0L schreiben (UBRR0H bleibt auf>> null), das sollte auch die 9600 bit/s ergeben.>> Der Wert 103 ist doch ein Dezimal-Wert. Warum 0x103?
Nicht 0x103 - ich habe doch extra 0d103 geschrieben, damit es klar wird,
das es dezimal ist. 0x103 würde doch auch in ein 8-bit Register gar
nicht reinpassen.
103 ist einfach der ausgerechnete Wert für Baudrate 9600 bei 16MHz Takt.
Ok, klappt trotzdem nicht. Beschreib uns doch mal, wie du TX des AVR mit
RX des PCs verbindest und was da für Hardware dazwischen ist.
Matthias S. schrieb:> Ok, klappt trotzdem nicht. Beschreib uns doch mal, wie du TX des AVR mit> RX des PCs verbindest und was da für Hardware dazwischen ist.
ok, danke. Mein MC ist über den DELOCK Adapter USB Seriell 1x9 Pin mit
dem PC verbunden.
Stefan U. schrieb:> Schreibe das Programm mal so um, dass es einfach fortlaufend 'A'> Sendet,> mit einigen hundert Millisekunden Pause zwischen jedem Buchstaben.> Kommen dann am PC 'A' an, oder was anderes?.
Ich bin deinem Rat gefolgt. Ich habe die while-Schleife geändert. Ich
bekomme anstatt 0x41 den Hex-Wert 5F.
Das ist ein USB RS232 Adapter. Den kannst Du nicht verwenden und dich
freuen wenn dein µC keinen Schaden genommen hat.
Du brauchst einen USB UART TTL Adapter.
Werner P. schrieb:> Du brauchst einen USB UART TTL Adapter.
Nö, braucht er nicht, der ist auf dem Nano in Form eines FT232RL schon
drauf. Und die genannten Pins (PD0/PD1) hängen da auch schon dran. Er
braucht ein stinknormales USB-Kabel.
Werner P. schrieb:> So wie ich ihn verstanden habe verbindet er die µC Pins direkt.> Und dann hat er mit seinem RS232 Adapter ein Problem.
Das hab ich nicht bestritten.
Nur was soll er mit zwei USB UART TTL Adaptern, die auch noch an den
gleichen Pins hängen? Man könnte natürlich die entsprechenden
Widerstände vom Board kratzen und den Onboard Chip damit totlegen.
@TE nur zur Erklärung:
1. ist dein Adapter auf einen Pegelbereich von etwa -10V bis +10V am TX
und RX Anschluss gedacht und
2. ist die Polarität der RS232 Signale genau anders rum als bei UART am
MC.
Das kann also nicht gehen. Entweder nimmst du das USB Interface, das
schon auf dem Uno drauf ist, wie o.a. oder du besorgt dir besagtes
USB-TTL Adapter.
Werner P. schrieb:> Das ist ein USB RS232 Adapter. Den kannst Du nicht verwenden und> dich> freuen wenn dein µC keinen Schaden genommen hat.>> Du brauchst einen USB UART TTL Adapter.
Hallo Leute ihr habt vollkommen recht. Es liegt tatsächlich an dem
Adapter. Ich hatte irgendwo noch einen USB UART TTL Adapter. Diesen habe
ich jetzt angeschlossen und dazu die Treiber-Software runtergeladen. Und
es funktionert jetzt.. Danke dass ihr euch die Zeit genommen habt und
mir geholfen habt.
VG