Geehrte Kollegen, wenn eine Speicherzelle (Reg.= MAMXFLH IC=ENC28J60) ein "Value of Reset" von 6 hat und ich gebe dort eine 5 ein so erhalte ich beim Auslesen dieser Zelle eine 7 (0110 + 0101 = 0111). Die voreingestellte 6 läßt sich nicht löschen. Wie gehe ich damit um wenn der richtige Wert dieser Zelle für den ENC28J60 entscheident ist. In dieser Speicherzelle soll die Framelänge (hier High-Byte) eingtragen werden. Danke euch, Bernd
BerndB schrieb: > Geehrte Kollegen, > > wenn eine Speicherzelle (Reg.= MAMXFLH IC=ENC28J60) ein "Value of Reset" > von 6 hat und ich gebe dort eine 5 ein so erhalte ich beim Auslesen > dieser Zelle eine 7 (0110 + 0101 = 0111). > Die voreingestellte 6 läßt sich nicht löschen. Das klingt in höchstem Masse unlogisch. So etwas wäre in der Paxis nicht sehr brauchbar. Womit sich der Verdacht erhärtet, das eigentliche Problem sitzt irgendwo in deinem Code.
Hallo Karl Heinz, danke für deine Antwort! Bei der Initialisierung des ENC28J60 habe ich bis auf diese Speicherzelle keine Probleme. Was ich reinschreibe kann ich aus auslesen. Bis auf die eine Zelle und mir ist aufgefallen das im Datenblatt "Value on Reset = 6" steht. Und diese "6" ist nicht löschbar. Mache ich was falsch, oder soll dieser Wert hier eine Mindestframelänge angeben?
Nenne Code *.c oder *.asm, aber nicht *.txt!
BerndB schrieb:
1 | > STS (SRAM_DATA_CODE), temp_1 //HIER IST EIN FEHLER ERGEBNIS = 7 statt 5 |
Und wie hast Du das geprüft? Und was hat das mit der "6" zu tun? Ethernet in Assembler, sehr ambitioniert. Peter
Hallo Peter, ich hab es in Assembler geschrieben. Geprüft habe ich das indem ich dem Speicherinhalt (hier MAMXFLH) über UART zu meiner LCD-Anzeige gesendet habe. Bernd
BerndB schrieb: > Hallo Peter, > > ich hab es in Assembler geschrieben. > > Geprüft habe ich das indem ich dem Speicherinhalt (hier MAMXFLH) über > UART zu meiner LCD-Anzeige gesendet habe. Und wo sieht man das in deinem Code? Nach dem Setzen kommt zwar ein Abschnitt, der mit Kontrolle übertitelt ist, aber da wird nicht MAMXFLH ausgelesen sondern ein Teil der MAC-Adresse Ich finde deinen Code sehr unübersichtlich und schwer zu lesen. Mir wimmelt es da auch zu sehr von STS und LDS und temp1. Wenn du sowieso dauernd das temp1 Register benutzt, wozu soll es dann gut sein, wenn du dir dauernd irgendwas im SRAM als Parameter zwischenspeicherst. Definier dir 2 Register, die als Schnittstelle zu den SPI Funktionen dienen (aber nenn sie nicht temp1 und temp2 ... ordentliche aussagekräftige Namen!), lade die mit den Werten und ruf die Funktion auf. Ich sehe nicht wirklich, was es bringen soll, wenn du vorher alles mittels STS in den Speicher schreibst, nur damit es sich die Funktion dann wieder mittels LDS erneut wieder nach temp1 holt. Es wird zwar wahrscheinlich egal sein, aber wenn du hier
1 | CHANGE_BANK: |
2 | LDS temp_1, (SRAM_BANK_NUMBER_NEW) |
3 | LDS temp_2, (SRAM_BANK_NUMBER_OLD) |
4 | |
5 | CP temp_1, temp_2 |
6 | BREQ CHANGE_BANK_END |
7 | TST temp_1 |
8 | BREQ BANK_00 |
9 | CPI temp_1, 1 |
10 | BREQ BANK_01 |
11 | CPI temp_1, 2 |
12 | BREQ BANK_02 |
13 | CPI temp_1, 3 |
14 | BREQ BANK_03 |
15 | |
16 | .... |
sowieso mit den Konstanten 0, 1, 2, 3 für die Banknummer vergleichst, dann solltest du hier beim Aufruf
1 | LDI temp_1, (1<<ENC28J60_BIT_ECON1_BSEL_1)|(0<<ENC28J60_BIT_ECON1_BSEL_0) //Bank 0x02 |
2 | STS (SRAM_BANK_NUMBER_NEW), temp_1 |
3 | |
4 | RCALL CHANGE_BANK |
dann auch diese Konstanten benutzen und nicht die Bitdefinitionen (auch wenn es aufs gleiche rausläuft). Denn die Funktion erwartet laut Funktions-API eine der Konstanten 0, 1, 2, oder 3 in SRAM_BANK_NUMBER_NEW. Das hat dann auch den Vorteil, dass du dir hier
1 | LDI temp_1, 2 |
2 | STS (SRAM_BANK_NUMBER_NEW), temp_1 |
3 | |
4 | RCALL CHANGE_BANK |
den Kommentar sparen kannst, weil die Bank-Nummer direkt lesbar im Code steht. Noch besser wäre ein wenig Assembler-Hilfe
1 | LDI temp_1, BANK_2 |
2 | STS (SRAM_BANK_NUMBER_NEW), temp_1 |
3 | |
4 | RCALL CHANGE_BANK |
(und natürlich dann auch die entsprechenden Konstanten in der Funktion benutzen)- Mit deinen ursprünglichen Bits bei diesem Aufruf suggerierst du, dass da etwas speziell bitmässiges passiert, was ja laut Auswertung in der Funktion gar nicht der Fall ist. Es sind solche Kleinigkeiten, die einen Code schwer lesbar machen können, weil man sich dann wieder ein Detail mehr merken muss. Wie gesagt: Ich kenne zwar die Bitdefinitionen nicht, aber aus dem Rest der CHANGE_BANK Funktion wird klar, dass es keinen Unterschied macht, weil die Bits ohnehin so sind, dass sich die Zahlen ergeben, aber es ist ein Punkt der einen bei der Analyse zu unnötigem Kopfkratzen und der Analyse eines Details zwingt, das völlig unnötig analysiert wird.
Aahhhh. Hier liegt der Hund! Wenn du ein Register beschreiben willst, dann benutze auch das Kommando "Write Register". Dazu wurde es gemacht! Mit deinem Bitfield-Clear und Bitfield-Set hast du dich selber in Teufels Küche gebracht. Die Bitfield Operationen benutzt du, wann du tatsächlich ein einzelnes Bit setzen oder löschen willst. Um einem ganzen Register einen neuen Wert zuzuweisen gibt es das wunderbare Kommando 'Write Control Register'.
1 | The Bit Field Set (BFS) command is used to set up to |
2 | 8 bits in any of the ETH Control registers. Note that this |
3 | command cannot be used on the MAC registers, MII |
4 | registers, PHY registers or buffer memory. The BFS command |
5 | uses the provided data byte to perform a bit-wise |
6 | OR operation on the addressed register contents. |
Und da steckt dann auch die Oder-Operation drinnen, die du anhand deiner Daten gesehen hast.
Danke Karl Heinz für den Tip, er wird mir sehr helfen! Ich habe jetzt herausgefunden das meine "Bit Field Clear" Funktion gar nicht richtig funktioniert! Mal sehen ob ich das hin bekomme!
Was in die gleiche Kerbe schlägt, wie die Anmerkung von weiter oben. Warum muss in
1 | LDI temp_1, (ENC28J60_OP_BF_SET | MAMXFLH) //0x80 | 0x0B |
2 | STS (SRAM_OP_CODE), temp_1 |
3 | LDI temp_1, HIGH(1518) //0x05EE = 5 238 |
4 | STS (SRAM_DATA_CODE), temp_1 //HIER IST EIN FEHLER ERGEBNIS = 7 statt 5 |
5 | |
6 | RCALL WRITE_REGISTER_VALUE |
eigentlich das ENC28J60_OP_BF_SET angegeben werden (das ja eigentlich ein WRITE REGISTER sein sollte). Da wird doch sowieso eine spezielle Funktion zum Beschreiben eines Registers aufgerufen! Den entsprechenden Opcode kann auch die Funktion einfügen! Und dann hat man dieses Detail an einer zentralen Stelle und muss sich nicht bei jedem Aufruf darum kümmern.
BerndB schrieb: > Danke Karl Heinz für den Tip, er wird mir sehr helfen! > > Ich habe jetzt herausgefunden das meine "Bit Field Clear" Funktion gar > nicht richtig funktioniert! > Mal sehen ob ich das hin bekomme! Wirf sie raus. Um ein Register zu beschreiben gibt es ein eigenes Kommando! (Bitfield Clear will genauso wie Bitfield Set ein Argument. Nämlich WELCHE Bits zu clearen sind. Das kann ich in deinem Code nirgends sehen. ABER: Der ganze Ansatz mit den Bitfield Commandos ist schon Unsinn. Es gibt ein Commando um ein Register zu beschreiben. Ganz einfach und simpel. Du machst dir hier viel zu viel Arbeit selber)
Hack. Der ganze Bitfield Quatsch zieht sich quer durch deinen ganzen Code. Die Bank-Umschaltungen sind auch davon betroffen. Hast du denn nicht mal anderen Code studiert, wie die das machen, ehe du dich auf dieses Abenteuer eingelassen hast?
Karl Heinz, "genau das war es". BFS anstatt WCR!!! Ich weiß nicht was mich geritten hat, aber ich habe komischer Weise nur für dieses Register den BFS-Befehl benutzt. VIELEN DANK Karl Heinz! Gruß, Bernd
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.