英創(chuàng)工控主板都給用戶提供了豐富的GPIO資源,在ESMARC系列的板卡上配置了32位GPIO,GPIO(General-purpose input/output)即通用輸入輸出,在實(shí)際使用中有多種用途,而作為外部中斷輸入便是較常用的功能,通過(guò)對(duì)外部輸入中斷的響應(yīng),可以滿足多種應(yīng)用需求,脈沖計(jì)數(shù)就是一種典型的應(yīng)用。英創(chuàng)主板已經(jīng)給用戶提供了兩路中斷功能,是采用異步IO的方式,電平上升沿觸發(fā)中斷,通過(guò)信號(hào)量SIGIO通知應(yīng)用程序,關(guān)于詳細(xì)的資料可以參考網(wǎng)站:《ESM335x外部中斷輸入應(yīng)用》。
為了讓用戶能夠使用到更多外部輸入中斷,英創(chuàng)公司進(jìn)一步在驅(qū)動(dòng)中增加了相應(yīng)的功能和接口,利用IO多路復(fù)用的技術(shù)讓所有GPIO都能夠作為外部中斷輸入,通過(guò)程序設(shè)置使能,一旦管腳電平發(fā)生變化,內(nèi)核就會(huì)通知應(yīng)用程序,這時(shí)使用select或者poll函數(shù)就可以接收到內(nèi)核發(fā)出的消息。通過(guò)這種方式,用戶可以將主板的32位GPIO全部作為外部中斷輸入,而原來(lái)提供的采用異步IO方式的兩路中斷我們?cè)瓌t上就不再做更新和維護(hù),建議客戶使用我們最新提供的方法。下面就以兩路GPIO的脈沖計(jì)數(shù)功能為例,介紹如何通過(guò)select或者poll函數(shù)實(shí)現(xiàn)外部中斷響應(yīng)。
首先要啟用中斷輸入功能,這一步需要調(diào)用英創(chuàng)公司提供的設(shè)置GPIO為輸入狀態(tài)的API函數(shù)來(lái)實(shí)現(xiàn)。也就是在程序中調(diào)用一次函數(shù),設(shè)置GPIO為輸入狀態(tài),就能把對(duì)應(yīng)的GPIO管腳設(shè)置為外部中斷輸入功能,如設(shè)置GPIO0和GPIO23為中斷輸入,代碼如下:
int GPIO_OutDisable(fd, GPIO0 | GPIO23)
當(dāng)設(shè)置完成后,GPIO作為輸入狀態(tài),同時(shí)會(huì)監(jiān)測(cè)外部輸入電平變化,并通過(guò)內(nèi)核驅(qū)動(dòng)通知應(yīng)用層。應(yīng)用程序使用select或者poll函數(shù)來(lái)監(jiān)聽GPIO的句柄的讀事件就能夠獲取到通知,用戶可以通過(guò)多線程的方式來(lái)實(shí)現(xiàn),通過(guò)select函數(shù)實(shí)現(xiàn)代碼如下:
while( 1 ) { //設(shè)置讀事件 FD_ZERO(&fdRead); FD_SET(fd,&fdRead); //設(shè)置超時(shí)時(shí)間 aTime.tv_sec= 0; aTime.tv_usec= 20000; ret =select(fd+1,&fdRead,NULL,NULL,&aTime); if(ret < 0 ) { printf("error!\n"); break; } if(ret > 0) { //判斷是否讀事件 if(FD_ISSET(fd,&fdRead)) { dwPinState = GPIO0 | GPIO23; rc = GPIO_PinState(fds.fd, &dwPinState); if(rc< 0) { printf("GPIO_PinState::failed %d\n", rc); returnrc; } //根據(jù)上升沿對(duì)脈沖計(jì)數(shù) if(dwPinState& GPIO0) pulse1_num++; if(dwPinState& GPIO23) pulse2_num++; //計(jì)數(shù)到500就退出 if(pulse1_num == 500 && pulse2_num == 500) { printf("the pules number is 500\n"); break; } } } } close(fd); return 0; |
使用poll函數(shù)也是類似的,同樣的需要先使能GPIO的外部中斷輸入功能,即調(diào)用一次設(shè)置GPIO為輸入狀態(tài)的函數(shù),然后使用poll函數(shù)來(lái)監(jiān)聽GPIO的句柄的讀事件就能夠獲取到通知,具體代碼如下:
while(1) { structpollfdfds; int timeout; //設(shè)置監(jiān)聽句柄 fds.fd = fd; //設(shè)置讀事件 fds.events = POLLIN; //設(shè)置超時(shí)時(shí)間 timeout = 20000; ret = poll(&fds, 1, timeout); if (ret < 0 ) { printf("error!\n"); break; } if (ret > 0) { //判斷是否讀事件 if (fds.revents == POLLIN) { dwPinState = GPIO0 | GPIO23; rc = GPIO_PinState(fds.fd, &dwPinState); if(rc< 0) { printf("GPIO_PinState::failed %d\n", rc); returnrc; } //根據(jù)上升沿對(duì)脈沖計(jì)數(shù) if(dwPinState& GPIO0) pulse1_num++; if(dwPinState& GPIO23) pulse2_num++; //計(jì)數(shù)到500就退出 if(pulse1_num == 500 && pulse2_num == 500) { printf("the pules number is 500\n"); break; } } } } close(fd); return 0; |
當(dāng)輸入電平發(fā)生變化,select和poll函數(shù)偵測(cè)到讀事件,就可以進(jìn)行相應(yīng)的操作,示例代碼通過(guò)判斷上升沿來(lái)計(jì)數(shù)脈沖數(shù),經(jīng)過(guò)測(cè)試,上述代碼能對(duì)兩路2KHz的脈沖實(shí)現(xiàn)可靠計(jì)數(shù)。用戶還可以根據(jù)實(shí)際的應(yīng)用需求,把上述代碼修改為支持多路脈沖計(jì)數(shù)功能。
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35225
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論