<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用PCIE主站卡控制IO從站step by step(二)

ZLG致遠電子 ? 2024-05-24 08:25 ? 次閱讀

ZLG致遠電子的PCIe EtherCAT通訊卡該如何使用?PDO過程數據該如何操作?具體編程又該如何實現?續接上一章節,本文將為您詳細講解。

EtherCAT工業總線技術工業自動化領域展現出了廣泛的應用價值,特別是在運動控制、機器人技術和測量技術等方面。ZLG致遠電子 PCIe EtherCAT通訊卡 基于自主知識產權的系統之上開發,實現了軟硬件間的無縫連接,極大地提升了系統的穩定性、可靠性以及安全性。同時,該通訊卡還支持線路冗余以及熱插拔功能,可輕松實現多軸同步控制和數據的高速傳輸。此外,ZLG致遠電子PCIe EtherCAT通訊卡還為用戶提供了便捷的二次開發庫,支持VC、C#、Linux、Python等各類主流開發環境,滿足客戶不同層次的開發需求。值得一提的是,ZLG致遠電子PCIe EtherCAT通訊卡通過將商業級EtherCAT主站協議和實時內核相結合的方式,有效釋放主機資源,完美解決傳統EtherCAT主站在非實時操作系統下運行所帶來的各類問題,為用戶帶來了更加高效、穩定的解決方案。0d7904f2-1964-11ef-bebc-92fbcf53809c.png圖1PCIeEtherCAT通訊卡表1PCIeEtherCAT通訊卡型號

0d9ad726-1964-11ef-bebc-92fbcf53809c.png

基于上一章《使用PCIe EtherCAT通訊卡控制IO從站step by step(一)》中所講訴的內容,我們已經完成了開發環境的搭建,以及主函數的建立,接下來,我們將會進一步完善主函數中的代碼,實現對從站的PDO數據讀寫。

1. 代碼編寫

打開ecat_api_io_test.cpp文件。根據AWStudio軟件導出的eni文件定義過程數據的結構體,打開eni文件,移動光標到文件尾部,找到注釋的節點ENI_PDO_LIST。0dbc29c6-1964-11ef-bebc-92fbcf53809c.png圖2ENI文件(1)0dd7b498-1964-11ef-bebc-92fbcf53809c.png圖3ENI文件(2)節點中的inputs為從站返回的PDO過程數據,outputs為主站發送到從站的PDO過程數據,根據每個變量的位寬bit_size,我們可以定義對應的類型。

根據圖2的信息,我們可以看出輸出有三個變量,DI_1,AI_1,AI_2,長度分別為8位,8位,16位,輸入有三個變量DO_1,AO_1,AO_2,長度分別位8位,8位,16位,定義結構體:

//過程數據,寫入從站的數據格式typedef struct{ uint8_t DI_1; uint8_t AI_1; uint16_t AI_2;}PDO_OUTPUTS_T;
//過程數據,從站返回的數據格式typedef struct{ uint8_t DO_1; uint8_t AO_1; uint16_t AO_2;}PDO_INPUTS_T;

定義完過程數據的結構體后。

第一步,輸入需要控制的pcie卡別名以及通道號,獲取Ecat控制句柄。

EXIT_IF_FAIL(EcatOpen(&hHandle, BOARD_ALIAS(buff, alias), channel));

第二步,輸入上位機程序導出的eni文件,啟動Ecat主站。

EXIT_IF_FAIL(EcatBusRun(hHandle, fileName));

第三步,將Ecat主站狀態切換為8(Operational)。

EXIT_IF_FAIL(EcatRequestMasterState(hHandle, EcatStateO));

等待主站切換狀態。

