• Nios II 系统时钟timestamp的应用


    在用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 ");
        }
        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 ", freq);   //freq可以写成ALT_CPU_FREQ
            printf(" ");
            printf("usleep(1)= %ld us ",(t1-t0)/(ALT_CPU_FREQ/1000000));  
            printf("usleep(4)= %ld us ",(t2-t1)/(ALT_CPU_FREQ/1000000));
            printf("usleep(7)= %ld us ",(t3-t2)/(ALT_CPU_FREQ/1000000));
            printf("usleep(10)= %ld us ",(t4-t3)/(ALT_CPU_FREQ/1000000));
            printf("usleep(40)= %ld us ",(t5-t4)/(ALT_CPU_FREQ/1000000));
            printf("usleep(70)= %ld us ",(t6-t5)/(ALT_CPU_FREQ/1000000));  
            printf("usleep(100)= %ld us ",(t7-t6)/(ALT_CPU_FREQ/1000000));
            printf("usleep(400)= %ld us ",(t8-t7)/(ALT_CPU_FREQ/1000000));
            printf("usleep(700)= %ld us ",(t9-t8)/(ALT_CPU_FREQ/1000000));  
            printf("usleep(1000)= %ld us ",(t10-t9)/(ALT_CPU_FREQ/1000000));
            printf("usleep(4000)= %ld us ",(t11-t10)/(ALT_CPU_FREQ/1000000));
            printf("usleep(7000)= %ld us ",(t12-t11)/(ALT_CPU_FREQ/1000000));  
            printf("usleep(10000)= %ld us ",(t13-t12)/(ALT_CPU_FREQ/1000000));
            printf("usleep(40000)= %ld us ",(t14-t13)/(ALT_CPU_FREQ/1000000));
            printf("usleep(70000)= %ld us ",(t15-t14)/(ALT_CPU_FREQ/1000000));
            printf("usleep(100000)= %ld us ",(t16-t15)/(ALT_CPU_FREQ/1000000));
            printf(" ");
            printf("for(1)= %ld us ",(t18-t17)/(ALT_CPU_FREQ/1000000));  
            printf("for(4)= %ld us ",(t19-t18)/(ALT_CPU_FREQ/1000000));
            printf("for(7)= %ld us ",(t20-t19)/(ALT_CPU_FREQ/1000000));
            printf("for(10)= %ld us ",(t21-t20)/(ALT_CPU_FREQ/1000000));
            printf("for(40)= %ld us ",(t22-t21)/(ALT_CPU_FREQ/1000000));
            printf("for(70)= %ld us ",(t23-t22)/(ALT_CPU_FREQ/1000000));  
            printf("for(100)= %ld us ",(t24-t23)/(ALT_CPU_FREQ/1000000));
            printf("for(400)= %ld us ",(t25-t24)/(ALT_CPU_FREQ/1000000));
            printf("for(700)= %ld us ",(t26-t25)/(ALT_CPU_FREQ/1000000));  
            printf("for(1000)= %ld us ",(t27-t6)/(ALT_CPU_FREQ/1000000));
            printf("for(4000)= %ld us ",(t27-t27)/(ALT_CPU_FREQ/1000000));
            printf("for(7000)= %ld us ",(t29-t28)/(ALT_CPU_FREQ/1000000));  
            printf("for(10000)= %ld us ",(t30-t29)/(ALT_CPU_FREQ/1000000));
            printf("for(40000)= %ld us ",(t31-t30)/(ALT_CPU_FREQ/1000000));
            printf("for(70000)= %ld us ",(t32-t31)/(ALT_CPU_FREQ/1000000));
            printf("for(100000)= %ld us ",(t33-t32)/(ALT_CPU_FREQ/1000000));
            printf(" ");
            printf("while(1)= %ld us ",(t35-t34)/(ALT_CPU_FREQ/1000000));  
            printf("while(4)= %ld us ",(t36-t35)/(ALT_CPU_FREQ/1000000));
            printf("while(7)= %ld us ",(t37-t36)/(ALT_CPU_FREQ/1000000));
            printf("while(10)= %ld us ",(t38-t37)/(ALT_CPU_FREQ/1000000));
            printf("while(40)= %ld us ",(t39-t38)/(ALT_CPU_FREQ/1000000));
            printf("while(70)= %ld us ",(t40-t39)/(ALT_CPU_FREQ/1000000));  
            printf("while(100)= %ld us ",(t41-t40)/(ALT_CPU_FREQ/1000000));
            printf("while(400)= %ld us ",(t42-t41)/(ALT_CPU_FREQ/1000000));
            printf("while(700)= %ld us ",(t43-t42)/(ALT_CPU_FREQ/1000000));  
            printf("while(1000)= %ld us ",(t44-t43)/(ALT_CPU_FREQ/1000000));
            printf("while(4000)= %ld us ",(t45-t44)/(ALT_CPU_FREQ/1000000));
            printf("while(7000)= %ld us ",(t46-t45)/(ALT_CPU_FREQ/1000000));  
            printf("while(10000)= %ld us ",(t47-t46)/(ALT_CPU_FREQ/1000000));
            printf("while(40000)= %ld us ",(t48-t47)/(ALT_CPU_FREQ/1000000));
            printf("while(70000)= %ld us ",(t49-t48)/(ALT_CPU_FREQ/1000000));
            printf("while(100000)= %ld us ",(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读取温度数据的办法较好。
  • 相关阅读:
    用CSV文件读写数据的两种方式(转)
    利用PHP生成二维码(转)
    PHP实现微博的同步发送(转)
    php实现网页标签补全方法(转)
    php 下载远程图片 的几种方法(转)
    Masonry+Infinite-Scroll实现无刷新无分页完美瀑布流(转)
    分享一个jQuery动态网格布局插件:Masonry(转)
    js判断图片是否显示
    PHP写入文件用file_put_contents代替fwrite优点多多(转)
    PHP 更高效的字符长度判断方法(转)
  • 原文地址:https://www.cnblogs.com/lueguo/p/3414842.html
Copyright © 2020-2023  润新知