Hallo, mein myEthernet greift (vorgegeben) mit USART1 in SPI Mode auf den ENC zu. PIN D2=MISO=RX; D3=MOSI=TX; D4=SCK=XCK; D5=invCS; Initialisierung: UBRR1=0;//Baud Register erst auf null setzten SPI2_DDR |= (1<<4);//Clock Ausgang SPI2_DDR &=~ (1<<SPI2_MISO); //MISO Eingang SPI2_DDR |= (1<<SPI2_MOSI);//MOSI Ausgang SPI2_DDR |= (1<<5);//CS Ausgang UCSR1C = (1<<UMSEL11) | (1<<UMSEL10) | (0<<UCPHA1) | (0<<UCPOL1);//MSPI //Mode, SPI Mode 0 UCSR1B = (1<<RXEN1) | (1<<TXEN1);//enable Receiver and Transmitter UBRR1 = 129;//Baudrate 9600 SPI_DISABLE(); //=CS high //Es soll zur Probe ein Register aus dem ENC ausgelesen werden //Nach Reset ist das ERXFCON Register 10100001 //Um den ENC zu lesen wird der OPcode und die Adresse des Registers an den ENC gesendet. Dieser antwortet (in diesem Fall) ohne Dummybyte direkt mit dem Inhalt des Registers. SPI_ENABLE();//CS low // _delay_ms(1); dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register UDR1 =reg;//sends data; hier:00011000 = Op code und adressse =read ERXFCON while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received value=UDR1; SPI_DISABLE();//CS wieder high DDRA=0xff;//Port A (LEDs-Extern)=Ausgang; PORTA=value; //Wert zur Kontrolle an die 8 LEDs ausgeben Nun zum Problem: Ich bekomme vom UDR1 Register immer nur 0x00 zurück und nicht den Wert, den ich von dem abgefragten Register erwarte. Dass die Register richtig definiert sind und dass die Bits richtig gesetzt werden habe ich mit debugging überprüft. Hat jemand Rat? Gruß Manni
Hallo, soweit ich sehen kann sollte es gehen, um auszuschließen, das es am ENC liegt, kannst du RX ja mal mit TX verbinden - CS lässt du deaktiviert. Damit solltest du das gesendete wieder empfangen. Sascha
>//Um den ENC zu lesen wird der OPcode und die Adresse des Registers an >den ENC gesendet. Dieser antwortet (in diesem Fall) ohne Dummybyte >direkt mit dem Inhalt des Registers. Das halte ich für Blödsinn. Woher soll der ENC wissen welches Register er lesen soll ohne vorher den Opcode gesendet zu haben? Das wär ja so als könnte er eine Antwort raten ohne die Frage zu kennen. Schick das Dummybyte und lies dann noch mal.
Habe Tx und Rx verbunden. Damit konnte ich meine gesendete Adresse und opcode selbst empfangen. @Holger: Der ENC sendet bei Abfragen des MAC Registers erst ein Dummybyte, gefolgt von dem Inhalt des MAC registers. Bei dem abgefragten Ethernet-Register sollte aber sofort der Inhalt folgen. Einen Fehler habe ich schon korrigiert: Ich habe bisher versucht aus dem falschen Register zu lesen, da es sich um ein Bank1 Register handelt. Und nach einem Reset liest der ENC erstmal von Bank0. Habe daraufhin versucht das ERDPTH-Register zu lesen. das sollte nach Reset nicht null sein. Ich lese aber immer nur 0x00 aus. Muss ich den ENC noch zusätzlich irgendwie Initialisieren? Software-Reset? Gruß
>Bei dem abgefragten Ethernet-Register sollte aber sofort der Inhalt >folgen. Wo steht das im Datenblatt? Tut mir leid ich finde das nirgends. Die Timingdiagramme sagen auch was anderes.
Seite 27 ENC28J60 user guide: if the 5 bit address is an ETH Register, then the data in the selected register will start shifting out immediately.
>Seite 27 ENC28J60 user guide: >if the 5 bit address is an ETH Register, then the data in the selected >register will start shifting out immediately. Ja, aber erst wenn der Opcode komplett übertragen wurde. Das rausshiften musst du mit dem senden eines Dummybytes machen. Sonst werden keine Clock Impulse für das SPI generiert. Aber was rede ich, du willst ja nicht. Dein Problem hätte vor 10 Minuten gelöst sein können.
Manfred Brunner schrieb: > Seite 27 ENC28J60 user guide: > if the 5 bit address is an ETH Register, then the data in the selected > register will start shifting out immediately. Dann schau Dir mal die Abbildung 4-3 auf dieser Seite an, dann siehst Du, dass die Daten erst ab dem 8.Takt übertragen werden. Also erst nach mit dem 2.Byte.
Jetzt verstehe ich was ihr meint. Probier ich gleich.
Ich dachte ich habs verstanden. Hab den Code abgeändert: SPI_ENABLE();//CS low _delay_ms(1); dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register UDR1 =reg;//sends data from transmit buffer to ENC: opcode und adress UDR1=dummy;//sendet weiterhin clock //gleichzeitig wird das Register vom ENC gelesen while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from ENC) value=UDR1; SPI_DISABLE();//CS wieder high value liest aber immer nur null aus; Sollte der code so in Ordnung sein?
Wenn du in UDR1 schreibst musst du warten bis die Daten raus sind. Du kannst da nicht einfach kurz nacheinander reinschreiben.
Habe jetzt vor dem Dummybyte den transmitbuffer geleert: dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer UDR1=dummy;//sendet weiterhin clock //gleichzeitig wird das Register vom ENC gelesen usw.. Funktioniert aber immer noch nicht.
>Habe jetzt vor dem Dummybyte den transmitbuffer geleert:
Lass das sein.
SPI_ENABLE();//CS low _delay_ms(1); dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register UDR1 =reg;//sends data from transmit buffer: opcode und adress while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from ENC) value=UDR1; //dummybyte senden damit clock weiterläuft dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer UDR1=dummy;//sendet weiterhin clock //gleichzeitig wird das Register vom ENC gelesen while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from ENC) value=UDR1; // jetzt wird adresssiertes register ausgelesen dummy=UDR1;//Transmit buffer leeren while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer UDR1=dummy;//sendet weiterhin clock //gleichzeitig wird das Register vom ENC gelesen while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from ENC) value=UDR1; SPI_DISABLE();//CS wieder high Es hat geklappt. Ich konnte erfolgreich ein Register (ECON2) auslesen. Ich danke euch.
holger schrieb: > Wenn du in UDR1 schreibst musst du warten bis die Daten raus sind. > Du kannst da nicht einfach kurz nacheinander reinschreiben. Doch, das geht. UDR1 ist doppelt gepuffert. Ein 16-Bit Transfer kann durchgeführt werden, indem 2 Bytes direkt hintereinander in UDR1 geschrieben werden. Aber: Um zu prüfen, ob die Datenübertragung abgeschlossen wurde, darf dann nicht das RXC1-Bit (Receive complete) abgefragt werden (dieses wird schon nach dem ersten empfangenen Byte gesetzt). Es muss das TXC1-Bit (Transmit Complete) im UCSR1A-Register abgefragt werden. Dieses wird nämlich erst dann gesetzt, wenn beide Bytes übertragen wurden. Aber Manfred hat es ja jetzt mit zwei hintereinander ausgeführten 1-Byte Transfers hinbekommen.
>> Wenn du in UDR1 schreibst musst du warten bis die Daten raus sind. >> Du kannst da nicht einfach kurz nacheinander reinschreiben. >Doch, das geht. UDR1 ist doppelt gepuffert. Ein 16-Bit Transfer kann >durchgeführt werden, indem 2 Bytes direkt hintereinander in UDR1 >geschrieben werden. Ja, da hast du recht. Das Problem ist nur ob man sicher stellen kann das nicht vorher schon mal jemand in UDR1 geschrieben hat. Wenn nicht muss UDRE1 abgefragt werden. Ansonsten ist SPI über UART wegen des Double Buffers sogar schneller als das reine SPI Modul. Man muss halt aufpassen was man tut;)
holger schrieb: > Ja, da hast du recht. Das Problem ist nur ob man sicher stellen > kann das nicht vorher schon mal jemand in UDR1 geschrieben hat. > Wenn nicht muss UDRE1 abgefragt werden. UDRE1 sollte vor jedem Transfer abgefragt werden, egal ob 8 oder 16 Bit zu übertragen sind. > Ansonsten ist SPI über UART wegen des Double Buffers sogar schneller > als das reine SPI Modul. Ein weiterer Vorteil ist, dass die Clockfrequenz viel feiner einstellbar ist.
ich vor einiger Zeit recht bereistegt die Buchreihe von Suzanne Collins gelesen hatte, war ich sehr gespannt auf den ersten Film der Serie. Ich hatte zwar beffcrchtet das
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.