En un STM32F103C8T6 (72MHz), quiero usar un retardo en el rango de 100 nanosegundos (para crear un controlador de tira de LED, WS2813B).
Dado que HAL solo proporciona un retraso de ms, encontré en varios lugares el código para usar el contador de marcas / depuración como temporizador.
Tengo el siguiente código:
Inicialización:
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register
unsigned int count = 0;
Dentro de main()
:
*SCB_DEMCR = *SCB_DEMCR | 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
int ticks = 1;
while (1)
{
unsigned int start, current;
start = *DWT_CYCCNT;
do
{
current = *DWT_CYCCNT;
} while((current - start) < ticks);
if (count++ % 1000 == 0)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
}
}
Cuando conecto un analizador lógico, veo una señal PWM de 0.53 ms por conmutador. Como se alterna cada 1,000 recuentos, esto significa 0.53 us (530 ns). Sin embargo, con 1 tick, esperaría algo así como 1 / 72,000,000 = 14 ns (más alguna sobrecarga para el loop while / counter). (nota: el contador de 1,000 que usé porque mi analizador lógico solo puede manejar 200 kHz).
No estoy seguro de si las direcciones en la inicialización son correctas (se encontraron solo para STM32F103VET6).
Entonces, mi pregunta: ¿Cuál es el error en el programa anterior?
(pregunta adicional: ¿es este método bueno de todos modos para un controlador LED, o debo enviar los datos por interrupción o DMA?).
Actualizar
La razón por la que necesito este tipo de retrasos es el T0H
, T1H
, T0L
y T1L
veces que se pueden encontrar en Hoja de datos de WS2813B , página 5.
Tiempo de transferencia de datos (TH + TL = 1.25µs ± 300ns)
T0H código 0, tiempo de alto nivel 300ns ~ 450ns
T1H 1-código, tiempo de alto nivel 750ns ~ 1000ns
T0L 0-code, Low-level time 300ns ~ 100us
T1L 1-code, Low-level time 300ns ~ 100us
Unidad de marco RES, tiempo de nivel bajo 300µs o más