(AVR开发)_delay_loop_1,一段内联汇编写的延时程序

本文解析了一段用在AVR微控制器上的内联汇编延时程序_delay_loop_1,通过计数器实现延时,详细解释了其工作原理和如何根据时钟频率计算实际延时时间。
摘要由CSDN通过智能技术生成

研究AVR时,看到一段用内联汇编写的延时程序,于是想着记录下来。当然,我肯定看不懂,但好在现在有ai这种神器,帮助我学习和理解。

void
_delay_loop_1(uint8_t __count)
{
asm volatile (
"1: dec %0" "\n\t"
"brne 1b"
: "=r" (__count)
: "0" (__count)
);
}

这段代码是什么

这段代码写了一个名为_delay_loop_1 的函数,用于在AVR微控制器上进行延时。

数的参数是一个无符号8位整数 (uint8_t __count),表示要进行的延时时间(循环次数)。

  • void _delay_loop_1(uint8_t __count): 这是函数的定义。函数接受一个参数 __count,用于确定延时的循环次数。

  • __asm__ volatile (...): 这是内联汇编语句块。volatile 关键字告诉编译器这个汇编代码具有副作用(会修改或使用输入、输出操作数),所以编译器不应该对其进行优化。它确保函数每次都执行相同的操作。

  • 汇编代码块中,使用两个指令:

  • 1: dec %0: 这是一个标签 1: 和一个汇编指令 dec %0dec 是减量指令,用于将寄存器 %0 的值减1。
  • brne 1bbrne 是一种分支指令,意思是 "如果零标志为0则跳转"。即当 %0 不为0时,跳转到标签 1: 继续执行循环。
  • : "=r" (__count): 这是汇编代码块的输出操作数部分,表示 __count 会被作为一个寄存器 (=r) 的输出操作数。最终结果将写回到变量 __count 中。

  • : "0" (__count): 这是汇编代码块的输入操作数部分,表示 __count 将被作为一个寄存器 (0) 的输入操作数,传递给汇编代码块中的 %0

综上所述,该函数通过循环减量 __count 参数来实现延时。循环次数由 __count 的初始值确定,循环在 __count 不为0时持续执行。

这那么到底延时了多长时间,也就是一个count是多少?

要准确确定该函数的延时时间,需要知道 AVR 微控制器的时钟频率以及每个循环迭代的执行时间。假设每个循环迭代的执行时间可以忽略不计,那么该函数的总延时时间取决于 __count 参数的值以及 AVR 微控制器的时钟频率。

如果假设在每个循环迭代中,执行时间可以忽略不计,那么每次循环的延时时间将主要由循环的执行次数决定。在这种情况下,循环体中的指令 dec %0brne 1b 将会重复执行,直到 %0 的值为零。

但是,要准确确定总的延时时间,我们需要知道 AVR 微控制器的时钟频率。通常情况下,AVR 微控制器的时钟频率在几十 MHz 到几百 MHz 之间,不同型号的微控制器具有不同的时钟频率。知道了时钟频率之后,我们可以根据循环迭代的次数和时钟频率来计算总的延时时间。

一般来说,延时时间可以通过以下公式计算:

延时时间 = 循环次数 × 每次循环的执行时间

每次循环的执行时间可以用时钟周期来表示,通常以纳秒 (ns) 或微秒 (μs) 为单位。

注释

看到了这个函数的注释

/** \ingroup util_delay_basic

    Delay loop using an 8-bit counter \c __count, so up to 256
    iterations are possible.  (The value 256 would have to be passed
    as 0.)  The loop executes three CPU cycles per iteration, not
    including the overhead the compiler needs to setup the counter
    register.

    Thus, at a CPU speed of 1 MHz, delays of up to 768 microseconds
    can be achieved.
*/

翻译过来就是:使用一个8位计数器 \c __count 来进行延时循环,因此最多可以进行256次迭代。(值256必须作为0传递)。每次循环执行三个CPU周期,不包括编译器设置计数器寄存器所需的开销。
因此,在CPU速度为1 MHz时,可以实现长达768微秒的延时。

我的理解

也就是1/1MHZ = 1us,不知道对不对,这里所说的循环执行3个时钟周期也就是每次调用就会延时3us,即_delay_loop_1(1)就是3us,但是最多执行256次,也就是传参最大值是256,所以_delay_loop_1(256) = 768us。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值