1、综述

  在工业控制中,经常需要获取脉冲信号计数值、频率、周期、占空比等参数。英创嵌入式主板ESM335X系列 Linux系统现已实现外部输入脉冲信号的计数、频率、周期、占空比测量功能。

  主要功能及技术指标如下:

  1、读取一段时间内的外部输入脉冲信号计数值。

  2、外部输入脉冲信号周期、有效脉宽测量。

  3、根据测得周期计算外部输入脉冲信号瞬时频率。

  4、根据测得计数值和测量时间间隔计算两次有效信号读取时间内外部输入脉冲信号重复频率(平均频率)。

  5、测得误差200KHz左右时最大,瞬时频率误差不超过0.1%,重复频率误差不超过0.005%,占空比误差不超过0.05%,计数值测量准确无误差。

2、硬件连接

  ESM335X 系列嵌入式主板引出了3路PWM输出,其中两路(PWM1和PWM2)可以用来进行外界输入的脉冲信号计数、频率、占空比测量,相应的GPIO复用脚为 GPIO6和GPIO7, 对应的引脚请参考光盘资料《ESMARC 335x工控主板数据手册》,用户使用脉冲波输入计数功能时可将外来信号接到上述两个GPIO管脚中的任意一个,并且地线与开发板接地引脚相连,然后在应 用程序中获得计数值、频率、占空比。若用户启用了脉冲输入计数功能,则相应管脚不能再作为PWM脉冲输出或GPIO使用。

  使用注意事项:

  1、GPIO管脚最大只允许输入3.3V电压,超过将会导致开发板损坏!以开发板接地脚为基准,负值电压无效,不符合电压要求时需要设计缓冲放大电路。

  2、输入脉冲波最大频率不应超过200KHz!超过之后由于硬件限制测量误差将急剧变大。

