Aufbau einer Kommunikation zwischen pc und USART0

OP #2805570
Lesenswert?

Hallo,

ich versuche zur Zeit eine Kommunikation zwischen ein PC und ein 
Atmega644p aufzubauen.

Eigentlich möchte ich Charakter in form von Byte über eine serielle 
Schnittstelle RS232 vom PC zum Atmega644p senden. Ich habe ein Programm 
in c++ geschrieben, um die Charakter zum Mikrocontroller Atmega644p zu 
senden. Danach habe ich ein c-Code  für den Mikrocontroller geschrieben, 
um die Charakter im Puffer UDR0 von USART0 zu erhalten. Dann soll wieder 
die empfangenen Charakter von UDR0 in Richtung des PCs übertragen, um 
die Funktion ReadFile() von der c++-Programm zu testen.

Ich habe ein Test durchgeführt und habe festgestellt, dass der Puffer 
UDR0 ewig auf Charakter von PC wartet, obwohl ich der pin RXC0 manuell 
aktiviert habe. Eigentlich bekommt der Puffer UDR0 keine Charakter. Was 
kann das Problem sein ?

Stimmt zufällig was nicht in mein c- und c++ Code ? Wenn ja, dann würde 
ich mich freuen, wenn sie mir helfen.

Im Anhang liegt meine Datei.

MFG

monkeydluffy
Angehängte Dateien:
Gast #2806132
Lesenswert?

Du solltest nicht zwei Programm gleichzeitig schreiben und dann 
gegeneinander testen.

Tausche das PC Programm durch ein anderes aus, bei dem Du weisst, dass 
es funktioniert (z.B. Hyperterminal von WIndows XP, oder Cutecom oder 
Hammer Terminal).

Dann nimm erstmal den Mikrocontroller aus seinem Sockel heraus un 
verbinde die RxD und TxD Pins des Sockel mit einem Drahtstück.

Dann sendest Du irgendwelche Zeichen mit dem PC. Wenn die Hardware Ok 
ist, kommen die gesendeten Zeichen als Echo zurück zum PC (wegen der 
Drahtschleife).

Erst dann würde ich mich an die Programmierung des Mikrocontrollers 
wagen. Und wenn der dann mit dem Terminalprogramm zusammen arbeitet, 
dann tausche das Terminalprogramm durch dein selbst geschriebenes aus.
OP #2810479
Lesenswert?

Hallo,

ich habe deine Tipps befolgen und habe  versucht, ein Charakter 'X' von 
Hyperterminal in die Variable c zu schreiben und dann der Wert von c 
wieder über die Schnittstelle  zum Hyperterminal zu senden. Leider läuft 
mein Experiment nicht.
Als Einstellung für Hyperterminal habe ich folgende Daten übernommen:

- Bits pro Sekunde : 112500
- Datenbits:           8
- Parität:            Keine
- Stoppbits:            2
- Flusssteuerung:      Keine

Die Implementierung des Mikrocontrollers lautet:
1
#include <avr/io.h>
2
#include <avr/interrupt.h> 
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
// #include "uart.h"
7
#include <avr/pgmspace.h>
8

9
#define FOSC 8000000 // Clock Speed
10
#define BAUD 115200UL
11

12
// Berechnungen zur Baudrate:
13

14
#define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
15

16
/****************************************************/
17
void USART_Init (unsigned int ubrr)
18
{
19
  UBRR0H = (unsigned char)(ubrr>>8);
20
  UBRR0L = (unsigned char) ubrr;
21
  UBRR1H = (unsigned char)(ubrr>>8);
22
  UBRR1L = (unsigned char) ubrr;
23
  
24
  UCSR0B = (1<<RXEN1) | (1<<TXEN0) |(0<<RXCIE0)|(0<<TXCIE0);
25
  UCSR0C = (1<<USBS0) | (0<<UCSZ02)|(1<<UCSZ01)|(1<<UCSZ00);
26
  
27
} 
28

29
/**********************************************************/
30

