Número de pines de PWM en STM32F072

0

Hoja de datos del microcontrolador

Estoy en el proceso de seleccionar un microcontrolador para un proyecto en el que necesito muchos pines PWM (alrededor de 30) para los LED. Prefiero el hardware PWM admitido para que mi CPU sea libre para otras tareas, pero no es una necesidad si se puede hacer cómodamente desde el punto de vista del software. La frecuencia PWM de 100 Hz debería funcionar para los LED y no necesitaré más de 8 niveles de brillo.

He reducido el STM32F072V8T6 (LQFP de 100 pines) que tiene 87 GPIO y otras características (como detección táctil capacitiva y rtc con vbat pin) que necesito para mi proyecto.

Pasando por la hoja de datos, no puedo averiguar cuántos pines de PWM puedo sacar de ella (vengo de un fondo de arduino donde no se menciona directamente el n. de pines de PWM). Encontré una pequeña nota que decía: "Un temporizador de control avanzado de 16 bits para la salida PWM de seis canales"

¿Eso significa que solo puedo tener 6 pines PWM?

Si este es realmente el caso, ¿cuáles son mis otras alternativas baratas para obtener tantas salidas PWM? Vi algunos expansores de puertos de salida PWM que se comunican a través de i2c, pero el costo parece demasiado alto.

    
pregunta Whiskeyjack

5 respuestas

2

No creo que ST tenga ningún microcontrolador con salidas de 30 pwm, pero con una frecuencia tan baja que realmente no lo necesita. Hay una interrupción de 1 ms con systick que le proporcionará 10 niveles de brillo a 100Hz.

Cada vez que se activa la interrupción, establezca o reinicie un pin io, deberá realizar un seguimiento de 30 variables, una para cada pin. Es realmente fácil y solo estás limitado por el número de pines de chip.

    
respondido por el Paulo Soares
2

Como es parte de 100 pines, creo que podemos asumir que las posibles configuraciones de pines no se superponen, por lo que simplemente puede agregar los factores:

TIM1 tiene 4 registros de captura y comparación y salidas configurables. Eso significa que puede tener 4 relaciones de servicio independientes pero la misma frecuencia. Las salidas trifásicas y complementarias dependen de la relación de trabajo de un solo CCR, por lo que no son relevantes para su preocupación.

Mira la página 21.

TIM1: 4 CCRs

TIM2: 4

TIM3: 4

TIM6 & 7: 0

TIM14: 1

TIM15: 2

TIM16 & 17: 1

+

respondido por el Ayhan
1

Hay micros con más de 30 canales HW PWM (por ejemplo, el Renesas RH850 / F1L en paquete de 100 pines: hasta 48 PWM a través de su unidad "PWM-Diag"), pero desafortunadamente no con el periférico Touch.

Sin embargo, hacer software PWM con 8 niveles de brillo a 100Hz es ridículo para cualquier microcontrolador de 32 bits.
Si no desea utilizar un ISR que consume tiempo de la CPU, puede usar un mecanismo DMA, activado por un temporizador, leyendo cíclicamente datos de un búfer de RAM y escribiéndolos en uno (o más) puerto (s) GPIO.
Por supuesto, el cálculo y llenado del búfer también requiere tiempo de CPU, pero solo si cambia el brillo.

    
respondido por el mic
1

He realizado un proyecto con un STM32F100 a 24MHz, que tiene 24 PWM a 2kHz, con un ciclo de trabajo seleccionable en el paso del 1%.

Para hacer este trabajo, tuve que usar todos los temporizadores disponibles con salida PWM, y algún pin en el modo de banda de bits activado por otro temporizador.

Por favor, preste atención a que es imposible alcanzar la alta velocidad en el modo de banda de bits. En mis pruebas, la frecuencia máxima de pwm con 24pwm en modo de banda de bits, impulsada por un temporizador en interrupción de tiempo constante, es muy baja, aproximadamente 600Hz.

Esta fue mi configuración:

/*
* PWM 1 : Bit banding
* PWM 2 : Bit banding
* PWM 3 : Bit banding
* PWM 4 : Bit banding
* PWM 5 : TIM1_CH1N (TIM1->CCR1, TIM1->CCER_CC1NP)
* PWM 6 : TIM1_CH2N (TIM1->CCR2, TIM1->CCER_CC2NP)
* PWM 7 : TIM1_CH3N (TIM1->CCR3, TIM1->CCER_CC3NP)
* PWM 8 : Bit banding
* PWM 9 : Bit banding
* PWM 10: Bit banding
* PWM 11: Bit banding
* PWM 12: TIM4_CH1 ()
* PWM 13: TIM4_CH2 ()
* PWM 14: TIM4_CH3 ()
* PWM 15: TIM4_CH4 ()
* PWM 16: TIM3_CH1 ()
* PWM 17: TIM3_CH2 ()
* PWM 18: TIM3_CH3 ()
* PWM 19: TIM3_CH4 () 
* PWM 20: Bit banding
* PWM 21: Bit banding
* PWM 22: Bit banding
* PWM 23: Bit banding
* PWM 24: Bit banding
*/

Establezca el ciclo de trabajo de pwm controlado por el temporizador.