3、应用程序

  为了简化用户使用脉冲计数功能,内部使用了原pwm输出模块,Linux系统内部没有增加新的设备节点,使用设备的计数功能(capture模式,后文简称cap),仍然需要使用pwm模式的设备节点进行模块功能设置。

  (1)程序中使用到的结构体及常量定义

  与内核直接交换数据读取设备原始测量值的结构体为cap_config_info,应用于read、write函数:

  typedef struct cap_config_info

  {

  // 以下为输入参数

  unsigned intdwPolarity; // 设置输入信号极性

  unsigned intdwMaxFreq; // 设置输入信号最大频率

  // 以下为输出参数,输入无效

  unsigned longdwTimeUs; // 两次读取之间的时间差

  unsigned intdwCount; // 两次读取之间的计数值

  unsigned intdwPeriodNs; // 读取时刻脉冲周期

  unsigned intdwWidthNs; // 读取时刻的脉冲有效脉宽

  }CAP_INFO, *PCAP_INFO;

  1、dwPolarity用于设置输入脉冲信号极性,可设为PWM_POLARITY_NORMAL和PWM_POLARITY_INVERTED,定义在pwm_api.h头文件中。

  2、dwMaxFreq等于0时用于停止计数功能,dwMaxFreq不为零时用于设置输入信号最大频率,最大频率不应超过200KHz,输入单位为Hz。

  3、dwTimeUs为输出参数,读取获得上次读操作(或使能操作)到本次读操作之间的时间差,单位为us。

  4、dwCount为输出参数,读取获得上次读操作(或使能操作)到本次读操作之间的计数值,单位为 个。

  5、dwPeriodNs为输出参数,读取获得本次读操作时脉冲信号周期, 单位为ns。

  6、dwWidthNs为输出参数,读取获得本次读操作时脉冲信号有效脉冲宽度,单位为ns。

  7、用户可根据dwPeriodNs和dwWidthNs计算占空比。

  8、用户可根据dwPeriodNs计算读操作时的脉冲信号频率。

  9、用户可根据dwTimeUs和dwCount计算两次读操作之间的输入信号的平均频率。

  (2)函数及系统调用

  在进行计数操作时,首先打开相应的设备节点/dev/em335x_pwmX,X为编号(1或者2),使能设备开始计数相关代码:

  a) 打开设备节点:

  intnpwm = 1;

  sprintf( device, "/dev/em335x_pwm%d", npwm );

  fd = open(device, O_RDWR);

  if ( fd < 0)

  {

    printf("can not open /dev/em335x_pwm%d device file!\n", npwm);

    return -1;

  }

  printf( "Open %s\n", device );

  b) 使能cap模式:

  int CAP_Start(int fd, unsigned int polarity, unsigned int maxfreq )

  {

    int rc;

    struct cap_config_infoconf;

    memset(&conf, 0 ,sizeof(struct cap_config_info))

    conf.dwPolarity = polarity;

    conf.dwMaxFreq = maxfreq;

    rc = write(fd, &conf, sizeof(struct cap_config_info));

    if ( rc == 0 )

      return rc;

    else

    {

      printf( " config for cap model failed!\n");

      exit(1);

    }

  }

  用户只需要调用此函数即可使能脉冲信号计数功能,并且计数功能开始计数。也可自己设置参数调用write使能cap模式。如:

  #include "pwm_api.h"

  unsigned intpolarity = PWM_POLARITY_NORMAL;

  unsigned intmaxfreq = 200000000;

  CAP_Start( fd, polarity, maxfreq );

  c) 在计数过程中可以调用read函数或者我们提供的CAP_Read函数读取测量数值:

  int CAP_Read(int fd, struct cap_config_info* conf )

  {

    printf ( "reading^^^^^^^\n" );

    int rc;

    rc = read(fd, conf, sizeof(struct cap_config_info));

    return rc;

  }

  用户可根据自己需要在任意时刻选择调用此函数或者直接调运read获取测量值。

  根据测量值可以计算脉冲频率并转换单位,注意测得dwCount小于2时其他参数均无效:

  doublePeriodUs; // 单位us

  doubleWidthUs; // 单位us

  doubleDuty; // 单位%

  intCount; // 个数

  doubleFreq; // 单位Hz

  doubleAVGFreq; // 单位Hz

  unsigned int TimeUs; // 单位us

  CAP_Read ( fd, &conf );

  Count = conf.dwCount;

  if(Count>1)

  {

    PeriodUs = (double)conf.dwPeriodNs/1000.0; // 单位转换

    WidthUs = (double)conf.dwWidthNs/1000.0;

    Duty = (double)conf.dwWidthNs*100000.0/conf.dwPeriodNs;

    Freq = CAP_CLK_FREQ/(double)conf.dwPeriodNs;

    AVGFreq = (double)conf.dwCount*CAP_CLK_FREQ/(double)conf.dwTimeUs;

  }

  else

  {

    PeriodUs = 0;

    WidthUs = 0;

    Duty = 0;

    Freq = 0;

    AVGFreq = 0;

  }

  d) 使用完成后需要关闭计数功能,同样可以自行设置参数调用write或者使用CAP_Stop,也可以直接使用close关闭设备节点同事停止使用计数功能:

  int CAP_Stop(int fd )

  {

    printf ( "stopping^^^^^^^\n" );

    int rc;

    struct cap_config_infoconf;

    memset( &conf, 0, sizeof(struct pwm_config_info));

    conf.dwMaxFreq = 0;

    rc = write(fd, &conf, sizeof(struct cap_config_info));

    return rc;

  }

  调用上述函数:

  CAP_Stop( fd);

  使用完成后需要关闭设备节点。

  close(fd);

  e) 触发机制(选读):

   如下图所示,在每一次上升沿或者下降沿处会触发硬件捕获功能,获得输入脉冲信号的参数并保存,应用程序中在任意时刻调用读操作得到的数据是最近一次上升 沿或下降沿处的数据。此图中调用read1一之后调用read2,得到的计数值为2,时间差为(硬件触发2-硬件触发1)的时间差。用户使用时请注意输入 信号有效时间段。所得时间不能作为两次读操作之间的时间差使用。如果要将读取的时间值作为两次读操作的时间值需要在前一次读操作后调用CAP_Start 或直接用write函数传递相同参数清零硬件保存值。

  4、实验测量

  由 于硬件的限制,测得瞬时频率、周期、占空比精度有限。硬件操作使用的时钟信号为100MHz,即周期、有效脉宽时间只能得到高于10ns的数值。平均频率 的测量需要保证整个测量时间段内输入脉冲信号一直有脉冲输入!平均频率的误差整个测量范围内不超过10Hz。实验使用RIGOL DG1022 信号发生器作为外部脉冲信号源,可以调整信号周期占空比,设置一定时间内的脉冲个数。

  频率测量(kHz):

输入 200.000 197.000 97.000 1.020
瞬间频率 200.000 196.850 96.993 1.020
平均频率 199.992 196.992 96.998 1.020

测得瞬时数据误差随频率增加而变大,具体数据可根据测量时间最小值10NS进行计算。

  在150KHz时测量的不同占空比值如下表:

输入% 90.00 50.00 20.00 10.00
测得% 89.96 50.00 19.97 9.91

  在100KHz时测量的不同占空比值如下表:

输入% 90.00 50.00 20.00 10.00
测得% 90.00 50.00 20.00 10.00

  在100KHz时连续测量的1S内脉冲个数如下表(信号源输入个数设置模式上限50K个,通过设置信号源取不同输入值):

输入% 39 999 23 338 8 766 432
测得% 39 999 23 338 8 766 432

注:当频率升高时,系统高负荷运转,实际读取时间差变化加大,如果连续读取,读到的计数值要以读到的时间差为准进行数值判断,实际读取个数并无误差。

  计数值在允许输入频率内无误差。

