Forum: Mikrocontroller und Digitale Elektronik Datenübertragungsproblem mit Wiznet W5300


von Promas (Gast)


Lesenswert?

Wir arbeiten an einem Projekt, bei dem wir mit einem Wiznet W5300 Daten 
über das TCP Protokoll übertragen wollen. Als µC dient uns ein Atmel 
XPLAINED Board mit einem ATXMega 128A1, das mit einem JTAG ICE 3 
programmiert wird.
Bis jetzt können wir den Wiznet mit dem PC (Client)pingen und den Socket 
öffnen und eine Verbindung mit dem TCP-IP Builder herstellen.

Beim Übertragen von Daten gibt es jedoch sowohl beim Senden, als auch 
beim Empfangen von Daten Probleme und wir würden uns freuen, wenn jemand 
eine Idee hätte.

Da in der Dokumentation des XPLAINED Boards ist nicht beschrieben, ob 
ein externer Oszillator verbaut ist, wollten wir fragen, ob uns jemand 
weiterhelfen kann.

Das wäre unser Code zum Empfangen von Daten:
1
void READ_LAN ()
2
{
3
  uint16_t Pack_Size;
4
  uint16_t Index;
5
  uint16_t Index2;
6
  uint16_t Pack_Size_Hilf;
7
  uint8_t  byte_array0 [3];
8
  uint8_t byte_array1 [3];
9
  uint8_t dummy;
10
  
11
  Index2 = 0;
12
  
13
  //Größe des Paketes auslesen
14
  //0x229, 0x22A , 0x22B sind die Received Size Register des W5300
15
  Pack_Size = W5300_DATA_READ (0x229); 
16
  Pack_Size = (Pack_Size << 8);
17
  Pack_Size = Pack_Size + W5300_DATA_READ (0x22A);
18
  Pack_Size = (Pack_Size << 16);
19
  Pack_Size = Pack_Size + W5300_DATA_READ (0x22B);
20
  
21
  // Kontrolle ob eine ungerade Zahl von Daten übertragen wurde
22
  if(Pack_Size & 0x01)
23
  {
24
    Pack_Size = Pack_Size +1;  
25
  }
26
  
27
  Pack_Size_Hilf = Pack_Size/2; //die auszulesenden Daten werden aúf 2 Register aufgeteilt
28
  
29
  for (Index=0;Pack_Size_Hilf>1;Index++)
30
  {
31
    Pack_Size_Hilf= Pack_Size_Hilf/2;
32
    byte_array0[Index] = W5300_DATA_READ(0x230); // 0x230 und 0x231 sind die Empfangsbuffer des W5300
33
    byte_array1[Index] = W5300_DATA_READ(0x231);
34
    
35
  }
36
  
37
  _delay_us(10);
38
  
39
  for (Index=0;Index<Pack_Size;Index++)  // den Wert aus den Hilfsvariablen in eine globale Variable schreiben
40
  {
41
    Lan_Data[Index2]=byte_array0[Index];
42
    Lan_Data[Index2+1] = byte_array1[Index];
43
    USART.DATA = Lan_Data [Index2]; 
44
    USART.DATA = Lan_Data [Index2];
45
    Index2 = Index2 +2;
46
  }
47
  
48
  // Kontrolle ob eine ungerade Zahl von Daten übertragen wurde
49
  if(Pack_Size & 0x01)
50
  {
51
    Lan_Data[Index2] = W5300_DATA_READ(0x230); 
52
    dummy = W5300_DATA_READ(0x231);  // bei einer ungeraden Anzahl von Daten, soll der Dummy nicht in Lan-Data geschrieben werden
53
  }
54
  
55
  W5300_DATA_WRITE(0x203,Sn_CR_RECV);  // Befehl zum Beenden des Lese-Vorgangs für den Wiznet
56
}

Danke im Voraus!

von Karl H. (kbuchegg)


Lesenswert?

Wenn PackSize ein uint16_t ist, dann wird hier
1
  Pack_Size = W5300_DATA_READ (0x229); 
2
  Pack_Size = (Pack_Size << 8);
3
  Pack_Size = Pack_Size + W5300_DATA_READ (0x22A);
4
  Pack_Size = (Pack_Size << 16);
