Accurate way to delay 100us

9 posts / 0 new
Last post
kr105
Offline
Last seen:4 years 6 months ago
Joined:2015-06-16 18:20
Accurate way to delay 100us

I'm interfacing with an external device where I'm bit banging the signal in one GPIO. The protocol is proprietary so I can't use any of the provided hardware peripherals. Right now I'm using a function like this to delay the execution:


void usDelay( uint32_t nof_us )
{
while( nof_us-- ){
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
}
}

I took this code from the adc.c function adc_usDelay.

问题是,它是不准确的t all, sometimes it delays 100us exactly and the next one (measured on the oscilloscope) it delays 110us instead and the protocol gets messed up and I can't transmit data. I used to do this with an AVR core and a delay function with nops worked well, here it doesn't for some reason.

I'm aware about the TIMER peripherals but I have no idea how to use them for such short intervals and without adding overhead that could alter the timing of the code.

Anyone has any idea about this?

Device:
mohit3112
Offline
Last seen:9 months 14 hours ago
Expert
Joined:2014-08-04 13:45
if not in sleep mode :-

if not in sleep mode :-

void delay_us(uint16_t time_us)
{
uint32_t time_gone = 0;
SysTick -> CTRL = 0;
SysTick ->LOAD = 0xFFFFFF;
SysTick ->VAL =0;
SysTick-> CTRL = 0x5;
while(time_limit <= time_us)
{
time_gone = (0xFFFFFF - SysTick->VAL)/16;
}
SysTick->CTRL = 0;
}

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi kr105,

Hi kr105,

The function should be accurate enough, are you sure that there isn't any interrupt issued while the function is executing?

Thanks MT_dialog

kr105
Offline
Last seen:4 years 6 months ago
Joined:2015-06-16 18:20
I'm doing this to avoid that:

I'm doing this to avoid that:


GLOBAL_INT_STOP();
... code ...
GLOBAL_INT_START();

As far as I understand that should avoid that problem, right?

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi kr105,

Hi kr105,

Yes by disabling the interrupts the delay function should be fine and should work accurate enough, please check the clock you are using, maybe this is causing the offset you are seeing.

Thanks MT_dialog

kr105
Offline
Last seen:4 years 6 months ago
Joined:2015-06-16 18:20
If bluetooth works well, that

If bluetooth works well, that means that the clock is fine right? Im using a 16mhz crystal and a 32khz crystal too (Im not using any sleep mode, so maybe it is redundant). I dont think it is the overhead of the if/for/calls that are being made on the algorithm as the Attiny was able to handle them with no problems at 11mhz and the code is mostly copy paste from there. Im also doing GPIO high/low operations on the loop and an active ble link is established (no data traffic).
Just to clarify, the signal seems to offset slowly during the course of the bitbanging, it always does the signal like : HIGH - 100us - LOW - 105us - HIGH - 110us - etc and in code it is specified as something like (simplified):
for ...
GPIO high
delay100us
GPIO low
delay100us
end for

Any more ideas? I got some while writing this post, ill test them tomorrow but any help will be nice.

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi kr105,

Hi kr105,

I 've just tested this on an analyzer.....in app_async_trm placed the following code:

for(i=0; i<15; i++)
{
GPIO_SetActive(GPIO_PORT_1, GPIO_PIN_0);
adc_usDelay(100);
GPIO_SetInactive(GPIO_PORT_1, GPIO_PIN_0);
adc_usDelay(100);
}

The pulse was accurate enough and always steady.

Thanks MT_dialog

kr105
Offline
Last seen:4 years 6 months ago
Joined:2015-06-16 18:20
I solved this issue. I haven

I solved this issue. I haven't go deep on the exact reason but having a loop like the one below produced the timing i was looking for. Maybe my nested functions, if/else, etc were causing the extra delay, but as of now this is what worked for me.


for(i=0; i<15; i++)
{
GPIO_SetActive(GPIO_PORT_1, GPIO_PIN_0);
adc_usDelay(100);
GPIO_SetInactive(GPIO_PORT_1, GPIO_PIN_0);
adc_usDelay(96);
}

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi kr105,

Hi kr105,

Glad it worked for you.

Thanks MT_dialog

Topic locked