Ich weiss zwar nicht, was ein MCP2515 ist, es ist aber bei meist allen ICs so, dass sie eine gewisse Anlaufzeit nach einem Reset haben. Wahrscheinlich sinds bei dem halt 150ns.
Hallo,
ich möchte mit einem ATmega48 einen MCP2515 ansteuern. Wenn ich (bei 16 MHz Takt beider ICs) erst über SPI einen Reset ausführe, dann 150 ns warte und dann einen Wert in ein Register schreibe, so wird dieser Wert korrekt gespeichert. Wenn ich zwischen Reset und Registerzugriff weniger als 100 ns warte, wird der Wert nicht gespeichert.
Woran könnte das liegen? Die SPI-Verbindung an sich funktioniert ja, gesendet werden beide Befehle auf auf jeden Fall (ich verändere ja nur die Wartezeit zwischen dem Senden beider Befehle).
Grüße
Randy
Ich weiss zwar nicht, was ein MCP2515 ist, es ist aber bei meist allen ICs so, dass sie eine gewisse Anlaufzeit nach einem Reset haben. Wahrscheinlich sinds bei dem halt 150ns.
Hallo,
du meinst 150 ms, ja?
Ich frage nach dem Reset das SPIF auf dem SPSR ab. Danach startet sofort das Bittiming. SPI läuft mit fosc/2 auch @ 16Mhz. Wenn du in C schreibst zeig doch mal den Code.
Gruß
Jens
Ähm ich meinte eigentlich rund 10 Nanosekunden, also 150 nop-Befehle, hatte das verwechselt. SPI läuft auch bei mir mit fosc/2.
@pongi: MCP2515 ist ein externer CAN-Controller. Das mit der Anlaufzeit klingt zwar einleuchtend, aber ich habe bisher noch nirgends einen Beispielcode gesehen, der wirklich zwischen Reset und dem Konfigurieren der Register eine Zeit lang wartet. Im Datenblatt kann ich dazu auch nichts finden.
Mein Code:
Code:// Enable SPI, Master, set clock rate fck/2 -> 8 MHz SPCR = (1<<SPE) | (1<<MSTR); SPSR = (1<<SPI2X); mcp2515_reset(); mcp2515_write(BFPCTRL, (1<<B0BFS) | (1<<B0BFE)); // Enable LED at RX0BF-PinWenn ich den Code so ausführe geht die LED nicht an (auch wenn ich in ein anderes Register schreibe und das Register wieder auslese, wurde der Wert darin nicht gespeichert). Aber wenn ich zwischen dem Reset und dem Write eben die 150 nop-Befehle warte, DANN funktioniert der Code.Code:uint8_t spi_putc(uint8_t data) { SPDR = data; while (!(SPSR & (1<<SPIF))) ; return SPDR; } void mcp2515_reset() { PORTB &= ~(0b00000100); // Chip Select low spi_putc(0xC0); PORTB |= 0b00000100; // Chip Select high } void mcp2515_write(uint8_t address, uint8_t data) { PORTB &= ~(0b00000100); // Chip Select low spi_putc(0x02); spi_putc(address); spi_putc(data); PORTB |= 0b00000100; // Chip Select high }
doch, ist so, hab ich bei Testaufbau auch beobachtet, das der MCP
erst "bootet" bevor er Anweisungen entgegennimmt ... don't worry
be happy
steht aber auch irgendwo im DB versteckt
Vor den Erfolg haben die Götter den Schweiß gesetzt
Hallo,
definitiv funktioniert bei mir das schreiben der Register unmittelbar nach dem Reset. Der Code sieht auf den ersten Blick gut aus. Denoch, was ich nicht weiß ist, wie schnell man nach Anlegen der Versorgung warten muss. Sollte sich aber schnell herausfinden lassen, indem du die NOP's mal vor den Reset schreibst. Ich starte meine Controller immer mit der größten Wartezeit und es werden vor dem CAN noch andere Initialisierungen durchgeführt.
Falls sich bis morgen Abend keine Lösung gefunden hat, will ich gerne bei mir das ganze mal näher testen. Ist auch für mich sehr interessant, da ich diesen Baustein mehrfach einsetzen möchte.
Gruß
Jens
Da ist über ISP programmiere ist bei mir die Versorgungsspannung die ganze Zeit ein, aber auch wenn ich vor dem Reset 3 Sekunden warte, geht die LED nicht an, wenn ich sie direkt nach dem Reset einschalte.
Ich habe den MCP2515 auch schon testweise durch einen anderen getauscht, mit dem gleichen Ergebnis. Wenn du sagst, bei dir funktioniert das direkt nach dem Reset, muss ich mir das morgen nochmal genau angucken. Sowohl die Schaltung (naja, viel kann man da ja nicht falsch machen - im Prinzip gehts ja), als auch den Code, also dass ich mal alles überflüssige davor und danach rauslösche und die einzelnen Funktionen direkt in die main() einbette.
Hallo,
so, mein Test hat ergeben, dass Vitis recht hat. Ich habe die Stelle im Datenblatt zwar nicht gefunden, konnte aber feststellen, dass man wirklich einen Moment warten muss, bis man in die Register schreiben kann. Dies ist bei mir nie aufgefallen, da ich bisher keinen anderen Busteilnehmer als die MCP2515 getestet habe. Das erste Register für das Timing wurde bei keinem der Controller geschrieben. Ich habe den Bus mit einer viel zu großen Baudrate betrieben. In den bisherigen Testaufbauten hat das funktioniert und ist nie aufgefallen.
Wirklich ärgerlich wäre das in den nächsten Tage für mich geworden. Im Moment baue ich eine Platine mit einem AT90CAN128 auf. Die Kommunikation mit dem MCP hätte wohl nicht geklappt. Den Fehler hätte ich wohl Tagelang beim AT90 vermutet.
Gruß
Jens
Ok, auch gut, dann ist es bei mir wenigstens kein Fehler im Code sondern eine Eigenheit des MCP2515. Sollte man halt nur wissen... Also vielen Dank nochmal!
Freut mich, anderen geholfen zu habenZitat von McJenso
Grüße
Randy
PS: Und noch was zu meinen 10 Nanosekunden...es sind natürlich 10 Mikrosekunden... Gestern ist mir aufgefallen, dass zwischen Milli und Nano doch noch Mikro kommt *ääähm
Senf: Genau das Problem hat mich auch schon etliche Stunden gekostet mit dem MCP2515
Hat jmd nun mal die Stelle im Datenblatt gefunden, die angibt wielange man nach dem Reset nun wirklich warten muss?
Gruß Philipp
Lesezeichen