5
  Pack_Size = Pack_Size + W5300_DATA_READ (0x22B);
wohl was schief gehen. Eine 16 Bit Variable um 16 Bit nach links shiften 
... da kannst du auch gleich
  variable = 0;
hinschreiben.

von Karl H. (kbuchegg)


Lesenswert?

1
  for (Index=0;Pack_Size_Hilf>1;Index++)
2
  {
3
    Pack_Size_Hilf= Pack_Size_Hilf/2;
4
    byte_array0[Index] = W5300_DATA_READ(0x230); // 0x230 und 0x231 sind die Empfangsbuffer des W5300
5
    byte_array1[Index] = W5300_DATA_READ(0x231);
6
    
7
  }

die byte_arrays haben eine Länge von gerade mal 3!
Welche Werte erwartest du denn in Pack_Size eigentlich?

Und die Halbierung? Was'n das für ein Protokoll? Das sieht irgendwie 
überhaupt nicht so aus, wie man das erwarten würde.

Am Anfang wird die Anzahl der Datenelemente übertragen, und dann genau 
diese Anzahl an Datenelementen nachgeschoben. So in etwa würde man das 
erwarten. Aber warum um alles in der Welt sollte man als Anzahl die 2-er 
Potenz der Datenlänge übertragen? Das ergibt doch keinen Sinn!

von Karl H. (kbuchegg)


Lesenswert?

Ich kann dir nur die Empfehlung geben:

Lass dir alles und jedes, was du von der Datenübertragungsstrecke 
bekommst, irgendwo ausgeben. Ansonsten ist das ein Stochern im Nebel. 
Speziell dann, wenn man noch nicht so viel Erfahrung hat.

Bau dir Ausgaben in dein Programm ein. Die erzählen dir, was passiert, 
warum es passiert und welche Daten über die Leitung eingetroffen sind. 
Und oft sind diese Daten nicht so, wie du eigentlich denkst, dass sie 
sein müssten. Deine Ausgaben erzählen dir diese Geschichte. Stochern im 
Nebel erzählt dir gar nichts.

Ein paar Ausgaben da und dort sind schnell eingebaut und bei der 
Fehlersuche unendlich hilfreich. Und genauso schnell sind sie, wenn 
alles fertig ist, auch wieder ausgebaut.

von Spess53 (Gast)


Lesenswert?

Hi

Schon mal die Software von WIZNET angesehen?

MfG Spess

von Promas (Gast)


Lesenswert?

Danke für den Hinweis bezügl. der Variablen Größe!
Wenn wir über den TCP-IP-Builder z.B 123456 an den Wiznet schicken 
erwarten wir uns eine Paketlänge von 6. Da der Wiznet die empfangenen 
Daten in 2 Register aufgeteilt müssen wir die beiden Register 
hintereinander auslesen und die Packsize halbieren, da ja 2 Zeichen in 
einem Schleifendurchlauf ausgelesen werden.
mfg promas

von Karl H. (kbuchegg)


Lesenswert?

Promas schrieb:

> hintereinander auslesen und die Packsize halbieren, da ja 2 Zeichen in
> einem Schleifendurchlauf ausgelesen werden.


Und jetzt überlegst du mal, was deine for-Schleife macht.

Deine PackSize sei 12.
Wie oft wird die Schleife durchlaufen?

Schnapp dir Papier und Bleistift und simulier das mal durch.

Dieser Code abschnitt
1
  Pack_Size_Hilf = Pack_Size/2; //die auszulesenden Daten werden aúf 2 Register aufgeteilt
2
  
3
  for (Index=0;Pack_Size_Hilf>1;Index++)
4
  {
5
    Pack_Size_Hilf= Pack_Size_Hilf/2;
6
    byte_array0[Index] = W5300_DATA_READ(0x230); // 0x230 und 0x231 sind die Empfangsbuffer des W5300
7
    byte_array1[Index] = W5300_DATA_READ(0x231);
8
    
9
  }

von Karl H. (kbuchegg)


Lesenswert?

Spess53 schrieb:
> Hi
>
> Schon mal die Software von WIZNET angesehen?

Gehe ich recht in der Annahme, dass es für solche Sachen auch wunderbare 
fertige Funktionen gibt und sich niemand auf Registerebene damit 
rumschlagen muss?

