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.
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:
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: Aber der Transistor invertiert das Signal und macht es unbrauchbar:
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:
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_InitTypeDef
würden Sie in Ihrer Instanz von an OCPolarity
entweder TIM_OCPOLARITY_HIGH
oder 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. 110
Wenn Sie den Hardware-Inverter nicht hätten, würde es wahrscheinlich funktionieren, das Signal in Dritteln und Takt oder anzunähern100
sequenziert 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).
FWIW Ein nicht-invertierender Pegelumsetzer kann auch ein Verstärker mit gemeinsamer Basis (CB) sein.
Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan
So können Sie den Code oder 2 Schnitte und 2 Jumper ändern.
George