Como funciona a função delayMicroseconds (). Pelo que entendi, o prescaler do timer0 está definido como 64. Para um relógio de 16MHz, você fornece 4,0uS por contagem. Estou um pouco confuso em matemática para chegar ao intervalo de 1 uS?
8
micros()
diz "Em placas Arduino de 16 MHz (por exemplo, Duemilanove e Nano), essa função tem uma resolução de quatro microssegundos (ou seja, o valor retornado é sempre um múltiplo de quatro)".Respostas:
O código fonte desta função está bastante bem documentado e pode ser encontrado em /usr/share/arduino/hardware/arduino/cores/arduino/wiring.c nos sistemas Linux. Os sistemas Windows terão um caminho semelhante ao arquivo fiação.c. Faça o esforço de encontrar o arquivo e navegá-lo. Por enquanto, apenas foque nesta função única, ela não depende de nenhuma outra função.
Ao inspecionar o código, você notará que não se trata de cronômetros, mas de ciclos de instruções. O código depende muito da otimização do compilador, sendo exatamente a mesma para você e para o desenvolvedor da biblioteca. Que uma suposição do autor! O número de ciclos de CPU 'queimados' por cada instrução está bem documentado no documento do conjunto de instruções do Atmel AVR .
Primeiro, o valor do atraso é verificado como sendo igual a 1, nesse caso, retornando da rotina já gasta em um microssegundo de tempo de CPU.
Em seguida, o valor do atraso é multiplicado por quatro (
<<=2
). O__asm__
loop é compilado em um loop de ciclo de 4 CPU. 4 ciclos × 4 = 16 ciclos. 16MHz / (4 × 4) = 1MHz, o que leva 1 us de tempo de ciclo, a resolução que buscamos.Os últimos -2 microssegundos (antes do início do loop) são novamente uma correção na sobrecarga do compilador introduzida. Chamar o
__asm__
código de C requer algumas instruções extras para salvar os registros da CPU.Para um Arduino normal a 16MHz, apenas o seguinte código será compilado:
BTW: O código compilado é bastante preciso, mas esteja ciente do seguinte: No Arduino, há interrupções temporizadas configuradas das quais a maioria desconhece. Quando uma interrupção é recebida durante a execução do
delayMicroseconds()
, o momentodelayMicroseconds()
será errado. É claro que você pode interromper as interrupções antes de chamádelayMicroseconds()
-las e ativá-las posteriormente, mas isso novamente afeta a precisão do tempo pela duração do código compilado para ativar / desativar.fonte