脉冲计数功能在ESM335x-Linux主板上的实现

时间:2022-06-21 23:34:43

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头文件中。

脉冲计数功能在ESM335x-Linux主板上的实现

  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函数传递相同参数清零硬件保存值。

脉冲计数功能在ESM335x-Linux主板上的实现

  4、实验测量

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

脉冲计数功能在ESM335x-Linux主板上的实现

脉冲计数功能在ESM335x-Linux主板上的实现

  频率测量(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个常用命令&lpar;转&rpar;

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

  6. &lbrack;转&rsqb;Linux Ubuntu上架设FTP

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

  7. &lpar;转&rpar;推荐一个在Linux&sol;Unix上架设ASP&period;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. java 调用axis2 webservice

    import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apach ...

  2. 连接池 druid&lpar;阿里巴巴的框架&rpar;

      引用自:http://blog.163.com/hongwei_benbear/blog/static/1183952912013518405588/ 说的是现在最好的连接池   注: 属性跟 d ...

  3. IOS 的loadView 及使用loadView中初始化View注意的问题。(死循环并不可怕)

    在XCode 4.2后,我基本上的应用都不使用Xib文件了,虽然xib文件有很多好趣,可以快速免代码构建视窗,可以减少好多代码构建带来的麻烦,其实能用xib还是不错的,主要是我的机器打开xib来编辑时 ...

  4. 从源码看 angular&sol;material2 中 dialog模块 的实现

    本文将探讨material2中popup弹窗即其Dialog模块的实现. 使用方法 引入弹窗模块 自己准备作为模板的弹窗内容组件 在需要使用的组件内注入 MatDialog 服务 调用 open 方法 ...

  5. Starting MySQL&period;&period;&period;&period;The server quit without updating PID file&lbrack;失败&rsqb;&sol;lib&sol;mysql&sol;ip12189&period;pid&rpar;&period; 错误一例

    [root@ip12189 etc]# service mysqld startStarting MySQL....The server quit without updating PID file[ ...

  6. C&num; EditPlus环境设置

    C# EditPlus环境设置 先要设置环境变量   5.0的 C:\Program Files\MSBuild\12.0\Bin 6.0的  C:\Windows\Microsoft.NET\Fra ...

  7. Java如何暂停线程一段时间?

    在Java编程中,如何暂停线程一段时间? 以下示例显示如何通过创建sleepThread()方法来暂停线程一段时间. package com.yiibai; public class Suspendi ...

  8. 【C】常用的字符串函数

    1. strcpy 函数名:strcpy 用法:char *strcpy(char *destin, char *cource) 功能:将一个字符串从一个拷贝到另外一个 程序示例: #include ...

  9. fb登陆遇到傻逼问题

    centos中curl需要ssl的支持, 所以我重新安装了curl,并安装了openssl-devel,这个是依赖,必须的. so 完美

  10. Django学习笔记之uWSGI详解

    WSGI是什么? WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义 ...