在用Nios II做外设时序驱动的时候,经常会用延时函数。有时会常使用某个FPGA芯片和时钟,比如笔者一直使用的芯片是cyclone系列 EP2C35F484C8N,PLL输入SOPC时钟是50M。因此,提前测试硬件运行延时情况并编写今后常用的延时函数有一定的意义。
软件:Quartus II 9.0, Nios II 9.0
硬件配置:
1、  在SOPC中调用Interval Timer核


图 1 调用Interval Timer核

2、配置Interval Time

图 2 Interval Timer参数配置
各参数说明请参照Quartus II Handbook Version 9.0 Volume 5: Embedded Peripherals, Chapter 24: Interval Timer Core.请根据需要进行设置。
3、更改核的名称
该名称可以按照自己的习惯取名。

 图 3 更改核的名称
4、生成SOPC系统后,要在Nios II中进行设置。右击工程名->System Library Properties-> system library->Timestamp timer

 图 4 Nios II设置
5、完成Nios II设置后,编译。
 
软件编程
参考Nios II Software Developer’s Handbook
例程:
#include <stdio.h>                  //printf()
#include <unistd.h>                 //usleep()
#include "system.h"                 
#include <sys/alt_timestamp.h>      //timestamp
#include "alt_types.h"
void Delay0(unsigned long m)
{
    usleep(m);
}
void Delay1(unsigned long n)
{
    for(;n>0;n--);   
}
void Delay2(unsigned long p)
{
    while(--p);
}
int main(void)
{
    alt_u32 t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,
            t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,
            t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,
            freq;     
    if(alt_timestamp_start()<0)              //启动timestampe的计数
    {
        printf("No timestamp device available\n");
    }
    else
    {
        //usleep
        t0 = alt_timestamp();                 // 测量时间戳t0 
        Delay0(1); 
        t1 = alt_timestamp();                 // 测量时间戳t1
        Delay0(4); 
        t2 = alt_timestamp();                 // 测量时间戳t2 
        Delay0(7); 
        t3 = alt_timestamp();                 // 测量时间戳t3  
        Delay0(10); 
        t4 = alt_timestamp();                 // 测量时间戳t4
        Delay0(40); 
        t5 = alt_timestamp();                 // 测量时间戳t5 
        Delay0(70); 
        t6 = alt_timestamp();                 // 测量时间戳t6  
        Delay0(100); 
        t7 = alt_timestamp();                 // 测量时间戳t7
        Delay0(400); 
        t8 = alt_timestamp();                 // 测量时间戳t8  
        Delay0(700); 
        t9 = alt_timestamp();                 // 测量时间戳t9 
        Delay0(1000); 
        t10 = alt_timestamp();                 // 测量时间戳t10
        Delay0(4000); 
        t11 = alt_timestamp();                 // 测量时间戳t11 
        Delay0(7000); 
        t12 = alt_timestamp();                 // 测量时间戳t12  
        Delay0(10000); 
        t13 = alt_timestamp();                 // 测量时间戳t13
        Delay0(40000); 
        t14 = alt_timestamp();                 // 测量时间戳t14
        Delay0(70000); 
        t15 = alt_timestamp();                 // 测量时间戳t15
        Delay0(100000); 
        t16 = alt_timestamp();                 // 测量时间戳t16 
        
        //for
        t17 = alt_timestamp();                 // 测量时间戳t17 
        Delay1(1); 
        t18 = alt_timestamp();                 // 测量时间戳t18
        Delay1(4); 
        t19 = alt_timestamp();                 // 测量时间戳t19 
        Delay1(7); 
        t20 = alt_timestamp();                 // 测量时间戳t20  
        Delay1(10); 
        t21 = alt_timestamp();                 // 测量时间戳t21
        Delay1(40); 
        t22 = alt_timestamp();                 // 测量时间戳t22 
        Delay1(70); 
        t23 = alt_timestamp();                 // 测量时间戳t23  
        Delay1(100); 
        t24 = alt_timestamp();                 // 测量时间戳t24
        Delay1(400); 
        t25 = alt_timestamp();                 // 测量时间戳t25  
        Delay1(700); 
        t26 = alt_timestamp();                 // 测量时间戳t26 
        Delay1(1000); 
        t27 = alt_timestamp();                 // 测量时间戳t27
        Delay1(4000); 
        t28 = alt_timestamp();                 // 测量时间戳t28 
        Delay1(7000); 
        t29 = alt_timestamp();                 // 测量时间戳t29  
        Delay1(10000); 
        t30 = alt_timestamp();                 // 测量时间戳t30
        Delay1(40000); 
        t31 = alt_timestamp();                 // 测量时间戳t31
        Delay1(70000); 
        t32 = alt_timestamp();                 // 测量时间戳t32
        Delay1(100000); 
        t33 = alt_timestamp();                 // 测量时间戳t33 
        
        //while
        t34 = alt_timestamp();                 // 测量时间戳t34 
        Delay2(1); 
        t35 = alt_timestamp();                 // 测量时间戳t35
        Delay2(4); 
        t36 = alt_timestamp();                 // 测量时间戳t36 
        Delay2(7); 
        t37 = alt_timestamp();                 // 测量时间戳t37  
        Delay2(10); 
        t38 = alt_timestamp();                 // 测量时间戳t38
        Delay2(40); 
        t39 = alt_timestamp();                 // 测量时间戳t39 
        Delay2(70); 
        t40 = alt_timestamp();                 // 测量时间戳t40  
        Delay2(100); 
        t41 = alt_timestamp();                 // 测量时间戳t41
        Delay2(400); 
        t42 = alt_timestamp();                 // 测量时间戳t42  
        Delay2(700); 
        t43 = alt_timestamp();                 // 测量时间戳t43 
        Delay2(1000); 
        t44 = alt_timestamp();                 // 测量时间戳t44
        Delay2(4000); 
        t45 = alt_timestamp();                 // 测量时间戳t45 
        Delay2(7000); 
        t46 = alt_timestamp();                 // 测量时间戳t46  
        Delay2(10000); 
        t47 = alt_timestamp();                 // 测量时间戳t47
        Delay2(40000); 
        t48 = alt_timestamp();                 // 测量时间戳t48
        Delay2(70000); 
        t49 = alt_timestamp();                 // 测量时间戳t49
        Delay2(100000); 
        t50 = alt_timestamp();                 // 测量时间戳t50 
        
        freq=alt_timestamp_freq();
        
        printf("系统时钟频率是 %ld Hz\n", freq);   //freq可以写成ALT_CPU_FREQ
        printf("\n");
        printf("usleep(1)= %ld us\n",(t1-t0)/(ALT_CPU_FREQ/1000000));  
        printf("usleep(4)= %ld us\n",(t2-t1)/(ALT_CPU_FREQ/1000000));
        printf("usleep(7)= %ld us\n",(t3-t2)/(ALT_CPU_FREQ/1000000));
        printf("usleep(10)= %ld us\n",(t4-t3)/(ALT_CPU_FREQ/1000000));
        printf("usleep(40)= %ld us\n",(t5-t4)/(ALT_CPU_FREQ/1000000));
        printf("usleep(70)= %ld us\n",(t6-t5)/(ALT_CPU_FREQ/1000000));  
        printf("usleep(100)= %ld us\n",(t7-t6)/(ALT_CPU_FREQ/1000000));
        printf("usleep(400)= %ld us\n",(t8-t7)/(ALT_CPU_FREQ/1000000));
        printf("usleep(700)= %ld us\n",(t9-t8)/(ALT_CPU_FREQ/1000000));  
        printf("usleep(1000)= %ld us\n",(t10-t9)/(ALT_CPU_FREQ/1000000));
        printf("usleep(4000)= %ld us\n",(t11-t10)/(ALT_CPU_FREQ/1000000));
        printf("usleep(7000)= %ld us\n",(t12-t11)/(ALT_CPU_FREQ/1000000));  
        printf("usleep(10000)= %ld us\n",(t13-t12)/(ALT_CPU_FREQ/1000000));
        printf("usleep(40000)= %ld us\n",(t14-t13)/(ALT_CPU_FREQ/1000000));
        printf("usleep(70000)= %ld us\n",(t15-t14)/(ALT_CPU_FREQ/1000000));
        printf("usleep(100000)= %ld us\n",(t16-t15)/(ALT_CPU_FREQ/1000000));
        printf("\n");
        printf("for(1)= %ld us\n",(t18-t17)/(ALT_CPU_FREQ/1000000));  
        printf("for(4)= %ld us\n",(t19-t18)/(ALT_CPU_FREQ/1000000));
        printf("for(7)= %ld us\n",(t20-t19)/(ALT_CPU_FREQ/1000000));
        printf("for(10)= %ld us\n",(t21-t20)/(ALT_CPU_FREQ/1000000));
        printf("for(40)= %ld us\n",(t22-t21)/(ALT_CPU_FREQ/1000000));
        printf("for(70)= %ld us\n",(t23-t22)/(ALT_CPU_FREQ/1000000));  
        printf("for(100)= %ld us\n",(t24-t23)/(ALT_CPU_FREQ/1000000));
        printf("for(400)= %ld us\n",(t25-t24)/(ALT_CPU_FREQ/1000000));
        printf("for(700)= %ld us\n",(t26-t25)/(ALT_CPU_FREQ/1000000));  
        printf("for(1000)= %ld us\n",(t27-t6)/(ALT_CPU_FREQ/1000000));
        printf("for(4000)= %ld us\n",(t27-t27)/(ALT_CPU_FREQ/1000000));
        printf("for(7000)= %ld us\n",(t29-t28)/(ALT_CPU_FREQ/1000000));  
        printf("for(10000)= %ld us\n",(t30-t29)/(ALT_CPU_FREQ/1000000));
        printf("for(40000)= %ld us\n",(t31-t30)/(ALT_CPU_FREQ/1000000));
        printf("for(70000)= %ld us\n",(t32-t31)/(ALT_CPU_FREQ/1000000));
        printf("for(100000)= %ld us\n",(t33-t32)/(ALT_CPU_FREQ/1000000));
        printf("\n");
        printf("while(1)= %ld us\n",(t35-t34)/(ALT_CPU_FREQ/1000000));  
        printf("while(4)= %ld us\n",(t36-t35)/(ALT_CPU_FREQ/1000000));
        printf("while(7)= %ld us\n",(t37-t36)/(ALT_CPU_FREQ/1000000));
        printf("while(10)= %ld us\n",(t38-t37)/(ALT_CPU_FREQ/1000000));
        printf("while(40)= %ld us\n",(t39-t38)/(ALT_CPU_FREQ/1000000));
        printf("while(70)= %ld us\n",(t40-t39)/(ALT_CPU_FREQ/1000000));  
        printf("while(100)= %ld us\n",(t41-t40)/(ALT_CPU_FREQ/1000000));
        printf("while(400)= %ld us\n",(t42-t41)/(ALT_CPU_FREQ/1000000));
        printf("while(700)= %ld us\n",(t43-t42)/(ALT_CPU_FREQ/1000000));  
        printf("while(1000)= %ld us\n",(t44-t43)/(ALT_CPU_FREQ/1000000));
        printf("while(4000)= %ld us\n",(t45-t44)/(ALT_CPU_FREQ/1000000));
        printf("while(7000)= %ld us\n",(t46-t45)/(ALT_CPU_FREQ/1000000));  
        printf("while(10000)= %ld us\n",(t47-t46)/(ALT_CPU_FREQ/1000000));
        printf("while(40000)= %ld us\n",(t48-t47)/(ALT_CPU_FREQ/1000000));
        printf("while(70000)= %ld us\n",(t49-t48)/(ALT_CPU_FREQ/1000000));
        printf("while(100000)= %ld us\n",(t50-t49)/(ALT_CPU_FREQ/1000000));
    }
    return 0; 
    
}
 
运行结果如下:

系统时钟频率是 50000000 Hz

usleep(1)= 42 us
usleep(4)= 38 us
usleep(7)= 40 us
usleep(10)= 44 us
usleep(40)= 72 us
usleep(70)= 102 us
usleep(100)= 130 us
usleep(400)= 418 us
usleep(700)= 706 us
usleep(1000)= 994 us
usleep(4000)= 3874 us
usleep(7000)= 6754 us
usleep(10000)= 9634 us
usleep(40000)= 38435 us
usleep(70000)= 67234 us
usleep(100000)= 96035 us

for(1)= 9 us
for(4)= 11 us
for(7)= 15 us
for(10)= 18 us
for(40)= 53 us
for(70)= 87 us
for(100)= 122 us
for(400)= 465 us
for(700)= 809 us
for(1000)= 226971 us
for(4000)= 0 us
for(7000)= 8018 us
for(10000)= 11452 us
for(40000)= 45782 us
for(70000)= 80115 us
for(100000)= 114447 us

while(1)= 7 us
while(4)= 10 us
while(7)= 11 us
while(10)= 14 us
while(40)= 35 us
while(70)= 58 us
while(100)= 79 us
while(400)= 298 us
while(700)= 516 us
while(1000)= 734 us
while(4000)= 2916 us
while(7000)= 5099 us
while(10000)= 7281 us
while(40000)= 29104 us
while(70000)= 50927 us
while(100000)= 72751 us