31
/*-- function receive USART0 --*/
32

33
  unsigned char USART0_Receive (void)
34
{
35
    while(!(UCSR0A & (1<<RXC0)) ) // warten bis Zeichen verfuegbar
36
    ;
37
  return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben
38
}
39

40

41
/*-- function transmit USART0 --*/
42

43
void USART0_Transmit (unsigned char data0)
44
{
45
  while ( !(UCSR0A & (1<<UDRE0)) )// warten bis Senden moeglich 
46
 
47
  UDR0 = data0;
48
} 
49

50
/**********************************************************/
51

52
/*-Aktivierung der Datenübertragung über RS485 von USART1-*/
53

54
 void RS485_Init (void)
55
{
56
  DDRD = (1<<PD4)|(1<<PD3)|(1<<PD5);//Steuer- und Datenausgang aktivieren
57
  PORTD = (1<<PD4);  //auf Senden stellen (Aktivierung Datensendung)
58
} 
59

60

61
int main (void)
62

63
{ 
64
  unsigned char c ;
65

66
  USART_Init(UBRR_VAL) ;  // USART Initialisierung
67
  RS485_Init (); // serielle Schnittstelle USART1
68

69
  while(1)
70

71
  {
72
 
73
/*-- Test USART0 (Receive and Transmit) --*/
74
    
75
//     USART0_Transmit('X');
76

77
    c = USART0_Receive();
78

79
    USART0_Transmit(c);
80
}
81

82
}

Hat jemand Lösungsvorschläge, damit ich der Test mit Erfolgreich 
durchführen kann.

Danke im Voraus.
OP #2810523
Lesenswert?

Hi,

>> ich habe deine Tipps befolgen und habe  versucht, ein Charakter 'X' von
>> Hyperterminal in die Variable c zu schreiben und dann der Wert von c
>> wieder über die Schnittstelle  zum Hyperterminal zu senden.

Als ich mein Programm debuggt, stelle ich fest, dass der Mikrocontroller 
der Charakter 'X' empfängt, der vom Hyperterminal gesendet wurde.

Allerdings soll wieder der empfangene Charakter 'X'  zum Hyperterminal 
über die serielle Schnittstelle übertragen. Leider läuft dieser Schritt 
meines Programm nicht. Im laufe des Debuggings wird die Funktion 
USART0_Transmit nicht vollständig ausgeführt. Irgendwie landet wieder 
der Charakter 'X' nicht in Hyperterminal.

Bitte, was stimmt eigentlich nicht in meinem Programm ?

Danke im Voraus.
#2810538
Lesenswert?

Nimm hier mal den Kommentar weg
1
void USART0_Transmit (unsigned char data0)
2
{
3
  while ( !(UCSR0A & (1<<UDRE0)) )// warten bis Senden moeglich 
4
 
5
  UDR0 = data0;
6
}

dann steht da
1
void USART0_Transmit (unsigned char data0)
2
{
3
  while ( !(UCSR0A & (1<<UDRE0)) )
4
  UDR0 = data0;
5
}

und jetzt rückst du auch noch den Code richtig ein und zwar so, wie der 
COMpiler das ganze sieht
1
void USART0_Transmit (unsigned char data0)
2
{
3
  while ( !(UCSR0A & (1<<UDRE0)) )
4
    UDR0 = data0;
5
}

dann steht da:
Solange Senden nicht möglich ist, füttere das UDR0 Register.
Sobald Senden wieder möglich ist, mache nichts mehr.


Da fehlt ein ; der der while Schleife die richtige Bedeutung verpasst.
#2810614
Lesenswert?

Luffy Monkey schrieb:
> Hallo,
>
> Karl Heinz Buchegger, danke schön für dein Feedback.
>
> Karl schrieb:
>
>>> Da fehlt ein ; der der while Schleife die richtige Bedeutung verpasst.
>
> Was meinst du da bitte ? Ich verstehe dein Hinweis nicht.

