- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 7 von 7

Thema: Problem mit Wiznet Wiz830mj Modul!

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.01.2005
    Beiträge
    103

    Problem mit Wiznet Wiz830mj Modul!

    Anzeige

    E-Bike
    Hallo

    Ich verwende das Wiz830Mj Modul und einen Atmega32L. Ich möchte eine als
    ersten Schritt eine Verbindung vom PC zu meinem Board (über Ethernet)
    herstellen und später einen Webserver implementieren.Leider klappt das
    Pingen nicht.
    ´
    Der Atmega ist folgendermaßen mit dem Wiznet Modul verbunden:
    Atmega -> Wiz830mj
    PortA -> D0...D7
    PortB (Pin 0,1) -> A8,A9
    PortC -> A0...A7
    PortD.2 -> /RD
    PortD.3-> /CS
    PortD.4 -> /RESET
    PortD.5 -> /WR
    PortD.6 -> /INT (verwende ich in der Software noch nicht)

    Die Spannungsversorgungen und GND Leitungen vom Atmega und Wiznet Modul
    sollten stimmen. Habe als Testprogramm ein einfaches Blinklicht in den
    Atmega programmiert und es funktioniert. Beim Wiznet Modul habe ich
    mehrmals nach gemessen. Also ich denke der Aurbau müsste passen.

    So nun habe ich im Netz einen Bascom code zur Initialisierung eines
    Wiz810mj Moduls gefunden. Dieses Modul hat einen W5100 und das Wiz830mj
    einen W5300 drauf. (Bens Hobby Corner) Dabei wird der Controller(W5100)
    auf dem Wiznet Modul per SPI initialisiert. Beim Wiz830mj kann ich den
    Controller (W5300) nur parallel ansteuern. Im Datenblatt findet man auch
    ein Zeitdiagramm um Werte in ein bestimmtes Register vom W5300 schreiben
    zu können.

    Ich habe hier mal die Funktion um Daten in ein bestimmtes Register des
    W5300 zu schreiben:
    Code:
    void write_data_wiznet(int registers, int value) {
       DATA_L_DDR = 0xFF;   //setting as outputs
       _delay_ms(5);
       ADDRESS_H = getHighAddress(registers);  //Highbyte aus registers und am PortB ausgeben 
       ADDRESS_L = getLowAddress(registers); // Low byte aus registers und am PortC ausgeben
       _delay_us(1);
       WIZ_CONFIG &= ~CS; // CS low setzen -> Wiznet enabled   
       //WIZ_CONFIG |=  RD;  // RD high setzen -> read disabled
       _delay_us(1);
       WIZ_CONFIG &= ~WR;  // WR low setzen -> write enabled
        _delay_us(0.010);  
       DATA_L = value;
       _delay_us(1);  
       WIZ_CONFIG |= WR;  // WR high setzen -> write disabled
       _delay_us(1);
       WIZ_CONFIG |= CS; // CS high setzen -> Wiznet disabled
       _delay_us(1);
    
       ADDRESS_H = 0x00;
       ADDRESS_L = 0x00;
       DATA_L = 0x00;
    }

    Ich glaube das in dieser Funktion der Hund begraben ist, doch leider
    weiß ich einfach nicht was ich falsch mache! Der Code müsste doch so
    stimmen oder??
    Ich wäre euch sehr dankbar wenn ihr mir weiterhelfen könntet!

    mfg[/code]

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Der Code müsste doch so stimmen oder??
    Was Allgemeines:
    Wenn du Fragen zu Code hast, dann poste alles, was zu diesem Code dazugehört. Wie soll dir irgendjemand hier sagen können, ob z.B. die Zeile "ADDRESS_H = getHighAddress(registers);" richtig ist, wenn wir weder das Makro "ADDRESS_H" kennen, noch die Funktion "getHighAddress"?

    Was Konkretes:
    Code:
       WIZ_CONFIG &= ~WR;  // WR low setzen -> write enabled
        _delay_us(0.010); 
       DATA_L = value;
    Das ist verkehrt herum, und das Delay ist überflüssig, bzw. sogar schädlich. Du hast dich von dem Diagramm im Datenblatt verwirren lassen.
    tDATAs | Data Setup Time after /WR low | MIN 7 ns | MAX 7ns + 7XPLL_CLK
    Das bedeutet nicht, dass du die Daten in diesem Bereich ausgeben musst. Es bedeutet, dass der W5300 in diesem Bereich anfängt, die Daten einzulesen. Sie müssen also zwingend schon vorher "da" sein. Am einfachsten und sichersten erreicht man das, indem man erst die Daten ausgibt, und dann WR auf Low zieht.

    PS: Und lösche den anderen Thread bevor da noch jemand antwortet.
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.01.2005
    Beiträge
    103
    Ok danke für die schnelle Antwort. Also das heißt ich könnte auch die Daten ausgeben bevor ich schon mit dem /CS auf low gehe oder? und wenn dann /CS und /WR auf low gehen sind die Daten bzw die Adresse schon verfügbar??

    Hier mal der gesamte Code

    Code:
    #define F_CPU 4000000UL  /* 16 MHz CPU clock */
    
    #include <util/delay.h>
    #include <avr/io.h>
    
    #include "ethernet.h"
    
    
    void init_ports() {
       WIZ_CONFIG_DDR = 0xBF;
       ADDRESS_L_DDR = 0xFF;
       ADDRESS_H_DDR = 0xFF;
       DATA_L_DDR = 0xFF;
    
       WIZ_CONFIG =0xBF;
       
    }
    
    void init_wiznet() {
    
       // Hardware reset
       WIZ_CONFIG |= RESET;
       _delay_us(10);
       WIZ_CONFIG &= ~RESET;
       _delay_us(10);
       WIZ_CONFIG |= RESET;
       _delay_ms(20);
    
       // register reset
       write_data_wiznet(MR0, 0x80);
       write_data_wiznet(MR1, 0x00);
    
       //Set gateway IP address
    /*   write_data_wiznet(GAR0, 192);
       write_data_wiznet(GAR1, 168);
       write_data_wiznet(GAR2, 0);
       write_data_wiznet(GAR3, 1);
    */
       //Set Subnet mask
       write_data_wiznet(SUBR0, 255);
       write_data_wiznet(SUBR1, 255);
       write_data_wiznet(SUBR2, 255);
       write_data_wiznet(SUBR3, 0);
    
       //Set MAC address
       write_data_wiznet(SHAR0, 0x00);
       write_data_wiznet(SHAR1, 0xC0);
       write_data_wiznet(SHAR2, 0x9F);
       write_data_wiznet(SHAR3, 0x9E);
       write_data_wiznet(SHAR4, 0x80);
       write_data_wiznet(SHAR5, 0x2F);
    
       //Set own IP address
       write_data_wiznet(SIPR0, 192);
       write_data_wiznet(SIPR1, 168);
       write_data_wiznet(SIPR2, 0);
       write_data_wiznet(SIPR3, 73);
    
       //Allocation internal TX/RX memory for SOCKETn
       
    }
    
    void write_data_wiznet(int registers, int value) {
       DATA_L_DDR = 0xFF;   //setting as outputs
       _delay_ms(5);
    
       ADDRESS_H = getHighAddress(registers);
       ADDRESS_L = getLowAddress(registers);
       _delay_us(1);
       WIZ_CONFIG &= ~CS; // CS low setzen -> Wiznet enabled   
       //WIZ_CONFIG |=  RD;  // RD high setzen -> read disabled
       _delay_us(1);
       WIZ_CONFIG &= ~WR;  // WR low setzen -> write enabled
        _delay_us(0.010);  
       DATA_L = value;
       _delay_us(1);  
       WIZ_CONFIG |= WR;  // WR high setzen -> write disabled
       _delay_us(1);
       WIZ_CONFIG |= CS; // CS high setzen -> Wiznet disabled
       _delay_us(1);
    
       ADDRESS_H = 0x00;
       ADDRESS_L = 0x00;
       DATA_L = 0x00;
    }
    
    int read_data_wiznet(int registers) {
       int value = 0;
       DATA_L_DDR = 0x00;   //setting as inputs
    
       WIZ_CONFIG &= ~CS; // CS low setzen -> Wiznet enabled
       WIZ_CONFIG &= ~RD;  // RD low setzen -> read enabled
       WIZ_CONFIG |=  WR;  // WR high setzen -> write disabled
       ADDRESS_H |= getHighAddress(registers);
       ADDRESS_L = getLowAddress(registers);
       value = DATA_L;
       WIZ_CONFIG |= CS; // CS high setzen -> Wiznet disabled
    
       return value;
    }
    
    
    int getHighAddress(int address) {
       int address_h = 0;
    
       address_h = (address & 0xFF00) >> 8;  
       return address_h; 
    }
    
    int getLowAddress(int address) {
       int address_l = 0;
    
       address_l = (address & 0x00FF);
       return address_l; 
    }
    //ethernet.h
    #define WIZ_CONFIG  PORTD
    #define WIZ_CONFIG_DDR DDRD
    #define RD         _BV(PD2)
    #define CS         _BV(PD3)
    #define RESET      _BV(PD4)
    #define WR         _BV(PD5)
    
    #define DATA_L       PORTA
    #define DATA_L_DDR   DDRA
    
    #define ADDRESS_L       PORTC
    #define ADDRESS_H       PORTB
    #define ADDRESS_L_DDR   DDRC
    #define ADDRESS_H_DDR   DDRB
    
    
    
    //mode register
    #define MR0 0x0000
    #define MR1 0x0001
    
    // register: Gateway address
    #define GAR0 0x0010
    #define GAR1 0x0011
    #define GAR2 0x0012
    #define GAR3 0x0013
    
    // register: Subnet mask
    #define SUBR0 0x0014
    #define SUBR1 0x0015
    #define SUBR2 0x0016
    #define SUBR3 0x0017
    
    // register: Hardware address
    #define SHAR0 0x0008
    #define SHAR1 0x0009
    #define SHAR2 0x000A
    #define SHAR3 0x000B
    #define SHAR4 0x000C
    #define SHAR5 0x000D
    
    // register: IP address
    #define SIPR0 0x0018
    #define SIPR1 0x0019
    #define SIPR2 0x001A
    #define SIPR3 0x001B
    
    // register: Sockets
    #define TMSR0 0x0020
    #define TMSR1 0x0021
    #define RMSR0 0x0028
    #define RMSR1 0x0029
    
    #define MTYPER0 0x0030
    #define MTYPER1 0x0031
    
    void init_ports();
    int getHighAddress(int address);
    int getLowAddress(int address);
    void write_data_wiznet(int registers, int value);
    int read_data_wiznet(int registers);
    void init_wiznet();
    mfg doolitle

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von doolitle15
    Also das heißt ich könnte auch die Daten ausgeben bevor ich schon mit dem /CS auf low gehe oder?
    Ja. /CS ist hier aber nicht entscheidend. Wichtig ist, dass die Daten bereits "da" sind, wenn /WR auf Low geht.

    Und in read_data_wiznet hast du das gleiche Problem. Die Adresse muss schon "da" sein, wenn /RD auf Low geht. Außerdem hast du dort vergessen /RD wieder auf High zu setzen.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.01.2005
    Beiträge
    103
    Okay super danke für die schnelle Hilfe! Ich werde die Funktionen gleich mal umschreiben und dann einen neuen Ping versuch starten.

    Melde mich dann ob es funktioniert hat.

    mfg

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.01.2005
    Beiträge
    103
    Meine write Funktion sieht jetzt so aus:
    Code:
    void write_data_wiznet(int registers, int value) {
       DATA_L_DDR = 0xFF;   //setting as outputs
       _delay_ms(5);
    
       ADDRESS_H = getHighAddress(registers);
       ADDRESS_L = getLowAddress(registers);
        DATA_L = value;
       _delay_us(1);
       WIZ_CONFIG &= ~CS; // CS low setzen -> Wiznet enabled   
       //WIZ_CONFIG |=  RD;  // RD high setzen -> read disabled
       _delay_us(1);
      
       WIZ_CONFIG &= ~WR;  // WR low setzen -> write enabled 
       _delay_us(1);  
       WIZ_CONFIG |= WR;  // WR high setzen -> write disabled
       _delay_us(1);
       WIZ_CONFIG |= CS; // CS high setzen -> Wiznet disabled
       _delay_us(1);
    
       ADDRESS_H = 0x00;
       ADDRESS_L = 0x00;
       DATA_L = 0x00;
    }
    Sollte doch jetzt so stimmen oder habe ich wieder etwas vergessen?

    Jetzt mal eine andere Frage. Ich schließe das Board über ein Kabel direkt an meinen Laptop an. Welche Adressen muss ich jetzt für MAC, Subnetmask, Standardgateway eingeben?? Für die Mac Adresse habe ich im CMD einfach IPCONFIG /ALL eingegeben und die Adresse die dort stand dann genommen. Für die IP Adresse vom Board kann ich mir eine aussuchen oder?

    mfg

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.01.2005
    Beiträge
    103
    So jetzt habe ich gerade noch einen Fehler entdeckt. Der Reset muss mindenstens 2us auf low gehalten werden und dann max. 10ms warten bis der pll-lock eingeschwungen ist. (nicht 20ms) Ich habe die 20ms auf 5 ms geändert aber leider funktioniert das pingen trotzdem noch nicht.

    mfg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress