STM32L0 - Retardo en microsegundos

Estoy usando una placa B-L072Z-LRWAN1 (que tiene una MCU STM32L072) y quiero obtener datos de un sensor DHT11. Para lograr esto, necesito un retraso de microsegundos que no puedo obtener.

Las bibliotecas proporcionadas por ST tienen una función de retraso de milisegundos pero no una función de microsegundos.

Necesito algo de ayuda. ¡Gracias de antemano!

¡UPS! El título anterior se guardó de una publicación anterior. Mis disculpas.
Este sitio ofrece un ejemplo del uso de un STM32 con el DHT11. Incluye código, pero no puedo mirar dentro para ver cómo funciona. El código se proporciona en un archivo comprimido que mi teléfono no puede descomprimir.
Tienes que ser más específico para tener una pregunta que se pueda responder. ¿Cuántos microsegundos? ¿Con qué mínimo después del error? y que maximo?
Necesito retrasos de 40us y 80us para poder leer datos del sensor.

Respuestas (1)

No necesita un retraso de microsegundos, sino un contador de tiempo con una precisión de microsegundos.

Mirando la hoja de datos vinculada por @JRE, este es un protocolo asíncrono. El host transmite un pulso largo y bajo (al menos 18 milisegundos ), y ese es el único momento en que la MCU debe retrasar algo. Pero ya tiene una función de retraso de milisegundos (y de todos modos, sería mejor hacerlo en la interrupción de milisegundos que probablemente ya se esté ejecutando).

Luego, el dispositivo responde con un ciclo de inicio y 40 ciclos de datos, donde la longitud de la fase alta codifica el valor del bit. Tienes que medir el tiempo transcurrido entre el flanco de subida y el de bajada.

Si la interrupción de milisegundos se está ejecutando, entonces ya hay algo que cuenta los ciclos. Por lo general, es el SysTicktemporizador. Espere el flanco ascendente en el pin, obtenga una marca de tiempo de SysTick->VAL, espere el flanco descendente, lea el contador nuevamente y reste la marca de tiempo anterior. Tenga cuidado con el desbordamiento, agregue SysTick->LOAD+1al resultado si es negativo. Divida el resultado por la frecuencia del reloj (en MHz) para obtener un valor en microsegundos.

Sin embargo, es posible que prefiera que la MCU haga algo útil o dejarla en reposo para conservar energía mientras ingresan los datos.

Un temporizador y DMA pueden hacer la mayor parte del trabajo por su cuenta

Lea la descripción funcional de TIM2/TIM3/ sección Modo de captura de entrada en el Manual de referencia.

Como la fase baja de la señal siempre debe tener una duración de 50 us, también puede medir el tiempo entre dos flancos descendentes consecutivos. El ejemplo en el manual es para flancos ascendentes, pero por supuesto puede modificarse para capturar flancos descendentes cambiando los bits CC1Py CC1NPen el Paso 3.

  • Elija un canal de temporizador y el canal DMA correspondiente. Utilice la tabla titulada Resumen de las solicitudes de DMA para cada canal .
  • Configure el canal DMA para transferir 41 (para 1 pulso de inicio + 40 pulsos de datos) medias palabras (16 bits) desde el CCRregistro del canal del temporizador a una matriz de tamaño adecuado en la memoria.
  • Puede habilitar la interrupción completa de la transferencia DMA para ejecutar un controlador cuando, bueno, la transferencia de datos esté completa.
  • Configure el temporizador con un preescalador que es la frecuencia de reloj de su sistema en MHz (escriba uno menos en PSC, y no olvide configurar UG) EGRpara obtener convenientemente una marca de tiempo en milisegundos.
  • Continúe con el procedimiento descrito en la sección Modo de captura de entrada . Incluso hay un ejemplo de código simple en el apéndice. Adáptelo para capturar los bordes descendentes y, en el último paso, habilite DMA en lugar de la interrupción del canal en DIER.
  • Como red de seguridad, puede habilitar la interrupción de actualización del temporizador. Se disparará después de 65535 microsegundos, para que el programa sepa que la transferencia se agotó. Se puede establecer un valor de tiempo de espera más bajo en ARR.