<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • 用GPIO實現多路外部中斷及脈沖計數

     2019-4-23     作者:黃志超         
    文章標簽:C/C++GPIO

      英創工控主板都給用戶提供了豐富的GPIO資源,在ESMARC系列的板卡上配置了32位GPIO,GPIO(General-purpose input/output)即通用輸入輸出,在實際使用中有多種用途,而作為外部中斷輸入便是較常用的功能,通過對外部輸入中斷的響應,可以滿足多種應用需求,脈沖計數就是一種典型的應用。英創主板已經給用戶提供了兩路中斷功能,是采用異步IO的方式,電平上升沿觸發中斷,通過信號量SIGIO通知應用程序,關于詳細的資料可以參考網站:《ESM335x外部中斷輸入應用》


      為了讓用戶能夠使用到更多外部輸入中斷,英創公司進一步在驅動中增加了相應的功能和接口,利用IO多路復用的技術讓所有GPIO都能夠作為外部中斷輸入,通過程序設置使能,一旦管腳電平發生變化,內核就會通知應用程序,這時使用select或者poll函數就可以接收到內核發出的消息。通過這種方式,用戶可以將主板的32位GPIO全部作為外部中斷輸入,而原來提供的采用異步IO方式的兩路中斷我們原則上就不再做更新和維護,建議客戶使用我們最新提供的方法。下面就以兩路GPIO的脈沖計數功能為例,介紹如何通過select或者poll函數實現外部中斷響應。


      首先要啟用中斷輸入功能,這一步需要調用英創公司提供的設置GPIO為輸入狀態的API函數來實現。也就是在程序中調用一次函數,設置GPIO為輸入狀態,就能把對應的GPIO管腳設置為外部中斷輸入功能,如設置GPIO0和GPIO23為中斷輸入,代碼如下:

      int GPIO_OutDisable(fd, GPIO0 | GPIO23)


      當設置完成后,GPIO作為輸入狀態,同時會監測外部輸入電平變化,并通過內核驅動通知應用層。應用程序使用select或者poll函數來監聽GPIO的句柄的讀事件就能夠獲取到通知,用戶可以通過多線程的方式來實現,通過select函數實現代碼如下:


    while( 1 )
      {
        //設置讀事件
        FD_ZERO(&fdRead);
        FD_SET(fd,&fdRead);
     
        //設置超時時間
      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;
                                }
     
    //根據上升沿對脈沖計數
                                if(dwPinState& GPIO0)
                                       pulse1_num++;
                                if(dwPinState& GPIO23)
                                       pulse2_num++;
     
    //計數到500就退出
                                if(pulse1_num == 500 && pulse2_num == 500)
                                {
                                       printf("the pules number is 500\n");
                                       break;
                                }
                         }
                 }
          }
         close(fd);
          return 0;


      使用poll函數也是類似的,同樣的需要先使能GPIO的外部中斷輸入功能,即調用一次設置GPIO為輸入狀態的函數,然后使用poll函數來監聽GPIO的句柄的讀事件就能夠獲取到通知,具體代碼如下:


    while(1)
           {
                  structpollfdfds;
                  int timeout;
     
    //設置監聽句柄
                  fds.fd = fd;
    //設置讀事件
                  fds.events = POLLIN;
    //設置超時時間
                  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;
                                }
     
    //根據上升沿對脈沖計數
                                if(dwPinState& GPIO0)
                                       pulse1_num++;
                                if(dwPinState& GPIO23)
                                       pulse2_num++;
     
    //計數到500就退出
                                if(pulse1_num == 500 && pulse2_num == 500)
                                {
                                       printf("the pules number is 500\n");
                                       break;
                                }
                         }
                  }
          }
         close(fd);
          return 0;


      當輸入電平發生變化,select和poll函數偵測到讀事件,就可以進行相應的操作,示例代碼通過判斷上升沿來計數脈沖數,經過測試,上述代碼能對兩路2KHz的脈沖實現可靠計數。用戶還可以根據實際的應用需求,把上述代碼修改為支持多路脈沖計數功能。


      對于不需要外部輸入中斷功能的用戶也不會有什么影響,當調用函數將GPIO設置為輸入后,不使用select和poll函數去監聽GPIO的句柄即可,其他功能都和原來保持一致。如有感興趣的客戶,可以英創工程師聯系索取代碼。

    文章標簽:C/C++GPIO
    91麻豆精品国产91久久久久久 | 国产一精品一av一免费爽爽| 国产91精品久久久久999| 精品国产成人亚洲午夜福利| 91www永久在线精品果冻传媒| 久久精品一区二区东京热| 热久久这里是精品6免费观看| 精品国产污污免费网站入口在线 | 国产精品十八禁在线观看| 欧美激情国产精品视频一区二区| 亚洲精品中文字幕无码AV| 99re热视频精品首页| 亚洲综合一区二区精品导航| 久久91精品久久91综合| 亚洲精品~无码抽插| 国产精品无码久久综合| 国产香蕉国产精品偷在线| 国产午夜福利精品久久| 91麻豆精品国产| 中文成人无字幕乱码精品区| 国产丝袜在线精品丝袜| 国产精品无套内射迪丽热巴| 精品国产自在在线在线观看| 亚洲av午夜成人片精品网站| 无码精品久久久久久人妻中字| 无码精品国产一区二区三区免费| 久久精品人成免费| 久久无码国产专区精品| 国产精品一二三区| 久久99热久久99精品| 探花国产精品三级在线播放| 国产在线91区精品| 国产三级精品三级| 亚洲国产一二三精品无码| 久久精品国产2020观看福利| 嫩草伊人久久精品少妇AV| 2021国产精品久久| 色妞www精品视频一级下载| 日韩在线视精品在亚洲| 一本一本久久a久久精品综合麻豆| 精品伦精品一区二区三区视频 |