Hallo zusammen, ich halte mich kurz und knapp. Student/Hochschule/Elektrotechnik 3 Semester Ich habe im schulischen Rahmen eine Projektaufgabe erhalten: Mit dem Nucleo64 - STM32F303Re eine Verbindung mit der LED-Matrix Max7219 herzustellen und ein kleines Spiel daraus zu machen und das alles in C und ohne Verwendung von irgendwelchen Libraries Die Übertragung funktioniert nicht wie es solle. (Der Prof. der das ganze betreut saß vor meinem Code und konnte mir auch nicht erklären warum es nicht klappt - sowohl dieser Bitbanging code, als auch mein gescheitertes SPI versuch) Im Anhang der Code ist nur eine Testfunktion die SCK, Din, CS manuell hoch und runter setzt und die Daten in "j" an die Matrix schicken sollte. Ich würde mich sehr über eine Erklärung meiner Fehler freuen und natürlich auch Verbesserungsvorschläge oder Lösungen. LG
:
Verschoben durch Admin
Mit Verlaub: was soll denn so ein Käse? GPIOC->MODER |= (1<<10)|(1<<12)|(1<<16); // PC8 = CS; PC6 = DIN; PC5 = CLK Erstens gehören zu jedem Pin 2 Bits, die man tunlichst auch beide auf den gewünschten Wert setzen sollte, am besten in einem Rutsch. Zweitens gibt's für die einzelnen Bits schöne "sprechende" Defines. Da mit wüsten Bitnummern herum zu wurschteln, ergibt genau das: Chaos, was keiner versteht. Drittes sind die beiden Bits (pro Pin) nach Reset sowieso auf '1'. Da eines noch mal auf '1' zu setzen, tut halt gar nichts - recht sinnfrei. Dass da außen nichts ankommt, ist klar. So etwas wie GPIOC->ODR |= (1<<8); //PC8High ist auch nicht der Weisheit letzter Schluss. Wozu gibt's die BSRR-Register?
1 | while(!interruptWarDa) |
2 | __WFI(); |
Das ist auch potentiell gefährlich und sollte man sich gar nicht erst angewöhnen. Je nach Makro tut es nicht was es soll, auch um Einzeiler immer {} setzen.
Ohne weitere ext. Beschaltung wird das nix. Bei 3,3V reicht der High-Pegel des µC nicht aus. Siehe Screenshot aus dem Datenblatt des MAX7219. Ein Ausweg ist, 5V-tolerante Pins am µC zu nutzen, diese als OpenDrain zu konfigurieren und die Eingänge des Max7219 mit PullUp gegen +5V zu beschalten.
:
Bearbeitet durch User
Das heißt, ein Pegelwandler um die 3,3 V Pins auf 5 V zu bringen würde auch funktionieren?
Daniel L. schrieb: > Das heißt, ein Pegelwandler um die 3,3 V Pins auf 5 V zu bringen würde > auch funktionieren? Sicher! Ist aber gar nicht nötig, wenn du es so machst, wie ich das oben beschrieben hab.
Tut mir außerdem Leid, sollte mein Code unerfahren wirken, denn das bin ich auch. Mein Wissen mit Programmieren insgesamt, besteht aus einem C Kurs in dem mir die wichtigsten Commands erklärt wurden und ein halbes Jahr später wurden mir ein paar Datasheets und Manuels vor die Füße gelegt und gesagt, dass ich das jetzt hinbekommen soll.
Ich habe ein halbes Dutzend Displays mit MAX7219, angesteuert mit STM32 oder ESP8266 und 3V3 Pegeln, läuft. Ist natürlich nicht allgemeingültig, vor allem da es auch viele Fakes von diesem Chip gibt (die dann vielleicht besser mit 3,3 V klarkommen?). Da ist systematisches Testen sinnvoll: LED oder Multimeter an Ausgang, blinken lassen und Delay Zeit messen. Logic Analyzer vereinfacht die Fehlersuche auch.
J. S. schrieb: > Ich habe ein halbes Dutzend Displays mit MAX7219, angesteuert mit STM32 > oder ESP8266 und 3V3 Pegeln, läuft. Das "kann" funktionieren, aber, wenn nicht, ist die Fehlersuche umso nerviger. Besonders bei den DotMatrix-Versionen hatte ich fast immer Probleme bei direkter Ansteuerung. Die 3 PullUp-Widerstände tun mir nicht weh, und ich muß mir darüber keine Gedanken mehr machen.
Nun auch mit PullUp Widerständen passiert an der LED-Matrix nichts neues. Entweder sind alle 64-LEDs an oder alle sind aus.
Daniel L. schrieb: > Nun auch mit PullUp Widerständen passiert an der LED-Matrix nichts > neues. Entweder sind alle 64-LEDs an oder alle sind aus. Hast du die Outputs auch als OpenDrain konfiguriert? Ansonsten wird es wohl an deinem Programm liegen. Ich hab mal meinen funktionierenden Code angehängt, der allerdings auf der ST-HAL basiert.
:
Bearbeitet durch User
Natürlich habe ich die Ports auch auf open-drain gesetzt. Dabei habe ich den Code um:
1 | GPIOC->OTYPER |= GPIO_OTYPER_OT_8; |
2 | GPIOC->OTYPER |= GPIO_OTYPER_OT_6; |
3 | GPIOC->OTYPER |= GPIO_OTYPER_OT_5; |
4 | |
5 | GPIOC->OSPEEDR |= (11<<10)|(11<<12)|(11<<16); |
erweitert. OSPEEDR wurde auf einer anderen Seite empfohlen, bei mir macht das aber kein Unterschied, weil sowohl mit als auch ohne ändert das nichts an der LED, bzw. die LEDs sind alle aus und gehen auch nicht mehr alle an wie vorhin.
> Tut mir außerdem Leid, sollte mein Code unerfahren wirken, denn das > bin ich auch. Keine Selbstverzwergung! Lass dich hier nicht unoetig runtermachen, es gibt hier auch viele die vergessen haben wie sie selber angefangen haben. > Mein Wissen mit Programmieren insgesamt, besteht aus einem C Kurs in > dem mir die wichtigsten Commands erklärt wurden und ein halbes Jahr > später wurden mir ein paar Datasheets und Manuels vor die Füße gelegt > und gesagt, dass ich das jetzt hinbekommen soll. Dagegen ist auch nix zu sagen. So haben wir im Prinzip alle angefangen. Problem ist halt das du es gewohnt bist im Internet nachzuschlagen und da findet sich heute halt nur noch Leute die mit Libaries programmieren. Arbeite dich von unten nach oben durch! Also pruefe erstmal ob sowas sowas funktioniert: void ClockLow(){ GPIOC->ODR &= ~(1<<5); //PC5 Low } Pruefe ob dein Compiler dich hier nicht warnt und schalte mal alle Warnungen ein. Es wundert mich z.b das du nicht angeben musst das diese Funktion sich nicht beschwert das da kein void drin steht. Wenn das funktioniert dann machst du das mit allen deinen Unterfunktionen, du musst dir also sicher sein das du funktionieren. Dann arbeitest du dich nach oben. Schreibst dir also z.b sowas hier: void test1(void) { ClockLow(); ClockHigh(); } Und schaust mal mit dem Oszi was da raus kommst. Dann fuegst du ein Wait/delay ein und testet ob das Timing deinen Erwartungen entspricht. Dann schreibst du dir eine Funktion welche das SPI komplett fuer einen uebergebenen 8Bit Wert haendelt. Die wird wieder einzeln getestet. Aber hier kann es sinn machen auch mal ueber den Einsatz des Debuggers nachzudenken und z.B Variablen und Abbruchbedingungen auszugeben. z.B falls dein Code mal nur 7 oder 9 Datenbits ausgibt. Du musst also pruefen ob das was du glaubst das eine Programmzeile bewirkt mit der Realitaet uebereinstimmt! So arbeitest du dich langsam von unten nach oben. Dann ist das schon zu schaffen. Eigentlich ist das was du da machst naemlich eine Aufgabe die mindestens die Haelfte der Leute hier die erstmal nur Arduinokram aus dem Internet klauen auch mal machen sollten. .-) Vanye
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.