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! ", npwm);
return -1;
}
printf( "Open %s ", 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! ");
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^^^^^^^ " );
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^^^^^^^ " );
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 |
注:當頻率升高時,系統高負荷運轉,實際讀取時間差變化加大,如果連續讀取,讀到的計數值要以讀到的時間差為準進行數值判斷,實際讀取個數并無誤差。
計數值在允許輸入頻率內無誤差。
如果需要使用此功能或有任何疑問,請和我們聯系。
-
Linux
+關注
關注
87文章
11314瀏覽量
209794 -
嵌入式主板
+關注
關注
7文章
6085瀏覽量
35421
發布評論請先 登錄
相關推薦
評論