Dabei hab ich so sehr versucht, herauszuarbeiten, was da passiert ohne 
den Fehler konkret zu benennen. (Am meisten lernt man immer noch, wenn 
man seine Fehler selbst findet.)


Wie soll die Logik in dieser Funktion sein?
( ===> Sollverhalten)


Wie ist die niedergeschriebene Logik tatsächlich?
( ===> Istverhalten)


OK. Ein Hinweis
Was ist der Unterschied zwischen (Pseudocode der sich an C anlehnt)
1
  Motor ein;
2
  while( ! Endschalter hat ausgelöst )
3
    ;
4
  Motor aus;
und
1
  Motor ein;
2
  while( ! Endschalter hat ausgelöst )
3
  Motor aus;
OP #2810644
Lesenswert?

Hallo nochmal,

>> OK. Ein Hinweis
>> Was ist der Unterschied zwischen (Pseudocode der sich an C anlehnt)

>>  Motor ein;
>>  while( ! Endschalter hat ausgelöst )
    ;
>>  Motor aus;

>>und

>>  Motor ein;
>>  while( ! Endschalter hat ausgelöst )
>>  Motor aus;

Ich vermute, die Anwesenheit in obere Block des Semikolons ';' allein in 
eine Zeile ohne Anweisung verursacht der Unterschied mit dem unteren 
Block.
Gast #2810666
Lesenswert?

Hätte man auch so schreiben könnnen. Ob das Semikolon alleine in einer 
Zeile steht ist egal.

main()
{
  int a=0;
  while( ! Endschalter hat ausgelöst );
  a=100;
}

und

main()
{
  int a=0;
  while( ! Endschalter hat ausgelöst )
  a=100;
}
OP #2810733
Lesenswert?

Hallo nochmal,

danke schön Uwe und Karl Heinz Buchegger für die ausführlichen 
Erklärungen. Ich habe jetzt der Unterschied zwischen die beide Blöcke 
verstanden.
1
main()
2
{
3
  int a=0;
4
  while( ! Endschalter hat ausgelöst );
5
  a=100;
6
}

Im oberen Fall gehört die Variable a  nicht zu der while-Schleife.
1
main()
2
{
3
  int a=0;
4
  while( ! Endschalter hat ausgelöst )
5
  a=100;
6
}

Im unteren Fall gehört die Variable a zu der while-Schleife.

Ich habe einfach  meine Fehler  übersehen, obwohl Karl mir alles  gut 
erklärt hat. Machmal bin ich wirklich dumm.

Vielen Dank noch für ihre Hilfe.

mfg
OP #2810950
Lesenswert?

Hallo,

ich wollte mich nochmal bei euch bedanken. Ich habe geschafft, die 
Kommunikation zwischen dem PC und dem Mikrocontroller Atmega644p 
aufzubauen. Meine c und C++ Code sind kompatibel und laufen einwandfrei, 
so dass der PC und der Mikrocontroller kommunizieren können.

Vielen für eure Hilfe

Monkey Luffy
OP #2814473
Lesenswert?

Morgen,

mit eueren Hilfen habe ich geschafft, die Kommunikation zwischen dem PC 
und dem Mikrocontroller aufzubauen.

Mein Ziele war die Übertragung von Charakter 0,1,2,3,4 von PC zum 
Mikrocontroller über die Serielle Schnittstelle RS232. Dann sollte die 
Routine des Mikrocontrollers wieder die empfangenen Charakter in die 
gleiche serielle Schittstelle zurückschicken, so dass man folgende 
Ergebnisse auf einem Fenster bekommt:

0 : 0
1 : 1
2 : 2
3 : 3
4 : 4

Als ich meine beide Code debuggt habe, habe ich folgende Resultat 
erhalten:

0 :
1 : 0
2 : 1
3 : 2
4 : 3

Ich bekomme eine Byte-verschiebung und ich weiße nicht, wie ich dieser 
Fehler korrigieren kann.

Weiß jemand, wie ich mein problem lösen kann ?

Danke im Voraus.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren