Cómo invertir la señal PWM en STM32

Estoy tratando de controlar un LED WS2812 con STM32F103. El LED es un LED RGB digital también conocido como Neopixel. Se controlan enviando 24 bits de datos de color por LED al pin de datos del primer LED.

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

El STM32 es de 3.3V y el LED es de 5V. Para poder controlarlo pongo un transistor en medio así:ingrese la descripción de la imagen aquí

Esto resuelve el problema del cambio de nivel, pero provoca otro: ahora la señal de datos para el LED está invertida. Cuando el pin STM32 es bajo, los datos del LED son altos y viceversa. USO Timer PWM y DMA para controlar el LED. Paso el búfer con bits de valor de color a DMA así:

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

Esto produce una buena señal PWM en el pin MC. Así es como se ven un montón de ceros a 800 KHz: ingrese la descripción de la imagen aquípero el transistor invierte la señal haciéndola inútil:ingrese la descripción de la imagen aquí

Necesito pasar la señal invertida del pin MC de alguna manera. Para que el transistor lo DESINVIERTA de nuevo. ¿Hay alguna forma de invertir completamente la señal PWM/pin? ¿Entonces ese pin MC siempre está ALTO de manera predeterminada, para que la línea de datos del LED permanezca BAJA?

Algunas notas:

  • Uso PB5 y PB6 para controlar dos líneas separadas de WS2812
  • Los PCB ya están impresos y todos los componentes son SMD, por lo que las soluciones alternativas de hardware son apenas posibles.
  • Ya intenté quitar el transistor por completo y usar el pin MC para llevar la línea de 5 V a tierra internamente en modo de drenaje abierto, pero PB5 no es tolerante a 5 V. No hay suerte aquí.

Respuestas (3)

Según el manual de referencia:

La polaridad OCx es programable por software usando el bit CCxP en el registro TIMx_CCER. Se puede programar como activo alto o activo bajo.

Por lo tanto, debe buscar las asignaciones de bits de ese registro y establecer/borrar el bit según corresponda, o mirar la API para la biblioteca de abstracción que está utilizando y pedirle que haga esto, por ejemplo, establezca el valor de estructura apropiado documentado para controlar la inversión , o si no existe, modifique la fuente de la biblioteca o, en caso extremo, incluso cambie el bit de hardware detrás de la biblioteca.

Por ejemplo, dado que parece que está utilizando los controladores HAL STM32F1, en su instancia de un TIM_OC_InitTypeDefconfiguraría OCPolarityen TIM_OCPOLARITY_HIGHo TIM_OCPOLARITY_LOW. Me abstendré de adivinar cuál debe usar (es fácil probar ambos), pero como el primero tiene un valor de cero, si ha puesto a cero la estructura para comenzar y aún no ha configurado nada, eso es probablemente lo que tiene, entonces el segundo es probablemente lo que daría un resultado diferente al que has estado obteniendo.

Por lo general, para algo como esto, el preprocesamiento de software de los valores podría funcionar, y no estoy 100% seguro de que no pueda hacerlo aquí, pero sería complicado ya que en su esquema representado al estilo de Manchester, el período de encuadre de un de un hi- low es consistente, pero el de low-hi abarca dos bits diferentes y varía como resultado. Además, ya pagó por el inversor de hardware en chip. Si no tuviera el inversor de hardware, algo que probablemente funcionaría sería aproximar la señal en tercios y el reloj 110o100secuencia el GPIO a través de DMA a 3 veces la tasa de bits (o usando un periférico serial síncrono). Esa también es una solución útil si alguna vez necesita hacer este tipo de cosas en pines que no tienen temporizadores. Si no tiene mucho más que hacer para el procesador, también podría potencialmente hacer un canal en código usando retrasos semicalibrados (el tiempo no tiene que ser tan preciso).

¡Oh muchas gracias! Dios mío, me tomó semanas resolver este problema. ¡GRACIAS!

FWIW Un cambiador de nivel no inversor también puede ser un amplificador de base común (CB).

esquemático

simular este circuito : esquema creado con CircuitLab

Entonces puedes cambiar el código o 2 cortes y 2 puentes.

Será mejor que uses el desagüe abierto para controlar a Din. Ver el lado izquierdo de la imagen:ingrese la descripción de la imagen aquí