Delay less than 1 µs ?

acronis
Mon Nov 06, 2017 12:14 pm
Hello .
How can I make delay (pause) less than 1 µs ?
for example, 10 nanoseconds ?

Pito
Mon Nov 06, 2017 12:24 pm
You cannot do it in sw, afaik. Try it in hw – for example a single 74HC gate (or inverter) makes ~10ns at 3.3V..

acronis
Mon Nov 06, 2017 12:38 pm
I understand you.
And if I have 1 nanosecond ?

edogaldo
Mon Nov 06, 2017 12:49 pm
Running @72MHz your clock period is little less than 14ns (assuming an F103 mcu) so I’d say that 14ns is the minimum resolution you could achieve.
To delay one clock cycle by code you could use:
asm volatile ("nop");

acronis
Mon Nov 06, 2017 12:53 pm
Great !
Thanks, I will try to F407VET6 BLACK.
I will unsubscribe by results

Pito
Mon Nov 06, 2017 1:03 pm
And if I have 1 nanosecond ?
You may get 1ns or less with:
1. an fpga (some have got a XXX picoseconds fine-tunig with delays)
2. delay lines – ie transmission lines, coax cable
3. there is an stm32 series (3×4) which has got:
High-resolution timer: 217ps, self-compensated versus power supply and temperature drift.

acronis
Tue Nov 07, 2017 2:00 pm
Today I tried
asm volatile (“nop”);

code:

loop ()
{
digitalWrite(PA5,LOW);
asm volatile (“nop”);
digitalWrite(PA5, HIGH);
}

oscilloscope showed failure in 200ns on-Board STM32F407.

how you got 14ns on the stm32f103 ?


acronis
Tue Nov 07, 2017 2:06 pm
you commented out “nop”

loop ()
{
digitalWrite(PA5,LOW);
//asm volatile (“nop”);
digitalWrite(PA5, HIGH);
}

the time remains the same – 200 ns at the switching state on pine (((


zoomx
Tue Nov 07, 2017 4:10 pm
This post!
nanoseconds delay
http://stm32duino.com/viewtopic.php?f=3&t=2080#p27850

edogaldo
Tue Nov 07, 2017 4:19 pm
Of course it’s the digitalWrite and loop overhead..
14ns is the duration of the single asm(nop) (on f407 it’s 1us/168 = 6ns) which is far little respect to the duration of all other stuff..

Rick Kimball
Tue Nov 07, 2017 4:34 pm
You should search in code snippets for a post I made about using the DWT peripheral for cycle counting

Rick Kimball
Tue Nov 07, 2017 11:34 pm
I used Pito’s code to create a 100kHz toggle using the DWT timer. Granted you aren’t going to be able to create a 10nsec pulse, as the the cycle count at 72 MHz is 13.888 nsec, however you can do accurate usec pulses using the DWT peripheral.

// accurate micro second pin toggle ..
// DWT defines from Pito's post
// * note, I made CpuGetTicks volatile

#define DWTEn() (*((uint32_t*)0xE000EDFC)) |= (1<<24)
#define CpuTicksEn() (*((uint32_t*)0xE0001000)) = 0x40000001
#define CpuTicksDis() (*((uint32_t*)0xE0001000)) = 0x40000000
#define CpuGetTicks() (*((volatile uint32_t*)0xE0001004))

void setup() {
DWTEn();
CpuTicksEn();
pinMode(LED_BUILTIN,OUTPUT); // for blue pill this is the PC13
}

const uint32_t usec_delay = 5; // 5usecs == 100kHz toggle
const unsigned usecs_in_cycles = 72*usec_delay; // 72 cycles in 1 usec with 72MHz system clock

void loop() {
static unsigned toggle;
static uint32_t prev;

while(1) {
uint32_t curr = CpuGetTicks();

// toggle LED pin every usec_delay
if ( (curr-prev) >= usecs_in_cycles ) {
prev = prev + usecs_in_cycles;
toggle^=1;
GPIOC->regs->BSRR = ((1 << 13 ) << 16) | (toggle << 13);
}
}
}


edogaldo
Wed Nov 08, 2017 11:14 am
[acronis – Tue Nov 07, 2017 2:06 pm] –
you commented out “nop”

loop ()
{
digitalWrite(PA5,LOW);
//asm volatile (“nop”);
digitalWrite(PA5, HIGH);
}

the time remains the same – 200 ns at the switching state on pine (((

If you want to achieve clock level speed you need to go with assembly..
Here a sample asm sketch to toggle PA5 on F407:
void setup() {
// put your setup code here, to run once:
pinMode(PA5,OUTPUT);
//GPIOA.regs->BSRRL = 0x0005;
//GPIOA.regs->BSRRL = 0x0500;
asm volatile ("mov r0,#0x0018");
asm volatile ("movt r0,#0x4002");
asm volatile ("mov r1,#0x0005");
asm volatile ("mov r2,#0x0500");
asm volatile ("myloop: strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("strh r1, [r0]");
asm volatile ("strh r2, [r0]");
asm volatile ("b.n myloop");
}

void loop() {
// put your main code here, to run repeatedly:

}


acronis
Wed Nov 08, 2017 12:17 pm
YOU very much.
I will try to do so

edogaldo
Wed Nov 08, 2017 1:18 pm
[acronis – Wed Nov 08, 2017 12:17 pm] –
YOU very much.
I will try to do so

Sorry, I made a mistake with setting BSRR..
Here a correction anyway I’m not able to test it on the F407 so I cannot guarantee there are no more errors:
void setup() {
// put your setup code here, to run once:
pinMode(PA5,OUTPUT);
//GPIOA.regs->BSRR = 0x0020; // set PA5
//GPIOA.regs->BSRR = 0x00200000; // clear PA5
asm volatile ("ldr r0,#0x40020018"); // r0 -> GPIOA.regs->BSRR
asm volatile ("mov r1,#0x0020"); // r1 -> mask to set PA5 HIGH in BSRR
asm volatile ("lsl r2,r1,#0x10"); // r2 -> mask to set PA5 LOW in BSRR
for(;;)
{
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
asm volatile ("str r2, [r0]");
asm volatile ("str r1, [r0]");
}
}

void loop() {
// put your main code here, to run repeatedly:

}


Leave a Reply

Your email address will not be published. Required fields are marked *