void setPwmDrivenByTimer(uint8_t pwm, uint8_t duty) {
    switch (pwm) {
        case 4:  TIM1->CCR1 = duty; break;
        case 5:  TIM1->CCR2 = duty; break;
        case 6:  TIM1->CCR3 = duty; break;
        case 11: TIM4->CCR1 = duty; break;
        case 12: TIM4->CCR2 = duty; break;
        case 13: TIM4->CCR3 = duty; break;
        case 14: TIM4->CCR4 = duty; break;
        case 15: TIM3->CCR1 = duty; break;
        case 16: TIM3->CCR2 = duty; break;
        case 17: TIM3->CCR3 = duty; break;
        case 18: TIM3->CCR4 = duty; break;
        default: break;
    }
}

Para establecer el estado del pin del pwm conducido en el modo de banda de bits, he usado este código:

/* bitband type */
typedef volatile uint32_t * const bitband_t;
/* base address for bit banding */
#define BITBAND_SRAM_REF                    (0x20000000)
/* base address for bit banding */
#define BITBAND_SRAM_BASE                   (0x22000000)
/* base address for bit banding */
#define BITBAND_PERIPH_REF                  (0x40000000)
/* base address for bit banding */
#define BITBAND_PERIPH_BASE                 (0x42000000)
/* sram bit band */
#define BITBAND_SRAM(address, bit)     ((void*)(BITBAND_SRAM_BASE +   \
        (((uint32_t)address) - BITBAND_SRAM_REF) * 32 + (bit) * 4))
/* periph bit band */
#define BITBAND_PERIPH(address, bit)   ((void *)(BITBAND_PERIPH_BASE + \
        (((uint32_t)address) - BITBAND_PERIPH_REF) * 32 + (bit) * 4))

#pragma diag_suppress 1296
bitband_t pwm[] =  {
    {BITBAND_PERIPH(&GPIOE->ODR,  2)},
    {BITBAND_PERIPH(&GPIOE->ODR,  3)},      
    {BITBAND_PERIPH(&GPIOE->ODR,  4)},
    {BITBAND_PERIPH(&GPIOB->ODR, 12)},
    {BITBAND_PERIPH(&GPIOB->ODR, 13)},
    {BITBAND_PERIPH(&GPIOB->ODR, 14)},
    {BITBAND_PERIPH(&GPIOB->ODR, 15)},
    {BITBAND_PERIPH(&GPIOD->ODR,  8)},
    {BITBAND_PERIPH(&GPIOD->ODR,  9)},
    {BITBAND_PERIPH(&GPIOD->ODR, 10)},
    {BITBAND_PERIPH(&GPIOD->ODR, 11)},
    {BITBAND_PERIPH(&GPIOD->ODR, 12)},
    {BITBAND_PERIPH(&GPIOD->ODR, 13)},
    {BITBAND_PERIPH(&GPIOD->ODR, 14)},
    {BITBAND_PERIPH(&GPIOD->ODR, 15)},
    {BITBAND_PERIPH(&GPIOC->ODR,  6)},
    {BITBAND_PERIPH(&GPIOC->ODR,  7)},
    {BITBAND_PERIPH(&GPIOC->ODR,  8)},
    {BITBAND_PERIPH(&GPIOC->ODR,  9)},      
    {BITBAND_PERIPH(&GPIOA->ODR,  8)},      
    {BITBAND_PERIPH(&GPIOA->ODR, 11)},      
    {BITBAND_PERIPH(&GPIOA->ODR, 12)},      
    {BITBAND_PERIPH(&GPIOC->ODR, 10)},      
    {BITBAND_PERIPH(&GPIOC->ODR, 11)}
};      
#pragma diag_warning 1296

void setPinStatusOfPwmDrivenInBitbandMode(uint8_t pin, GPIO_PinState newStatus) {   
    *(pwm[pin]) = newStatus;
}

Y ahora la parte difícil pero más importante. He dicho que tengo otro temporizador. Yo uso este temporizador para configurar el estado del pin de la banda de bits pwm. No he configurado el temporizador para hacer una entrada siempre al mismo tiempo, pero lo configuro para hacer una interrupción en el próximo cambio de estado de pwm pin en la banda de bits.

Para hacer esto, he usado alguna función de clasificación que hace una serie de tiempos y estados del pin.

De esta manera, la interrupción se realiza solo cuando es necesario y el núcleo tiene tiempo para hacer otra cosa.

Para hacer este trabajo, he hecho una función que:

  • Cree una matriz con el estado y la hora del cambio de pin,
  • Ordene esta matriz en orden de media luna
  • Eliminar duplicados
  • Establecer el estado del pin inicial
  • Configure el temporizador para disparar una matriz en el primer cambio de estado

Todo el código es complejo y largo, es por eso que en esta respuesta solo tengo el concepto funcional.

Espero que esto ayude.

    
respondido por el Katte
-1

La serie STM32 no tiene pines PWM fijos, se pueden configurar como funciones GPIO o PWM, u otros pines de función alternativos. La función PWM se proporciona con temporizadores avanzados. Puede utilizar su herramienta de configuración para averiguar cuántos pines de PWM se pueden implementar como máximo.

    
respondido por el diverger

Lea otras preguntas en las etiquetas