So invertieren Sie das PWM-Signal auf STM32

Ich versuche, eine WS2812-LED mit STM32F103 zu steuern. Die LED ist eine digitale RGB-LED, auch bekannt als Neopixel. Sie werden gesteuert, indem 24 Bit Farbdaten pro LED an den Datenpin der ersten LED gesendet werden.

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Der STM32 hat 3,3 V und die LED 5 V. Um es steuern zu können, habe ich einen Transistor wie folgt dazwischen geschaltet:Geben Sie hier die Bildbeschreibung ein

Dies löst das Level-Shifting-Problem, verursacht aber ein weiteres: Jetzt wird das Datensignal für die LED invertiert. Wenn der STM32-Pin niedrig ist, sind die LED-Daten hoch und umgekehrt. Ich verwende Timer PWM und DMA, um die LED zu steuern. Ich übergebe den Puffer mit Farbwertbits so an DMA:

HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t *)&BUF_DMA, ARRAY_LEN);

Dies erzeugt ein schönes PWM-Signal am MC-Pin. So sieht ein Haufen Nullen bei 800 kHz aus: Geben Sie hier die Bildbeschreibung einAber der Transistor invertiert das Signal und macht es unbrauchbar:Geben Sie hier die Bildbeschreibung ein

Ich muss das invertierte Signal vom MC-Pin irgendwie weitergeben. Damit der Transistor es zurück UN-INVERT. Gibt es eine Möglichkeit, das PWM/Pin-Signal vollständig zu invertieren? Also ist dieser MC-Pin standardmäßig immer HIGH, sodass die LED-Datenleitung LOW bleibt?

Ein paar Anmerkungen:

  • Ich verwende PB5 und PB6, um zwei separate Leitungen von WS2812 zu steuern
  • Die Leiterplatten sind bereits gedruckt und alle Komponenten sind SMD, sodass Hardware-Workarounds kaum möglich sind.
  • Ich habe bereits versucht, den Transistor vollständig zu entfernen und den MC-Pin zu verwenden, um die 5-V-Leitung im Open-Drain-Modus intern auf Masse zu ziehen, aber PB5 ist nicht 5-V-tolerant. Kein Glück hier.

Antworten (3)

Laut Referenzhandbuch:

Die OCx-Polarität ist softwareprogrammierbar unter Verwendung des CCxP-Bits im TIMx_CCER-Register. Er kann als aktiv hoch oder aktiv niedrig programmiert werden.

Sie müssen also die Bitzuweisungen dieses Registers nachschlagen und das Bit entsprechend setzen/löschen oder die von Ihnen verwendete API für die Abstraktionsbibliothek aufrufen und sie dazu auffordern, z. B. den entsprechenden dokumentierten Strukturwert zur Steuerung der Inversion festlegen , oder wenn eine solche nicht existiert, ändern Sie die Bibliotheksquelle oder ändern Sie im Extremfall sogar das Hardware-Bit hinter dem Rücken der Bibliothek.

Da es beispielsweise so aussieht, als würden Sie die STM32F1 HAL-Treiber verwenden, TIM_OC_InitTypeDefwürden Sie in Ihrer Instanz von an OCPolarityentweder TIM_OCPOLARITY_HIGHoder festlegen TIM_OCPOLARITY_LOW. Ich werde davon absehen, zu raten, was Sie verwenden sollten (einfach beide ausprobieren), aber da der erste einen Wert von Null hat, wenn Sie die zu startende Struktur auf Null gesetzt und noch nichts festgelegt haben, ist dies wahrscheinlich das, was Sie haben, also der zweite was wahrscheinlich ein anderes Ergebnis geben würde als das, was Sie bekommen haben.

Normalerweise könnte für so etwas eine Software-Vorverarbeitung der Werte funktionieren, und ich bin mir nicht 100% sicher, dass dies hier nicht der Fall ist, aber es wäre schwierig, da in Ihrem abgebildeten Manchester-Schema die Framing-Periode eines Hi- Low ist konsistent, aber das von Low-Hi erstreckt sich über zwei verschiedene Bits und variiert daher. Außerdem haben Sie bereits für den On-Chip-Hardware-Inverter bezahlt. 110Wenn Sie den Hardware-Inverter nicht hätten, würde es wahrscheinlich funktionieren, das Signal in Dritteln und Takt oder anzunähern100sequenziert den GPIO über DMA mit der dreifachen Bitrate (oder mit einem synchronen seriellen Peripheriegerät). Das ist auch eine praktische Lösung, wenn Sie jemals so etwas an Pins tun müssen, die keine Timer haben. Wenn Sie nicht viel anderes für den Prozessor zu tun haben, können Sie möglicherweise auch einen Kanal im Code mit halbkalibrierten Verzögerungen ausführen (das Timing muss nicht so genau sein).

Oh vielen Dank! OMG, ich habe Wochen gebraucht, um dieses Problem zu lösen. DANKE SCHÖN!

FWIW Ein nicht-invertierender Pegelumsetzer kann auch ein Verstärker mit gemeinsamer Basis (CB) sein.

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

So können Sie den Code oder 2 Schnitte und 2 Jumper ändern.

Verwenden Sie besser den offenen Abfluss, um Din zu kontrollieren. Siehe linke Seite des Bildes:Geben Sie hier die Bildbeschreibung ein