COMP2 para activar el modo One-Pulse en STM32L1

Estoy tratando de usar la salida de COMP2 para activar el modo One-Pulse de un temporizador (en mi ejemplo, TIM4, pero es bastante flexible si necesita cambiar a otro temporizador) en la serie STM32L1.

En el manual de referencia, la explicación del modo One-Pulse utiliza TI2FP2 como disparador del temporizador, que está vinculado a la captura de entrada en el canal 2 del temporizador; sin embargo, la salida del comparador solo se puede redirigir a la captura de entrada en el canal 4. (excepto TIM10 pero no tiene un segundo canal para emitir el PWM en...), o para OCREF Clear.

He intentado redirigir la salida COMP2 a:

  • “OCxREF Borrar” de TIM4,
  • la captura de entrada 4 de TIM4,
  • la captura de entrada 4 de TIM3 y el uso de ITR2 como disparador de TIM4 (ITR2 es TIM3 cuando se usa en TIM4)

pero ninguna de esas opciones funcionó.

¿Alguna de estas configuraciones debería haber funcionado y simplemente no las configuré correctamente?

¿Se supone que debo hacerlo de manera diferente?

¿No hay forma de conectar los dos directamente y debería, por ejemplo, iniciar el modo One-Pulse desde la interrupción COMP2?

Respuestas (1)

Mirando el diagrama de bloques de los temporizadores, tampoco pude encontrar un método directo, aparentemente no hay señales que vayan desde CH4 a la unidad de activación.

Si desea evitar interrupciones y tiene un canal DMA libre adecuado, puede usarlo para iniciar otro temporizador. Puede usar TIM2_CH4o TIM3_CH4(estoy usando TIM3 en el ejemplo), pero no hay un canal DMA para TIM4_CH4. Puede ceñirse TIM4o usar cualquier otro temporizador como objetivo.

  • Configure TIM4el modo de un solo pulso, pero no lo inicie todavía. Averigüe qué valor entraría TIM4->CR1y guárdelo en una variable de memoria, por ejemplo, volatile uint8_t tim4_cr1_start = TIM_CR1_OPM|TIM_CR1_CEN;para el caso más simple.
  • Configuración DMA1_Channel3, la dirección de la memoria es &tim4_cr1_startdesde arriba, la dirección del periférico es &TIM4->CR1, la longitud de la transferencia es 1. Use el modo de 8 bits, habilite el modo circular.
  • Configure TIM3_CH4la captura de entrada, seleccione la polaridad, etc. en TIM3_CCERy TIM3_CCMR2.
  • Habilite CC4DE, capture/compare 4 solicitudes DMA en TIM3->DIER.
  • Empezar TIM3_
  • Redirigir la salida de COMP2 a TIM3_CH4(podría usar TIM2_CH4' too, but there is no DMA channel forTIM4_CH4`).

Ahora, un evento de comparación activaría una captura en TIM3_CH4, lo que le indicaría a DMA que escriba un valor adecuado en TIM4->CR1. Como el DMA está configurado en modo circular, copiaría el mismo valor en TIM4->CR1cada evento de captura posterior.

Gracias por la explicación, realmente no he usado el DMA antes, ¡así que definitivamente es una buena oportunidad para aprender a usarlo! ¿Sabe cómo se compararía esta solución con el uso de interrupciones en términos de retraso entre el cambio de salida de COMP2 y el inicio del modo One-Pulse en el pin de salida?
@BenoîtVernier La entrada de interrupción en un Cortex-M3 toma al menos 12 ciclos, luego una implementación mínima del controlador tomaría al menos otros 5 ciclos (1 para MOVS, 2 para LDRy 2 para STR). Es un mínimo teórico, yo diría que 20-25 ciclos son realistas. Realmente no sé acerca de las latencias de DMA, supongo que 3 o 4 ciclos, y me sorprendería mucho si tomara más de 5. Luego, el temporizador necesita quizás otros 2 ciclos para comenzar en ambos casos.
@BenoîtVernier En realidad, una entrada de interrupción puede ser más rápida si otro controlador de interrupciones está terminando en el momento exacto ( ver encadenamiento de cola ). El punto es que la latencia de interrupción puede ser incierta de +/- 6 ciclos, el retraso de DMA debe ser constante si le da a este canal el nivel de prioridad más alto.