在ALT_CPU_FREQ处右击,选中Open Declaration,可以找到ALT_CPU_FREQ在system.h中的定义。其值与函数alt_timestamp_freq()返回的值相同,都是在SOPC中设置的。如图5所示。

图5 系统时钟设置
分析得知, 100us以下用while较准确, 100us以上用usleep。
补充:
1、 要在SOPC中加入Interval Timer,并在Nios II中”system library properties”中的”system library”中,为timestamp timer指定物理设备,即在SOPCBuilder中添加的timer。否则出现如下错误。

 
2、 如果没有头文件alt_types.h,会出现如下警告。


3、(2011.5.31)

在调试好延时函数之后,要将红圈处System Library Properties-> system library->Timestamp timer设置成none。本人就是遇到问题,比如最简单的LED跑马灯,同样的ptf和Nios II程序,之前做的可以运行。设置timer之后,实验没有现象,也没有提示错误,过了很久才找到的问题产生的原因。
4、(2011.6.15)对于时序比较复杂要求严格的控制,比如DS18B20,不适用于Nios II完全控制它的操作。先用硬件逻辑实现,再用Nios II读取温度数据的办法较好。

Nios II 系统时钟timestamp的应用的更多相关文章

  1. Nios II系统在Quartus II编译后Timing requirements for slow timing model timing analysis were not met. See Report window for details

    来自http://wenku.baidu.com/link?url=h0Z_KvXD3vRAn9H8mjfbVErVOF_Kd3h-BZSyF1r4sEYj3ydJGEfBHGY1mvntP4HDuF ...

  2. 关于Nios II的启动分析(转载)

    原文地址:http://hi.baidu.com/goatdai/item/cc33671545d89243e75e06ad 常用到的存储器包括SDRMA.SRAM.FLASH.Onchip_memo ...

  3. NIOS II CPU复位异常的原因及解决方案

    NIOS II CPU复位异常的原因及解决方案   近期在用nios ii做项目时,发现一个奇怪的现象,在NIOS II EDS软件中编写好的代码,烧写到芯片中,第一次能够正常运行,但是当我按下板卡上 ...

  4. Nios II的Boot过程分析

    目录 1       概述....................................................................... 1 2       几种常见的 ...

  5. 解决NIOS II工程移动在磁盘上位置后project无法编译问题

    说明:本文档于2017年3月4日由小梅哥更新部分内容,主要是增加了讲解以Quartus II13.0为代表的经典版本和以15.1为代表的更新版本之间,解决问题的一些小的差异. 如果用户只是想快速解决问 ...

  6. 【小梅哥SOPC学习笔记】NIOS II工程目录改变时project无法编译问题

    解决NIOS II工程移动在磁盘上位置后project无法编译问题 说明:本文档于2017年3月4日由小梅哥更新部分内容,主要是增加了讲解以Quartus II13.0为代表的经典版本和以15.1为代 ...

  7. 在WIN7系统下用Quartus ii 11.1 NIOS II 11.1 有时候会出现Nios II 的Run as hardware 中报错:Downloading ELF Process failed

    nios工程在编译通过后RUN的过程中出现Error Running Nios II Project: ‘Downloading ELF Process failed’问题原因: 1.nios2 cp ...

  8. 初探NIOS II之hello_world

    平台背景: 操作系统:win7  64bit 开发板:DE2-115 Quartus ii:15.0及配套的NIOS ii开发平台 一.硬件系统的建立 1.在Quartus里新建工程,这是很基本的就不 ...

  9. 给NIOS II CPU增加看门狗定时器并使用

    给NIOS II CPU增加看门狗定时器并使用   配置看门狗定时器: 设置计时溢出时间为1秒 计数器位宽为32位 勾选No Start/Stop control bits 勾选Fixed perio ...

