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.
El STM32 es de 3.3V y el LED es de 5V. Para poder controlarlo pongo un transistor en medio así:
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: pero el transistor invierte la señal haciéndola inútil:
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:
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_InitTypeDef
configuraría OCPolarity
en TIM_OCPOLARITY_HIGH
o 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 110
o100
secuencia 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).
FWIW Un cambiador de nivel no inversor también puede ser un amplificador de base común (CB).
simular este circuito : esquema creado con CircuitLab
Entonces puedes cambiar el código o 2 cortes y 2 puentes.
Jorge