打印
[应用方案]

新唐单片机如何生成精确延迟

[复制链接]
1829|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
uiint|  楼主 | 2024-5-20 20:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
假如使用者想要产生精确的延迟时间,建议使用 __nop() 函数来组合达成。__nop() 函数能够产生 1 个精确的 CPU 频率周期延迟时间。然而,由于 flash 的速度低于 CPU 的频率速度,在 CPU 内部有快取优化的技术,编译程序也会自动针对程序做优化,造成__nop() 函数组合出来的时间会与预期的时间不同。因此,建议将程序代码放置于 SRAM 中执行,以避免优化造成的非预期延迟时间问题。

以产生 2 us 的延迟时间为例:
(1) CPU 频率= 32MHz => 1 CPU 频率周期花费 1/32000000 sec = 31.25 ns
(2) 2 us 延迟时间 = 2000 ns / 31.25 ns = 64 次 CPU 频率周期

1. 于KEIL的项目中加入一个新的.c文件
2. 将文件位置指定至SRAM
3. 设定 Linker

4. 编写延迟程序代码

由于执行一次 for 循环需要花费 5 个 CPU 频率周期的时间,因此可以使用以下的方式达到 2 us 的时间延迟

(1) 执行一次 for 循环需要 5 个 CPU 频率周期
(2) 执行一次 __NOP() 指令需要 1 个 CPU 频率周期
(3) 64 个 CPU 频率周期 = 8 ( 5 ( for 循环 ) + 3 * 1 ( __NOP() ) )



void Delay_Test_Function(void)
{
    for(i = 0; i <8; i ++)/ *延迟2微秒。* /
    {
        __NOP();
        __NOP();
        __NOP();
    }
}



5. 测试

使用者可以利用下列程序代码进行延迟时间的测试,透过示波器量测 I/O toggle 的时间,以观察延迟函数是否精准。由于 CPU 需要下指令让 I/O 转态,因此观察到的时间中需要增加转态的指令时间 (PA0 = 0)。

执行一次 PA = 0 需花费 11 CPU 指令周期,这意味着 I/O 会持续 (64+11) * 31.25 ns = 2343.75 ns 的时间才进行转态。



void Delay_Test_Function(void)
{
    uint32_t i,DelayCNTofCPUClock = 8;
    PA0 = 1;
    for(i = 0; i <DelayCNTofCPUClock; i ++)/ *延迟2微秒。* /
    {
        __NOP();
        __NOP();
        __NOP();
    }
    PA0 = 0;
}

使用特权

评论回复
沙发
tpgf| | 2024-6-4 16:40 | 只看该作者
为什么有时候会在延时函数中卡死呢

使用特权

评论回复
板凳
renzheshengui| | 2024-6-4 17:16 | 只看该作者
如何确定自己的延时是非常精确的呢

使用特权

评论回复
地板
keaibukelian| | 2024-6-4 18:01 | 只看该作者
nop的时间和主频的分频倍数有关系吗

使用特权

评论回复
5
heimaojingzhang| | 2024-6-4 18:33 | 只看该作者
nop指令的延时时间肯定收到主频的影响啊

使用特权

评论回复
6
guanjiaer| | 2024-6-4 19:05 | 只看该作者
精确的延迟和时钟的精度成正比

使用特权

评论回复
7
paotangsan| | 2024-6-5 08:01 | 只看该作者
不同架构的单片机的指令所需要的指令周期不同?

使用特权

评论回复
8
weifeng90| | 2024-6-6 23:15 | 只看该作者
用定时器实现精确延时

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

4184

帖子

1

粉丝