Nios II IDE中编程的延时子程序的问题及解决 ,关于编写Nios II的延时函数的一点心得

使用单层的for循环,一切问题解决了。既可以单独使用,也可以使用在子程序中。

void Delay(volatile int t)
{
  static volatile int ti;
  for( ti = 0; ti < t; ti ++ );
}


平台

硬件:nios/f 100MHz

软件:image

 

内容

0 一点说明

本文仅讨论所述平台的一点心得,若其他等级的nios或优化,请自行研究。

 

1 usleep()有多准

参考[笔记].怎样使用Nios II中的timestamp_timer?.[Nios II][SOPC Builder],我们做以下实验:

代码1 本文所用测试代码模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>                    // printf()
#include <unistd.h>                   // usleep()
#include "system.h"                   // 系统
#include "my_types.h"                 // 数据类型
#include "sys/alt_timestamp.h"        // timestamp
int  main()
{
   u32 t0, t1, t2;
   vu32 i;
 
   alt_timestamp_start();                // 开启时间戳服务
 
   t0 = alt_timestamp();                 // 测量时间戳t0
   usleep(1000);
   t1 = alt_timestamp();                 // 测量时间戳1
   for (i=0; i<1000; i++);
   t2 = alt_timestamp();                 // 测量时间戳1
 
   printf ( "时间戳(t1-t0) = %ld \n" , (t1-t0));
   printf ( "时间戳(t2-t1) = %ld \n" , (t2-t1));
   printf ( "\n" );
   printf ( "系统时钟频率是 %ld Hz\n" , alt_timestamp_freq());
 
   return  0;
}

其中第14行和第16行的内容是下面讨论的重点

1
usleep(1000);
1
for (i=0; i<100; i++);

众所周知,usleep()是Nios II HAL自带的us级的延时函数,那么它究竟有多准。

(1)修改第14行为:

1
usleep(1*1000*1000);

编译运行的结果如图1.1 所示,usleep(1*1000*1000)共占用99,568,957个tick。那么1s有多少tick呢,正如显示的时钟频率一样,1s可分为100,000,000个tick。也就是说usleep(1*1000*1000)实际延时为99,568,957/100M=0.99568957 s。这个时间已经相当准了,和1s差距不大。

图1.1 usleep(1*1000*1000)的结果

图1.1 usleep(1*1000*1000)的结果

(2)修改第14行为:

1
usleep(1*1000);

编译运行的结果如图1.2所示。这一次是100,843/100M=1.008ms,也不错。

图1.2 usleep(1*1000)的结果

图1.2 usleep(1*1000)的结果

(3)修改第14行为:

1
usleep(100);

编译运行的结果如图1.3所示。这一次是11,743/100M=117.43us,误差开始显现了。

图1.3 usleep(100) 的结果

图1.3 usleep(100) 的结果

(4)修改第14行为:

1
usleep(10);

编译运行的结果如图1.4所示。这一次是1,511/100M=15.11us,误差不是一点点。

图1.4 usleep(10)的结果

图1.4 usleep(10)的结果

(5)修改第14行为:

1
usleep(1);

 

 

 

编译运行的结果如图1.5所示。这一次是620/100M=6.2us,已经相当离谱了。

图1.4 usleep(1)的结果

图1.4 usleep(1)的结果

 

小结一下:usleep()在ms级别及以上的延时的确很准,但是us级别就有点捉襟见肘了

 

2 想要延时1us怎么办?

(1)修改第16行为:

1
for (i=0; i<100; i++);

编译运行的结果如图2.1所示,亦即延时1,197/100M=11.97us。

图2.1 for(100)的结果

图2.1 for(100)的结果

(2)修改第16行为:

1
for (i=0; i<10; i++);

编译运行的结果如图2.2所示,亦即延时207/100M=2.07us。

图2.2 for(10)的结果

图2.2 for(10)的结果

(3)修改第16行为:

1
for (i=0; i<1; i++);

编译运行的结果如图2.2所示,亦即延时106/100M=1.06us。

图2.3 for(1)的结果

图2.3 for(1)的结果

 

小结:for(1)可以很第实现延时1us的任务。

 

需要注意的地方

观察第9行,此处i被申明为vu32(volatile unsigned long)类型,倘若改为u32(unsigned long)类型的话。那么无论i值为多少,都会被gcc优化掉的。

 

4 小结

timestamp可以有效地协助我们编写小时间段的延时代码。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值