我首先在 Arduino 论坛上发布了这个问题,但我的问题最近没有受到太多关注,所以这里......
我非常努力地制作了一个简单的草图来证明 micros() 方法在 Nano 33 BLE Sense 上的速度有多慢:
#include "mbed.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#define OUTPUT_PIN NRF_GPIO_PIN_MAP(1,11)
unsigned long startClock;
unsigned long stopClock;
unsigned long arithmeticMinuend = 4294967295;
unsigned long arithmeticSubtrahend = 2147483648;
unsigned long arithmeticDifference = 0;
unsigned long timeDifference1 = 0;
unsigned long timeDifference2 = 0;
//Assume 1 to 4 clock cycles (15.625 to 62.5 ns) is required for every...
//* call of micros();
//* subtraction of two unsigned longs.
//Therefore we should not be able to measure the time to execute either task by using the micros() - startClock technique, as...
//* micros() - startClock = 0 in either case.
void setup() {
Serial.begin(115200);
while (!Serial);
nrf_gpio_cfg_output(OUTPUT_PIN);
startClock = micros();
stopClock = micros();
}
void loop() {
timeDifference1 = microsecondsToSubtract2LongsOnce();
timeDifference2 = microsecondsToSubtract2LongsTwice();
Serial.print("timeDifference1 = ");
Serial.print(timeDifference1);
Serial.print(" us.\ntimeDifference2 = ");
Serial.print(timeDifference2);
Serial.println(" us.");
microsecondsToSubtract2LongsOnceMeasuredWithScope();
delay(100);
microsecondsToSubtract2LongsTwiceMeasuredWithScope();
delay(100);
microsecondsToToggleOutputPinMeasuredWithScope();
while(1) {
}
}
//Prints 8 us:
unsigned long microsecondsToSubtract2LongsOnce() {
startClock = micros();
stopClock = micros();
return stopClock - startClock;
}
//Prints 9 us:
unsigned long microsecondsToSubtract2LongsTwice() {
startClock = micros();
arithmeticDifference = arithmeticMinuend - arithmeticSubtrahend;
stopClock = micros();
return stopClock - startClock;
}
//Measured 18 us on scope:
void microsecondsToSubtract2LongsOnceMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
startClock = micros();
stopClock = micros();
nrf_gpio_pin_toggle(OUTPUT_PIN);
}
//Measured 18 us on scope:
void microsecondsToSubtract2LongsTwiceMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
startClock = micros();
arithmeticDifference = arithmeticMinuend - arithmeticSubtrahend;
stopClock = micros();
nrf_gpio_pin_toggle(OUTPUT_PIN);
}
//Measured 500 ns on scope:
void microsecondsToToggleOutputPinMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
nrf_gpio_pin_toggle(OUTPUT_PIN);
}
我将使用示波器进行的时间测量与使用 micros() 进行的时间测量进行比较。通过数学计算,我们得到一个 micros() 调用所需的时钟周期数 (CC) = (0.5*(18000 - 500) ns)/15.625 ns = 560 CC!!!
有人可以举一个在不需要超过 10 CC 的板上测量时间的例子吗???
根据我的阅读,我认为更快(理论上 1 CC)策略将涉及使用方法nrf_drv_timer或更新的nrfx_timer(这两种策略都需要将计时器设置为在计数器模式下运行),但我找不到具体的使用示例在我的 Arduino 的 NRF52840 上。
编辑:
我还尝试通过使用 mbed 的 us_ticker 来减少时间,但计时结果完全相同。这是我用于该测试的代码:
#include "mbed.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#define OUTPUT_PIN NRF_GPIO_PIN_MAP(1,11)
mbed::Timer timer;
uint32_t startClock;
uint32_t stopClock;
uint32_t arithmeticMinuend = 4294967295;
uint32_t arithmeticSubtrahend = 2147483648;
uint32_t arithmeticDifference = 0;
uint32_t timeDifference1 = 0;
uint32_t timeDifference2 = 0;
//Assume 1 to 4 clock cycles (15.625 to 62.5 ns) is required for every...
//* call of micros();
//* subtraction of two unsigned longs.
//Therefore we should not be able to measure the time to execute either task by using the micros() - startClock technique, as...
//* micros() - startClock = 0 in either case.
void setup() {
Serial.begin(115200);
while (!Serial);
nrf_gpio_cfg_output(OUTPUT_PIN);
timer.start();
startClock = timer.read_us();
stopClock = timer.read_us();
}
void loop() {
timeDifference1 = microsecondsToSubtract2LongsOnce();
timeDifference2 = microsecondsToSubtract2LongsTwice();
Serial.print("timeDifference1 = ");
Serial.print(timeDifference1);
Serial.print(" us.\ntimeDifference2 = ");
Serial.print(timeDifference2);
Serial.println(" us.");
microsecondsToSubtract2LongsOnceMeasuredWithScope();
timer.stop();
delay(100);
timer.start();
microsecondsToSubtract2LongsTwiceMeasuredWithScope();
timer.stop();
delay(100);
timer.start();
microsecondsToToggleOutputPinMeasuredWithScope();
timer.stop();
while(1) {
}
}
//Prints 8 us:
unsigned long microsecondsToSubtract2LongsOnce() {
startClock = timer.read_us();
stopClock = timer.read_us();
return stopClock - startClock;
}
//Prints 9 us:
unsigned long microsecondsToSubtract2LongsTwice() {
startClock = timer.read_us();
arithmeticDifference = arithmeticMinuend - arithmeticSubtrahend;
stopClock = timer.read_us();
return stopClock - startClock;
}
//Measured 18 us on scope:
void microsecondsToSubtract2LongsOnceMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
startClock = timer.read_us();
stopClock = timer.read_us();
nrf_gpio_pin_toggle(OUTPUT_PIN);
}
//Measured 18 us on scope:
void microsecondsToSubtract2LongsTwiceMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
startClock = timer.read_us();
arithmeticDifference = arithmeticMinuend - arithmeticSubtrahend;
stopClock = timer.read_us();
nrf_gpio_pin_toggle(OUTPUT_PIN);
}
//Measured 500 ns on scope:
void microsecondsToToggleOutputPinMeasuredWithScope() {
nrf_gpio_pin_toggle(OUTPUT_PIN);
nrf_gpio_pin_toggle(OUTPUT_PIN);
}