Forum: Mikrocontroller und Digitale Elektronik Überwachung des Datenaustauches zwischen USART0 und USART1


von Luffy M. (monkeydluffy)



Lesenswert?

Hallo,

Ich arbeite mit dem Mikrocontrollerboard 644P und versuche vor einigen 
Tagen den datenaustauch zwischen dem USART0 und USART1 zu aufbauen bzw 
zu überwachen.Ich habe im Puffer UDR0 von USART0 ein Zeichen 'b' 
geschrieben und habe wieder dieses Zeichen zum Puffer UDR1 übertragen.

Als ich mein C-Code compiliere,  läuft das Programm einwandfrei. Aber 
die
Puffer UDR0 und UDR1 bekommen nicht das Zeichen im Laufe der Simulation.
Außerdem wird mein Interrupt Routine im Laufe der Simulation überhaupt
nicht verarbeitet. Ich verstehe nicht, was schieflauft.

Bitte,kann jemand mir was vorschlagen ?

Mein C-Code befindet sich im Anhang.

Danke im Voraus.

mfg monkeydluffy.

von Karl H. (kbuchegg)


Lesenswert?

Luffy Monkey schrieb:

> Mein C-Code befindet sich im Anhang.

Dann poste ihn auch als C-File.
Das Forum kann mit Files der Endung .c umgehen und macht dann Syntax 
Coloring.


Ähm
1
void USART1_Transmit (unsigned char data1)
2
3
{
4
5
/* Wait for empty transmit buffer */
6
7
while ( !(UCSR1A & (1<<UDRE1)) ); //warten bis Senden moeglich
8
9
/* Put data into buffer and sends the data */
10
11
data0 = UDR0 ;
12
UDR1 = data0 ;
13
14
}

Sag mal, was machst du eigentlich die ganze Zeit mit deinen UDRx 
Registern? Dir ist schon klar, dass du da nicht einfach nach Belieben 
und beliebig oft auslesen bzw. reinschreiben darfst?

Du darfst UDRx nur EINMAL auslesen. Danach ist das Byte aus der UART 
raus und ein weiterer Leseversuch von UDRx liefert nicht mehr dieses 
Byte.

Auch kann man UDRx NICHT als Zwischenspeicher benutzen.
Wenn du von UDRx liest, greifst du hardwaremässig auf etwas anderes zu, 
als wie wenn du hineinschreibst.

   UDR0 = x;
   y = UDR0;

liefert dir in y NICHT das ab, was du mittels x hineingeschrieben hast!
Bei der Zuweisung an UDR0 gibst du der UART implizit die Anweisung: 
dieses Byte raussenden. Das Byte landet in der AUsgangsstufe der UART.
Beim Lesen von UDR0 holst du dir aber das nächste Byte von der 
Eingangsstufe der UART (und das Byte ist danach in der Eingangsstufe 
nicht mehr verfügbar). Das sind 2 getrennte Beriche in der UART, die mit 
demselben Registernamen angesprochen werden, mehr aber auch nicht. Die 
haben so gesehen nichts miteinander zu tun.

von Luffy M. (monkeydluffy)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

danke schön für die Erklärung Karl Heinz. Jetzt habe ich zumindestens 
eine Ahnung, wie man die Registern UDRx ansprechen muss. Ich habe noch 
mal mein C-Code geändert. Aber ich sehe  im Laufe der Compilierung das 
Zeichen 'b' nicht im Register UDR0 als auch im Register UDR1. Außerdem 
reagiert mein Interrupt Routine nicht im laufe der Compilierung.

Was mache ich denn falsch ? Übrigens, ich bin kein Profi und mache mein 
besten, um keine blöde Fragen zu stellen.

Mein Code liegt im Anhang.

Danke im Voraus.

mfg  monkeydluffy.

von spess53 (Gast)


Lesenswert?

Hi

>Was mache ich denn falsch

Die UARTs werden vom Simulator nur eingeschränkt unterstützt. Der 
Interrupt sollte aber durch manuelles setzen von RXC ausgelöst werden

>  USART_Init(UBRR_VAL) ;
>  sei();
>  ISR(USART1_RX_vect) <-------

Eine ISR wird nicht direkt aufgerufen.

MfG Spess

von Luffy M. (monkeydluffy)


Lesenswert?

Hi,

Ertsmal danke für deinen Tipp Spess53.

> Die UARTs werden vom Simulator nur eingeschränkt unterstützt. Der
> Interrupt sollte aber durch manuelles setzen von RXC ausgelöst werden.

ich habe deinen Tipp befolgt und habe die USART0 und USART1 mit dem 
Mikrocontrollerboard 644P in Betrieb genommen. Außerdem habe ich nicht 
mehr die Funktion ISR direkt aufgerufen.