随机推荐

  1. HDFS架构与原理

    HDFS HDFS 全称hadoop分布式文件系统,其最主要的作用是作为 Hadoop 生态中各系统的存储服务 特点 优点 • 高容错.高可用.高扩展 -数据冗余多副本,副本丢失后自动恢复 -Name ...

  2. Vue中如何监控某个属性值的变化?

    比如现在需要监控data中, obj.a 的变化.Vue中监控对象属性的变化你可以这样: deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改: 还有一种 ...

  3. Linux/UNIX线程(1)

    线程(1) 本文将介绍怎样使用多个控制线程在单个进程环境中运行多个任务. 一个进程中的全部线程都能够訪问该进程的组成部件(如文件描写叙述符和内存). 线程包含了表示进程内运行环境必须的信息,当中包含进 ...

  4. Android--Fragment与Activity通信

    package com.example.testfragment; import com.example.testfragment.MainFargment.BackString; import an ...

  5. Python语法篇:

    - 基础篇: - 介绍 - 下载安装以及PyCharm安装 - 变量 - 数据类型 - 列表,元组,字典,集合 - 函数 - 内置函数 - 生成器,迭代器,装饰器 - 面向对象: - 面向对象简介: ...

  6. CSS之基于不同场景的垂直居中解决方案

    元素的水平居中,如果是一个行内元素,就对它的父元素应用 “text-align:center”: 如果是一个块级元素,就对它自身应用“margin:auto”. 垂直居中的几种场景以及实现方法: 一. ...

  7. 让IE9以下版本的浏览支持html5,CSS3的插件

    随着html5(后面用h5代表)标签越来越广泛的使用,IE9以下(IE6-IE8)不识别h5标签的问题让人很是烦恼. 在火狐和chrome之类的浏览器中,遇到不认识的标签,只要给个display:bl ...

  8. 使用物化视图解决GoldenGate不能使用中文表名问题

    源端: conn sh/sh create table "学生" ("学号" number primary key,"姓名" varchar ...

  9. Goldengate进程的合并与拆分规范

    Goldengate抽取进程的合并与拆分原则 1.    文档综述 1.1.  文档说明 本文档描述了对GoldenGate的抽取进程进行拆分和合并的基本原则和详细步骤.  1.2.  读者范围 本文 ...

  10. NodeJS学习笔记 进阶 (2)Nodejs进阶:MD5加密算法(ok)

    个人总结:这篇文章讲解了Nodejs中自带模块的MD5加密算法的使用,读完这篇文章需要15分钟,其实还有一个叫utility的包在npm上,也非常好用. 摘选自网络 简介 MD5(Message-Di ...