uint8_t query = EcatStateNotSet;do{ EXIT_IF_FAIL(EcatGetMasterState(hHandle, &query)); //輸出當前狀態 _DBG_("request_state=%d, query_state=%d", EcatStateO, query); if (query == EcatStateO){ break;; } std::sleep_for(std::seconds(1));}while(1);

第四步,定義PDO過程數據的指針并指向本地緩存空間,這一步將會讓我們更加方便快捷地讀寫PDO數據。

0df5f5b6-1964-11ef-bebc-92fbcf53809c.png圖4PDO數據的收發原理執行EcatPINMap函數,將會修改第3個參數inputBuff,outputBuff的指向,讓其直接指向本地輸入輸出緩存區,固不需要再額外申請空間。

PDO_OUTPUTS_T *outputBuff;PDO_INPUTS_T *inputBuff;//將指針inputBuff,outputBuff分別指向本地緩存的空間EXIT_IF_FAIL(EcatPINMap(hHandle, PI_AREA_LOCAL_INPUT, (void**)&inputBuff));EXIT_IF_FAIL(EcatPINMap(hHandle, PI_AREA_LOCAL_OUTPUT, (void**)&outputBuff));

第五步,向發送隊列中添加空數據,添加空數據的數量取決于PC系統抖動的程度,抖動越小,添加的空數據越少,控制指令的滯后性越小。

for(auto i = 0; i < 2; i++){ ? ?EcatPIOutputQueuePush(hHandle, false, 100);}

第六步,使能過程數據PDO通信。

EXIT_IF_FAIL(EcatPIEnable(hHandle));

第七步,通過EcatPIInputQueuePop接口,等待從站數據返回,然后讀寫PDO過程數據,最后調用EcatPIOutputQueuePush接口將數據添加到發送隊列。當前例子中,在收到從站返回的數據后,主站會將收到的輸入數據寫到輸出的變量。

bool loopFlag = true;while(loopFlag){ //阻塞式等待PDO數據 if (!EcatPIInputQueuePop(hHandle, false, 100)){ /*********************************************************/ //修改過程數據 printf("0x%02x, 0x%02x, 0x%04x\r\n", inputBuff->DO_1, inputBuff->AO_1, inputBuff->AO_2); outputBuff->DI_1 = inputBuff->DO_1; outputBuff->AI_1 = inputBuff->AO_1; outputBuff->AI_2 = inputBuff->AO_2; /*********************************************************/ //將數據添加到PDO的發送隊列中 if (EcatPIOutputQueuePush(hHandle, false, 100)){ _ERR_("PI push error."); break; } }}

第八步,釋放句柄。

EXIT_IF_FAIL(EcatClose(hHandle));

完整的ecat_api_io_test.cpp文件。

#include #include //用于sleep#include //用于sleep#include "pci_errno.h"#include "pci_zecm.h"#include "pci_dbg.h"
//過程數據,寫入從站的數據格式typedef struct{ uint8_t DI_1; uint8_t AI_1; uint16_t AI_2;}PDO_OUTPUTS_T;
//過程數據,從站返回的數據格式typedef struct{ uint8_t DO_1; uint8_t AO_1; uint16_t AO_2}PDO_INPUTS_T;
int32_t testDemo(int alias, int channel, const char* fileName){ int32_t result = 0; char buff[256]; ECAT_HANDLE hHandle; //初始化hHandle句柄 EXIT_IF_FAIL(EcatOpen(&hHandle, BOARD_ALIAS(buff, alias), channel)); //啟動主站 EXIT_IF_FAIL(EcatBusRun(hHandle, fileName)); //將狀態切換為8(Operational) EXIT_IF_FAIL(EcatRequestMasterState(hHandle, EcatStateO));
//等待主站切換狀態 uint8_t query = EcatStateNotSet; do{ EXIT_IF_FAIL(EcatGetMasterState(hHandle, &query)); //輸出當前狀態 _DBG_("request_state=%d, query_state=%d", EcatStateO, query); if (query == EcatStateO){ break;; } std::sleep_for(std::seconds(1)); }while(1);
PDO_OUTPUTS_T *outputBuff; PDO_INPUTS_T *inputBuff; //將指針inputBuff,outputBuff分別指向本地緩存的空間 EXIT_IF_FAIL(EcatPINMap(hHandle, PI_AREA_LOCAL_INPUT, (void**)&inputBuff)); EXIT_IF_FAIL(EcatPINMap(hHandle, PI_AREA_LOCAL_OUTPUT, (void**)&outputBuff));
//向發送隊列中添加空數據,添加空數據的數量取決于PC系統抖動的程度,抖動越小,添加的空數據越少,控制指令的滯后性越小 for(auto i = 0; i < 2; i++){ EcatPIOutputQueuePush(hHandle, false, 100); } //使能過程數據PDO通信 EXIT_IF_FAIL(EcatPIEnable(hHandle));
bool loopFlag = true; while(loopFlag){ //阻塞式等待PDO數據 if (!EcatPIInputQueuePop(hHandle, false, 100)){ /*********************************************************/ //修改過程數據 printf("0x%02x, 0x%02x, 0x%04x\r\n", inputBuff->DO_1,inputBuff->AO_1, inputBuff->AO_2); outputBuff->DI_1 = inputBuff->DO_1; outputBuff->AI_1 = inputBuff->AO_1; outputBuff->AI_2 = inputBuff->AO_2; /*********************************************************/ //將數據添加到PDO的發送隊列中 if (EcatPIOutputQueuePush(hHandle, false, 100)){ _ERR_("PI push error."); break; } } }
//釋放句柄 EXIT_IF_FAIL(EcatClose(hHandle)); return result;}
int main(int argc, char* argv[]){ ECAT_HANDLE hHandle; char buff[256]; uint32_t channel = 0, alias = 0; std::string eniFile; if (argc != 4){ std::cout << "usage: " << argv[0] << " encoder_id channel eni.xml" << std::endl; ? ? ? ?return 1; ? ?} ? ?alias = atoi(argv[1]); ? ?channel = atoi(argv[2]); ? ?eniFile = argv[3]; ? ?if (channel > 1){ channel = 1; } testDemo(alias, channel, eniFile.c_str()); return 0;}

編譯

0e191078-1964-11ef-bebc-92fbcf53809c.png

運行測試

0e3396b4-1964-11ef-bebc-92fbcf53809c.png

輸出,程序將持續打印從站的輸入狀態

0e4b7d06-1964-11ef-bebc-92fbcf53809c.png

但真正開發的時候,建議將打印信息等耗時的操作注釋后再編譯,否則,程序將可能會因為打印動作耗時過長而導致主機無法快速填充pdo數據,最終將產生控制抖動等問題。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 總線
    +關注

    關注

    10

    文章

    2735

    瀏覽量

    87389
  • PCIe
    +關注

    關注

    13

    文章

    1103

    瀏覽量

    81255
  • 通訊卡
    +關注

    關注

    0

    文章

    6

    瀏覽量

    5824
收藏 人收藏

    評論

    相關推薦

    Step7 Micro Win v4.0.4.16 最新版下載

    與Modbus的通訊簡單易行。使用Modbus協議指令,您可以將S7-200組態作為Modbus RTU
    發表于 04-25 07:25

    C語言step-by-step

    C語言step-by-step!
    發表于 12-27 09:59

    基于EtherCAT的通信控制器設計

    基于EtherCAT的通信控制器設計
    發表于 09-20 16:05

    Modbus多問題

    ModbusRTU兩之間如何交互數據? 工業控制中,一般都是主從通訊方式居多,有時也會碰到兩個之間通訊。例如某工作站上位機(
    發表于 11-24 16:36

    PLC分享

    總站是主控制單元,含有CPU,可以不加CPU,可以作為遠程,用
    發表于 07-02 08:20

    CAN的功能是什么

    基于 STM32 和 CAN總線的溫度監控系統的設計,通過上位機與下位機的通信,實現對溫度數據的監控,并經初步實驗達到了設計的要求。1 系統總體方案概述系統總體框圖如圖 1 所示,本系統采用+
    發表于 08-19 07:47

    PLC具有哪些功能

    PLC具有哪些功能?PLC具有哪些功能?
    發表于 09-29 07:22

    開源!ZYNQ IgH EtherCAT方案分享

    前 言:創龍科技已基于IMX8、ZYNQ、AM5728、AM5708、AM437x、AM335x、T3/A40i等平臺提供了開源EtherCATIgH案例。本文主要演示
    發表于 10-29 11:17

    通過Mbus發送信息,無法收到信息怎么解決?

    通過Mbus發送信息,無法收到信息怎么解決?
    發表于 01-20 06:42

    請問在RT-thread系統里運行4個和1個是否穩定

    請問這個協議包,在RT-thread系統里,如果運行4個small modbus和1個small modbus,是否穩定
    發表于 11-25 10:28

    esp32當modbus-rtu slave通訊,收不到的響應報文是為何?

    有朋友測試過esp32當 modbus slave(我拿的esp32當,用的是RTU模式)嗎? 我用modbus poll軟件測試下來,
    發表于 02-14 07:11

    lightech mbus完整指令庫

    lightech mbus完整指令庫
    發表于 10-09 06:20

    STEP7 IO冗余編程方法 (S7-400 )

    elecfans.com-STEP7 IO冗余編程方法
    發表于 07-03 16:15 ?30次下載

    S7-400作為PROFINET IO控制器(STEP7)

    S7-400集成PN口和CP443-1均可作為PROFINET IO控制器。本文以CPU 414-3 PN/DP作為IO設備,分別闡述以CPU 416-3 PN/DP和CP443-1作為IO
    的頭像 發表于 12-16 11:35 ?1352次閱讀

    使用PCIe EtherCAT通訊卡控制IO從站step by step(一)

    卡是一款高性能的總線控制卡,專為滿足高實時的工業控制需求而設計?;赑CIExpress技術,該卡通過使用實時內核+商業授權EtherCAT協議棧的方式,實現了高達
    的頭像 發表于 05-21 08:24 ?121次閱讀
    使用<b class='flag-5'>PCIe</b> EtherCAT通訊卡<b class='flag-5'>控制</b><b class='flag-5'>IO</b>從站<b class='flag-5'>step</b> by <b class='flag-5'>step</b>(一)
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>