Forum: Mikrocontroller und Digitale Elektronik Bit Banging STM32 - F303RE ohne Library


von Daniel L. (daniel_l947)


Angehängte Dateien:

Lesenswert?

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
von Andreas B. (abm)


Lesenswert?

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?

von J. S. (jojos)


Lesenswert?

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.

von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

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
von Daniel L. (daniel_l947)


Lesenswert?

Das heißt, ein Pegelwandler um die 3,3 V Pins auf 5 V zu bringen würde 
auch funktionieren?

von Harry L. (mysth)


Lesenswert?

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.

von Daniel L. (daniel_l947)


Lesenswert?

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.

von J. S. (jojos)


Lesenswert?

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.

von Harry L. (mysth)


Lesenswert?

Hier hab ich das erklärt: (ab ca. 1:15)
https://www.youtube.com/watch?v=mSMyjvVz4Ec&t=72s

von Harry L. (mysth)


Lesenswert?

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.

von Daniel L. (daniel_l947)


Lesenswert?

Nun auch mit PullUp Widerständen passiert an der LED-Matrix nichts 
neues. Entweder sind alle 64-LEDs an oder alle sind aus.

von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

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
von Daniel L. (daniel_l947)


Lesenswert?

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.

von Vanye R. (vanye_rijan)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.