准确的方式延迟100us

9个帖子/ 0新
最后一篇
KR105
离线
最后一次露面:4年6个月前
加入:2015-06-16 18:20
准确的方式延迟100us

我正在与外部设备相互作用,在那里我在一个GPIO中敲击信号。该协议是专有的,所以我不能使用任何提供的硬件外围设备。现在我正在使用这样的函数来延迟执行:


void usdelay(uint32_t nof_us)
{
而(nof_us--){
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
}
}

我从ADC.C函数ADC_USDELay拍摄了此代码。

这是一个问题,它根本不准确,有时它延迟了100U起来,下一个(在示波器上测量)它延迟110US,协议搞定,我无法传输数据。我曾经用AVR核心做过这件事,并且与NOPS工作得很好,这里没有出于某种原因。

我知道Timer外围设备,但我不知道如何为这种短暂的间隔使用它们,而无需添加可以改变代码的时机的开销。

有人对此有任何想法吗?

设备:
Mohit3112.
离线
最后一次露面:9个月14小时前
专家
加入:2014-08-04 13:45
如果不是睡眠模式: -

如果不是睡眠模式: -

void delay_us(uint16_t time_us)
{
uint32_t time_gone = 0;
Systick - > Ctrl = 0;
Systick - > Load = 0xFFFFFF;
Systick - > Val = 0;
Systick-> Ctrl = 0x5;
而(time_limit <= time_us)
{
time_gone =(0xffffff - systick-> val)/ 16;
}
Systick-> Ctrl = 0;
}

mt_dialog.
离线
最后一次露面:1个月3周前
职员
加入:2015-06-08 11:34
嗨KR105,

嗨KR105,

该功能应该足够准确,你确定是否在函数正在执行时发出任何中断?

谢谢mt_dialog.

KR105
离线
最后一次露面:4年6个月前
加入:2015-06-16 18:20
我这样做是为了避免:

我这样做是为了避免:


global_int_stop();
... 代码 ...
global_int_start();

据我所知,应该避免这种问题,对吗?

mt_dialog.
离线
最后一次露面:1个月3周前
职员
加入:2015-06-08 11:34
嗨KR105,

嗨KR105,

是的,禁用中断延迟功能应该正常,应该足够准确,请检查您使用的时钟,也许这导致您看到的偏移量。

谢谢mt_dialog.

KR105
离线
最后一次露面:4年6个月前
加入:2015-06-16 18:20
如果蓝牙运行良好,那

如果蓝牙运行良好,这意味着时钟很好吗?我也使用16MHz晶体和32kHz晶体(即时不使用任何睡眠模式,所以也许它是冗余的)。我不认为这是在算法上进行的IF / for /呼叫的开销,因为该算法能够在11MHz处没有问题,并且代码主要从那里复制粘贴。我还在循环上执行GPIO高/低操作,并建立了有源BLE链接(无数据流量)。
只是为了澄清,信号似乎在比特禁止过程中慢慢地偏移,它始终是这样的信号:高度 - 10U - 低 - 105us - 高 - 110us等,并且代码被指定为类似(简体)的东西(简化):
为了 ...
GPIO高
delay100us
GPIO低
delay100us
结束

更多的想法?我在写这篇文章时有一些,明天生病了,但任何帮助都会很好。

mt_dialog.
离线
最后一次露面:1个月3周前
职员
加入:2015-06-08 11:34
嗨KR105,

嗨KR105,

我刚刚在分析仪上测试了这个.....在App_Async_trm中放置了以下代码:

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);
}

脉冲足够精确,始终稳定。

谢谢mt_dialog.

KR105
离线
最后一次露面:4年6个月前
加入:2015-06-16 18:20
我解决了这个问题。我没有

我解决了这个问题。我没有深入了解确切的原因,但是有一个像下面的一个循环制作了我正在寻找的时间。也许我嵌套的函数,如果/ elorly等导致额外的延迟,但从现在这是对我有效的。


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.
离线
最后一次露面:1个月3周前
职员
加入:2015-06-08 11:34
嗨KR105,

嗨KR105,

很高兴它对你有效。

谢谢mt_dialog.

主题锁定