von Promas (Gast)


Lesenswert?

Die Schleife würde vermutlich 1-2 mal durchlaufen => Anstatt des /2 muss 
ein -2 verwendet werden?
mfg promas

von NopNop (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Spess53 schrieb:
>> Hi
>>
>> Schon mal die Software von WIZNET angesehen?
>
> Gehe ich recht in der Annahme, dass es für solche Sachen auch wunderbare
> fertige Funktionen gibt und sich niemand auf Registerebene damit
> rumschlagen muss?

http://www.wiznet.co.kr/UpLoad_Files/ReferenceFiles/W5300_Drv_AVR_V1.2.2.zip

von Spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>Gehe ich recht in der Annahme, dass es für solche Sachen auch wunderbare
>fertige Funktionen gibt und sich niemand auf Registerebene damit
>rumschlagen muss?

Sieh es dir selbst an. Du weisst doch, das ich mit C nicht viel am Hut 
habe. Außerdem habe ich bisher nur mit dem W5100 und W5200 in den 
Fingern gehabt. Beide laufen bei mir unter Assembler wunderbar.

Zum W5300 Driver gibt es auch noch eine Hilfedatei bei Wiznet.

MfG Spess

von Spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Mist falsche Datei.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Promas schrieb:
> Die Schleife würde vermutlich 1-2 mal durchlaufen => Anstatt des /2 muss
> ein -2 verwendet werden?

Nicht vermutlich.
Hör auf zu raten und spiel den Code im Kopf durch. So schwer ist das 
nichgt, du wirst ja wohl im Kopf 2 Variablen und deren Werte verfolgen 
können, während du den Code in Gedanken durcharbeitest. Und wenn du das 
im Kopf nicht kannst, dann nimm dir ein Schmierpapier, mach 2 Kästen 
rein, über den einen schreibst du 'Index' und über den anderen 
'PackSizeHilf' und schreibst eben dort immer wieder die Werte rein bzw. 
radierst sie aus. So wie dir das dein Programm vorschreibt.

Deine PackSize sei 12
Was passiert in diesem Code
1
  Pack_Size_Hilf = Pack_Size/2; //die auszulesenden Daten werden aúf 2 Register aufgeteilt
2
  
3
  for (Index=0;Pack_Size_Hilf>1;Index++)
4
  {
5
    Pack_Size_Hilf= Pack_Size_Hilf/2;
6
    byte_array0[Index] = ...
7
    byte_array1[Index] = ...
8
  }

Wie oft sollte die for-Schleife bei einer PackSize von 12 durchlaufen 
werden und wie oft wird sie durchlaufen?

von Promas (Gast)


Lesenswert?

Packsize_Hilf = 6.
Beim ersten Durchlauf wird Packsize halbiert, d.h es wird auf 3 
reduziert. Beim 2. Durchlauf wird es noch einmal halbiert und somit 1,5 
da wir jeoch nicht wissen, ob diese Integer aufgerundet oder abgerundet 
wird, wenn ihr ein Float-Wert zugewiesen wird, kommen wir nicht auf eine 
genaue Anzahl von Durchläufen.

von Karl H. (kbuchegg)


Lesenswert?

Promas schrieb:
> Packsize_Hilf = 6.
> Beim ersten Durchlauf wird Packsize halbiert, d.h es wird auf 3
> reduziert. Beim 2. Durchlauf wird es noch einmal halbiert und somit 1,5

no.
3 durch 2 ergibt 1.
Du hast Integer Variablen

> ob diese Integer aufgerundet oder abgerundet
> wird, wenn ihr ein Float-Wert zugewiesen wird

Es wird ihr kein Float Wert zugewiesen. Die ganze Division wird nicht in 
Float gerechnet.


Ich empfehle dringend den Erwerb eines C-Buches.

(und ausserdem ist das gar nicht der springende Punkt)

von Karl H. (kbuchegg)


Lesenswert?


von Promas (Gast)


Lesenswert?

Ja ok, die for-Schleife wird 2 mal durchlaufen, aber was ist dann der 
springende Punkt??

von Karl H. (kbuchegg)


Lesenswert?

Promas schrieb:
> Ja ok, die for-Schleife wird 2 mal durchlaufen, aber was ist dann der
> springende Punkt??

das sie hätte 6 mal durchlaufen werden sollen und nicht 2 mal!

von Promas (Gast)


Lesenswert?

Vielen, vielen Dank für die Hilfe! (Natürlich auch Spess53!)

von asdffdsa (Gast)


Lesenswert?

Hallo Promas,

Ich bin gerade dabei mir einen Webserver mit dem WIZ830mj Modul (W5300 
Ethernet controller) zu basteln :-)