Leider bekomme ich wieder nicht das Zeichen 'b' im UDR0 und UDR1 und die 
Funktion ISR ist immer nicht ausführbar.

Bemerkung: Als ich mein Code compiliere, läuft das Programm ohne Ende.

Hat jemand noch eine Idee ??

mfg monkeydluffy

von Karl H. (kbuchegg)


Lesenswert?

> UCSR1B = (0<<RXEN1)|(1<<TXEN1) | (0<<RXCIE1)|(1<<TXCIE1);

Du schreibst jetz 100 mal:
Ich soll einen Interrupt nicht freigeben, wenn ich keine ISR dafür habe.

Du gibst hier den Transmit Complete Interrupt der UART 1 frei, hast aber 
keine ISR dafür.

von Karl H. (kbuchegg)


Lesenswert?

Machs doch für deine ersten Versuche nicht so kompliziert mit 
Interrupts.
1
int main()
2
{
3
  unsigned char c;
4
5
  USART_Init(UBRR_VAL) ;
6
7
  while( 1 )
8
  {
9
    c = USART0_Receive();
10
    USART1_Transmit( c );
11
  }
12
}

von Luffy M. (monkeydluffy)


Lesenswert?

Hallo,

danke schön für deine Anweisung.

Ich werde umgehend deine Meinungen befolgen.

mfg monkeydluffy

von Luffy M. (monkeydluffy)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

ich bedanke mich erstmal bei Karl Heinz und spess53 für ihre Ratschläge. 
ich habe ihre Anweisung befolgt und bin ziemlich gut voran gegangen.

Spess53 schrieb :

> Die UARTs werden vom Simulator nur eingeschränkt unterstützt.

zwar bin ich kein Profi, aber ich habe selber mein Experiment mit 
Erfolgreich durch den Simulator durchgeführt. Eigentlich war es möglich 
für mich durch den simulator das Zeichen 'b' im Register UDR0 zu 
schreiben. Dafür habe ich manuel die Parameter RXC0 (receive complete), 
TXC0 (transmit complete)und RXC1 (receive complete) auf High gesezt.

Aber der Register UDR1 empfängt immer nicht das Zeichen 'b'. Ich habe 
verschidene Variante probiert, aber das klappt einfach nicht.

Woran liegt das ?

Anbei liegt mein C-Code.

Danke im Voraus.

mfg monkeydluffy.

von Uwe (Gast)


Lesenswert?

Du hast sicherlich vergessen im Simulator USART1 mit USART0 mit einem 
Nullmodemkabel zu verbinden.
Falls du dich jetz fragst wie man das macht :
Gar nicht !

von Luffy M. (monkeydluffy)


Lesenswert?

Hi,

UWE schrieb:

> Du hast sicherlich vergessen im Simulator USART1 mit USART0 mit einem
> Nullmodemkabel zu verbinden.
> Falls du dich jetz fragst wie man das macht :
> Gar nicht !

gibt´s dann einen anderen Lösungsweg ?

mfg monkeydluffy

von Sascha W. (sascha-w)


Lesenswert?

Luffy Monkey schrieb:
> Hi,
>
> UWE schrieb:
>
>> Du hast sicherlich vergessen im Simulator USART1 mit USART0 mit einem
>> Nullmodemkabel zu verbinden.
>> Falls du dich jetz fragst wie man das macht :
>> Gar nicht !
>
> gibt´s dann einen anderen Lösungsweg ?

soweit ich dich verstanden habe, und auch dein Progamm sieht so aus 
kommen Daten über die serielle Schnittstelle an USART0 an und die Daten 
willst du über USART1 wieder ausgeben. Das heist das extern keine 
Verbindung zwischen USART0 und USART1 besteht. Damit musst du das auch 
nicht simulieren.
Eingehende Daten an USART0 kannst du über den Simulator auch nicht 
simulieren, hab ich gerade mal gestestet. Ändert man den Wert des 
Registers, dann steht nach dem nächsten Takt wieder 0 drin. Setzt man 
RXC0 dann wird zwar die ISR ausgelöst, aber es wird immer 0 eingelesen.

Fazit: Eine Simulation deines Programms ist so nicht möglich!

Sascha

von UART Meister (Gast)


Lesenswert?

Physikalisch über die Schnittstellen raus und wieder rein.

TXD RXD anzapfen und über ein Proramm (Unicom) welches beide Richtungen 
mitliest debuggen.
So machen das Männer die sich auskennen.

von Monkey Luffy (Gast)


Lesenswert?

Hallo,

Erstmal danke schön an alle, die mir helfen. Ich komme langsam mit der 
Sache klar. Dank eurer Tipps und Unterstützungen verstehe ich besser, 
wie man die USARTs ansprechen muss. Sobald ich noch Fragen habe, werde 
ich mich noch bei euch melden.

Noch mal vielen Dank.

mfg monkeydluffy

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.