脉冲计数功能在ESM335x-Linux主板上的实现
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主板上的实现的更多相关文章
- 用shell脚本实现linux系统上wifi模式(STA和soft AP)的转换
转载请注明出处:http://blog.csdn.net/hellomxj1/ 功能:在linux系统上实现wifi STA与AP功能的转换 实现成果:1.加入wifipassword账户add_wi ...
- ESM335x Linux输出脉冲计数
1.综述 ESM335X具有4路PWM输出,其中PWM1和PWM2除了可以用于产生标准的PWM信号,现已支持输出脉冲计数功能,可以在应用程序中设置脉冲个 数,当输出脉冲个数达到指定值时,驱动程序自 ...
- stm32定时器计数功能
stm32的外部时钟源模式2和外部时钟源模式1都可以用来实现计数功能,他们的区别是什么呢? 以上2种模式对应不同的管脚输入: 外部时钟源模式2 <-->TIMx_ETR 外部时钟源模式1 ...
- Linux服务器上监控网络带宽的18个常用命令
[51CTO精选译文]本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量分开来显示. 一些命令可以 ...
- Linux服务器上监控网络带宽的18个常用命令(转)
本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量分开来显示. 一些命令可以显示单个进程所使用的带 ...
- [转]Linux Ubuntu上架设FTP
Linux Ubuntu上架设FTP http://www.blogjava.net/stonestyle/articles/369104.html 操作系统:ubuntu (GNU/Linux) 为 ...
- (转)推荐一个在Linux/Unix上架设ASP.NET的 WEB服务器--Jexus
在Linux/Unix上架设ASP.NET WEB服务器,有两个可选方式,一种是Mono+XSP,一种是Mono+Jexus,其它的方式,比如 Apache+mod_mono.Nginx+FastCg ...
- 在linux服务器上发布web应用的完整过程
首先你要有一个完整的web应用的小Demo,一个简单的demo就可以了,但是要涉及到数据库,笔者这里简单的模拟一个登陆的过程. 在本地测试,访问项目: 键入账号密码,点击登陆: 就是这么个简单的动作, ...
- Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务
一.引言 今天本来没有打算写这篇文章,当初我感觉使用这个工具应该很简单,下载的过程也不复杂,也没有打算记录下来.但是在使用的过程中还是出现了一些问题,为了给第一次使用Redis Desktop Man ...
随机推荐
- 通过类名获取spring里的Bean
import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactor ...
- c#-基础:类的进阶
类的概述: 类是一个能存储数据并执行代码的数据结构 数据成员:通常模拟该类所表示显示世界的事物特性 函数成员:执行代码.模拟显示世界事物的功能和操作 数据成员:字段,常量 函数成员执行代码:方法 运算 ...
- ThinkPHP单字母函数(快捷方法)使用总结
在ThinkPHP中有许多使用简便的单字母函数(即快捷方法),可以很方便开发者快速的调用,但是字母函数却不方便记忆,本文将所有的字母函数总结一下,以方便以后查找. 1.U() URL组装 支持不同UR ...
- cakephp 打印出SQL语句
最近一直在使用cakephp这个框架学习,最近发现了一些问题,就是怎样将SQL语句打印出来进行调试,方法如下: $db=ConnectionManager::getDataSource('defaul ...
- MSSQL日志传送出现“LSN 太晚,无法应用到数据库”
一个月之前配置了日志传送的数据库,在今天早上收到作业警报:"LSRestore_ServerName_Databasename"运行失败,到历史记录中查看,错误信息如下 消息 20 ...
- ToolStrip控件在窗体没有焦点的情况下,需要单击二次才能够激发事件的解决办法
protected override void WndProc(ref Message m) { if (m.Msg == 0x210) { Control control = Control.Fro ...
- SRM 146 DIV1 800
Problem Statement The purpose of a roundabout is to control the flow of traffic at a busy inter ...
- poj1068
Parencodings Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18785 Accepted: 11320 De ...
- DNS初识
/注释----本文大部分内容来自网络/ 一.定义: DNS 是域名系统 (Domain Name System) 的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库, ...
- 批量部署ssh信任关系
要求1:大批量部署SSH信任关系,在A文件分发服务器上大批量部署WEB层面信任关系文件分发服务器为:10.0.3.9 登录用户为:zhangsan WEB层IP段:10.0.3.10~10.0.3.6 ...