ESM7000是支持正版WEC7 / Linux的双核Cortex-A7工业级工控主板,支持双网口、双CAN、6路串口、触摸屏显示接口等,广泛应用于工控智能终端设备。根据客户的应用需求,我们为ESM7000增加了输入脉冲计数功能,支持对几赫兹到数十兆赫兹的输入脉冲信号进行准确计数,实现脉冲数量统计,脉冲频率换算功能。
ESM7000 WinCE / Linux工控主板
对于低频脉冲信号计数,可通过简单的GPIO中断来实现。当输入脉冲频率超过数千赫兹时,频繁的GPIO中断会降低系统性能,并存在丢数风险,所以对高速脉冲计数通常需要专门的硬件来实现。
ESM7000主CPU为NXP的i.MX7D,我们利用了i.MX7D的通常定时器(GPT)的Capture功能来实现对高速脉冲的硬件计数。脉冲计数涉及到两个输入信号:1)被测信号——脉冲信号输入;2)测量周期控制信号——用于触发CPU Capture功能实现计数捕捉。
ESM7000脉冲计数功能对应的GPIO如下所示:
ESM7000 Pin | ESM7000 GPIO | 功能说明 |
D9 | GPIO8 | 测量周期控制信号输出 |
D10 | GPIO9 | 测量周期控制信号输入 |
D15 | GPIO14 | 脉冲信号输入 |
测量周期控制信号由驱动程序从GPIO8输出,所以实际应用时,需要将GPIO8与GPIO9短接(建议使用0R电阻短接)。GPIO14为被测脉冲信号输入,需要注意输入信号电平不能直接3.3V,否则必须通过电平转换后才能接入。
ESM7000脉冲计数功能的设备驱动名为“CNT1:”,ESM7000所有GPIO在系统上电后的缺省状态为GPIO输入上拉,打开“CNT1:”后,GPIO8,GPIO9, GPIO14会自动切换为脉冲计数功能引脚。
在应用程序中设置测量周期后,驱动程序就开始对输入脉冲连续计数,DeviceIoControl会在每个测量周期自动返回,并运回脉冲计数值。
完整的应用程序代码如下:
#include "stdafx.h" #include <winioctl.h> #include "bsp_drivers.h" BOOL bThreadStop = FALSE; DWORD dwCountingPeriod; DWORD max = 0, min = 0xffffffff; DWORD WINAPI CntThread(PVOID pArg) { BOOL bRet; DWORD dwTimeout; DWORD dwCount; HANDLE hCnt; hCnt = (HANDLE)pArg; dwTimeout = INFINITE; while (!bThreadStop) { // 等待获取脉冲计数值 bRet = DeviceIoControl(hCnt, // file handle to the driver IOCTL_WAIT_FOR_EVENT, // I/O control code NULL, // in buffer 0, // in buffer size &dwCount, // out buffer sizeof(DWORD), // out buffer size NULL, // pointer to number of bytes returned NULL); // ignored (=NULL) if(bRet) { if(dwCount > max){ max = dwCount; if(min != 0xffffffff) printf("max:%d min:%d Frequency:%.2fKHz\r\n", max, min, (float)dwCount/(float)dwCountingPeriod); } if(dwCount < min){ min = dwCount; printf("max:%d min:%d Frequency:%.2fKHz\r\n", max, min, (float)dwCount/(float)dwCountingPeriod); } } } return 0; } int _tmain(int argc, _TCHAR* argv[]) { int num = 10; HANDLE hCnt = CreateFile(L"CNT1:", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); HANDLE hThread = CreateThread(NULL, 0, CntThread, (LPVOID)hCnt, 0, NULL); // 配置并启动计数 dwCountingPeriod = 1000; // 计数周期,单位毫秒(可设置范围1ms ~ 1000ms) DeviceIoControl(hCnt, // file handle to the driver IOCTL_GENERIC_START, // I/O control code &dwCountingPeriod, // in buffer sizeof(DWORD), // in buffer size NULL, // out buffer 0, // out buffer size NULL, // pointer to number of bytes returned NULL); while(num--) { Sleep(1000); } /* 可调用IOCTL_GENERIC_STOP临时停止计数,调用IOCTL_GENERIC_SETUP再次开始计数 */ DeviceIoControl(hCnt, IOCTL_GENERIC_STOP, NULL, 0, NULL, 0, NULL, NULL); bThreadStop = TRUE; CloseHandle(hThread); CloseHandle(hCnt); return 0; }
成都英创信息技术有限公司 028-8618 0660