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 bajo prolongado (al menos 18 milisegundos ), y ese es el único momento en que la MCU debe retrasar algo. Pero ya tiene una función de demora de milisegundos (y de todos modos, sería mejor hacerlo en milisegundos interrupt que probablemente ya se estén 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. Debe medir el tiempo transcurrido entre el flanco ascendente y el flanco descendente.
Si la interrupción de milisegundos se está ejecutando, entonces ya hay algo que cuenta los ciclos. Por lo general, es el temporizador SysTick
. Espere el borde ascendente en el pin, obtenga una marca de tiempo de SysTick->VAL
, espere el borde descendente, lea el contador nuevamente y reste la marca de tiempo anterior. Tenga cuidado con el desbordamiento, agregue SysTick->LOAD+1
al resultado si es negativo. Divida el resultado por la frecuencia de reloj (en MHz) para obtener un valor de microsegundos.
Sin embargo, es posible que prefieras que la MCU haga algo útil, o dejarla en reposo para ahorrar energía mientras ingresan los datos.
Un temporizador y un DMA pueden hacer la mayor parte del trabajo por su cuenta
Lea la sección Descripción funcional de TIM2 / TIM3 / Modo de captura de entrada en el Manual de referencia.
Como la fase baja de la señal siempre debe durar 50 dólares, también puede medir el tiempo entre dos flancos descendentes consecutivos. El ejemplo en el manual es para bordes ascendentes, pero, por supuesto, se puede modificar para capturar bordes descendentes cambiando los bits CC1P
y CC1NP
en 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) del registro
CCR
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 se haya completado.
- Configure el temporizador con un prescaler que sea la frecuencia de reloj de su sistema en MHz (escriba uno menos en
PSC
, y no olvide configurar UG
en EGR
) para 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 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 activará después de 65535 microsegundos, lo que permitirá al programa saber que la transferencia se ha agotado. Se puede establecer un valor de tiempo de espera menor en
ARR
.