Quiero enviar datos a una tira de LED. Esto se debe hacer aproximadamente cada 400 (u 800 ns), dependiendo de los datos (un 0 o un 1 a ser enviado).
unsigned long counter = 0;
Hice una prueba con mi STM32F103C8T6 con este código en el bucle:
while (1)
{
GPIOC->BSRR = GPIO_PIN_13; // Set GPIO
counter++;
}
Corrí en modo de depuración, para poder verificar el valor del contador. Después de aproximadamente 10 segundos, suspendí el programa y verifiqué el valor del contador. Tenía un valor de 27822623. Esto significa que cada contador toma aproximadamente 10/27822623 = 3.5942E-07 segundos / incremento de contador, que es de 359 ns / incremento de contador.
Sin embargo, todo lo que hago aquí es configurar el pin GPIO, que es un puntero de desplazamiento, una asignación y un incremento. Y esto lleva el tiempo 'gigantesco' de 359 ns. En mi aplicación real, necesito ir al siguiente byte, verificar si es un 0 o 1, dependiendo de eso para enviar el comando anterior para configurar, o un comando de reinicio del pin (que requiere un cambio de bit adicional). ¿Cómo puedo realizar esto dentro (o en realidad alrededor de 400 ns?)
El STM32 está configurado a 72 MHz (velocidad máxima). No tengo ninguna interrupción adicional en ejecución.
¿Cómo puedo enviar datos a 400 ns manualmente?
(Intenté SPI: no lo suficientemente confiable, a veces se omiten los pulsos del reloj y los datos resultantes). Las interrupciones a través de un temporizador incluso tomarán más tiempo, ya que contiene flujo de interrupción (a través de HAL).
Actualizar
Nueva aplicación para probar mejor:
unsigned long counter = 0;
En main:
while (1)
{
GPIOC->BSRR = GPIO_PIN_13; // SET
counter++;
if (counter == 10000000)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14);
counter = 0;
}
}
Actualizar Debajo del código desensamblado (más de lo que pensaba):
152 GPIOC->BSRR = GPIO_PIN_13; // SET
0800122e: mov.w r2, #8192 ; 0x2000
08001232: ldr r3, [pc, #36] ; (0x8001258 <main+64>)
08001234: str r2, [r3, #16]
158 counter++;
08001236: ldr r2, [pc, #36] ; (0x800125c <main+68>)
08001238: ldr r3, [r2, #0]
0800123a: adds r3, #1
0800123c: str r3, [r2, #0]
159 if (counter == 10000000)
0800123e: ldr r2, [pc, #32] ; (0x8001260 <main+72>)
08001240: cmp r3, r2
08001242: bne.n 0x800122e <main+22>
161 HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14);
08001244: mov.w r1, #16384 ; 0x4000
08001248: ldr r0, [pc, #12] ; (0x8001258 <main+64>)
0800124a: bl 0x80004e0 <HAL_GPIO_TogglePin>
162 counter = 0;
0800124e: movs r2, #0
08001250: ldr r3, [pc, #8] ; (0x800125c <main+68>)
08001252: str r2, [r3, #0]
08001254: b.n 0x800122e <main+22>
08001256: nop