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