脉冲计数功能在ESM335x-Linux主板上的实现的更多相关文章

  1. 用shell脚本实现linux系统上wifi模式(STA和soft AP)的转换

    转载请注明出处:http://blog.csdn.net/hellomxj1/ 功能:在linux系统上实现wifi STA与AP功能的转换 实现成果:1.加入wifipassword账户add_wi ...

  2. ESM335x Linux输出脉冲计数

    1.综述   ESM335X具有4路PWM输出,其中PWM1和PWM2除了可以用于产生标准的PWM信号,现已支持输出脉冲计数功能,可以在应用程序中设置脉冲个 数,当输出脉冲个数达到指定值时,驱动程序自 ...

  3. stm32定时器计数功能

    stm32的外部时钟源模式2和外部时钟源模式1都可以用来实现计数功能,他们的区别是什么呢? 以上2种模式对应不同的管脚输入: 外部时钟源模式2 <-->TIMx_ETR 外部时钟源模式1  ...

  4. Linux服务器上监控网络带宽的18个常用命令

    [51CTO精选译文]本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量分开来显示. 一些命令可以 ...

  5. Linux服务器上监控网络带宽的18个常用命令(转)

    本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量分开来显示. 一些命令可以显示单个进程所使用的带 ...

  6. [转]Linux Ubuntu上架设FTP

    Linux Ubuntu上架设FTP http://www.blogjava.net/stonestyle/articles/369104.html 操作系统:ubuntu (GNU/Linux) 为 ...

  7. (转)推荐一个在Linux/Unix上架设ASP.NET的 WEB服务器--Jexus

    在Linux/Unix上架设ASP.NET WEB服务器,有两个可选方式,一种是Mono+XSP,一种是Mono+Jexus,其它的方式,比如 Apache+mod_mono.Nginx+FastCg ...

  8. 在linux服务器上发布web应用的完整过程

    首先你要有一个完整的web应用的小Demo,一个简单的demo就可以了,但是要涉及到数据库,笔者这里简单的模拟一个登陆的过程. 在本地测试,访问项目: 键入账号密码,点击登陆: 就是这么个简单的动作, ...

  9. Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务

    一.引言 今天本来没有打算写这篇文章,当初我感觉使用这个工具应该很简单,下载的过程也不复杂,也没有打算记录下来.但是在使用的过程中还是出现了一些问题,为了给第一次使用Redis Desktop Man ...

随机推荐

  1. 第四章ppt课后作业

    字符串加密解密: 源代码: package tutorial04String; import javax.swing.JOptionPane; public class Wordsecret { pu ...

  2. 『c++』 模板(template)--- 参数化多态性

    ---恢复内容开始--- 题外话: 模板机制的设计和细节是由Bjarne Stroustrup在其1988年10月发表的名为“Parameterized Types for C++”一文中披露的. 引 ...

  3. c#-基础:类的进阶

    类的概述: 类是一个能存储数据并执行代码的数据结构 数据成员:通常模拟该类所表示显示世界的事物特性 函数成员:执行代码.模拟显示世界事物的功能和操作 数据成员:字段,常量 函数成员执行代码:方法 运算 ...

  4. [MAC]2015款MACBOOK使用BOOTCAMP安装WIN8.1+多分区

    注意事项: 2013年以前,带光驱的,请使用WinClone安装WIN7或WIN8,或可使用BOOTCAMP制作WINDOWS安装光盘 13-14年,不带光驱的,也能使用WinClone安装WIN7和 ...

  5. Oracle中SYS_CONNECT_BY_PATH函数的使用

    在Oracle中,SYS_CONNECT_BY_PATH函数主要作用是可以把一个父节点下的所有子节点通过某个字符进行区分,然后连接在一个列中显示. sys_connect_by_path(字段名, 2 ...

  6. ubuntu 14.04 重复登录问题解决方法

    为了远程登录,装了xubunt后出现重复登录的问题,尝试了多种方法,后来用下面的命令解决了 chown username:username .Xauthority 参考资料:http://askubu ...

  7. 操作素有的ul的元素

    1 $(function() { var all = $(".test"); $(".test").each(function() { var y = $(th ...

  8. 重写form 表单的验证信息

    (function($) { var isformValidationPostBack=true; var isformValidation = false; $.extend({ formValid ...

  9. Device eth0 does not seem to be present, delaying initialization. 问题

    今天在复制vmware的时候 出现网卡无法启动 报错显示 Device eth0 does not seem to be present, delaying initialization. 这个错误原 ...

  10. Wordpress上传到阿里云服务器

    Wordpress上传到阿里云服务器 登录服务器 https://account.aliyun.com/login/login.htm 绑定域名 获取FTP信息.数据库信息 在本地修改wordpres ...