Ich benutze auch einen Atxmega128. Leider klappt bei mir das Pingen 
nicht. Verstehe aber nicht ganz warum.

Beim Reset bin ich mir nicht sicher. Im Datenblatt steht das dieses 
Signal low-active ist. Wenn ich den Reset so wie im Code unten 
implementiere und mein Board mit dem PC verbinde leutet die grüne LED am 
RJ45 Stecker.
Aber ich denke es müsste ja genau umgekehrt sein oder?? weil es ja 
low-active sein sollte (so wie im Code unten in den Kommentaren)
wenn ich es so implementiere leuchtet die LED nicht und es scheint so 
als funktioniert nichts :-)

Wie hast du den W5300 initialisiert?
Habe ich vlt etwas vergessen?

Was vlt noch gesagt werden muss, ich habe das WIZ530mj Modul nicht an 
den External Bus Interface vom Microcontroller angeschlossen und muss 
jetzt natürlichdie komplette Ansteuerung ausprogrammieren (also 
CS,hardware Reset,...) Im Bsp Code auf der Wiznet Webseite ist das 
leider nicht so...

Hier meine init Funktion:
1
void init_wiznet() {
2
    // setting data bus width -> 8bit bus
3
   WIZ_CONFIG &= ~(1<<BIT16EN);
4
   
5
   //Hardware reset
6
   //WIZ_CONFIG &= ~(1<<RESET); // reset low setzen --> Reset high
7
   WIZ_CONFIG |= (1<<RESET); // reset high setzen --> Reset low
8
   _delay_ms(10);
9
   //WIZ_CONFIG |= (1<<RESET); // reset high setzen --> Reset low
10
   WIZ_CONFIG &= ~(1<<RESET); // reset low setzen --> Reset high
11
   _delay_ms(5);
12
   //WIZ_CONFIG &= ~(1<<RESET); // reset low setzen --> Reset high
13
   WIZ_CONFIG |= (1<<RESET); // reset high setzen --> Reset low
14
   _delay_ms(1);
15
   
16
17
   // register reset
18
   write_data_wiznet(MR0, 0x00);
19
   write_data_wiznet(MR1, 0x80);
20
   
21
   //Set gateway IP address
22
   write_data_wiznet(GAR0, 192);
23
   write_data_wiznet(GAR1, 168);
24
   write_data_wiznet(GAR2, 0);
25
   write_data_wiznet(GAR3, 1);
26
27
   //Set Subnet mask
28
   write_data_wiznet(SUBR0, 255);
29
   write_data_wiznet(SUBR1, 255);
30
   write_data_wiznet(SUBR2, 255);
31
   write_data_wiznet(SUBR3, 0);
32
33
   //Set MAC address
34
   write_data_wiznet(SHAR0, 0x00);
35
   write_data_wiznet(SHAR1, 0x16);
36
   write_data_wiznet(SHAR2, 0x6F);
37
   write_data_wiznet(SHAR3, 0x09);
38
   write_data_wiznet(SHAR4, 0x2C);
39
   write_data_wiznet(SHAR5, 0x03);
40
41
   //Set own IP address
42
   write_data_wiznet(SIPR0, 192);
43
   write_data_wiznet(SIPR1, 168);
44
   write_data_wiznet(SIPR2, 0);
45
   write_data_wiznet(SIPR3, 73);
46
   
47
   //
48
   write_data_wiznet(RTR0, 0x0F);
49
   write_data_wiznet(RTR1, 0xA0);
50
   write_data_wiznet(RCR1, 0x07);
51
   
52
   write_data_wiznet(MTYPER0, 0x00);
53
   write_data_wiznet(MTYPER1, 0xFF);
54
}


Vielen Dank schon im Voraus!

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.