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
voidREAD_LAN()
2
{
3
uint16_tPack_Size;
4
uint16_tIndex;
5
uint16_tIndex2;
6
uint16_tPack_Size_Hilf;
7
uint8_tbyte_array0[3];
8
uint8_tbyte_array1[3];
9
uint8_tdummy;
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
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!
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.
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
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
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?
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
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?
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.
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)
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!
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
voidinit_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