那曲檬骨新材料有限公司

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

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

3天內不再提示

英創信息技術C/C#開發基于WEC7的CAN通訊介紹

英創信息技術 ? 來源:英創信息技術 ? 作者:英創信息技術 ? 2020-01-17 10:01 ? 次閱讀

英創EM335x工控主板,使用的Cortex-A8及WEC7操作系統。本文以EM335x工控主板光盤例程為例,簡單介紹一下C和C#代碼如何調用WEC7平臺下CAN驅動,實現CAN通信的方法。

C代碼

客戶可以在自己工程中添加例程中的EM335X_CAN.h及EM335X_CAN.cpp,使用里面封裝好的EM335X_CAN類。
#include 'EM335X_CAN.h'
EM335X_CAN can;

打開CAN
調用EM335X_CAN類的OpenCAN方法。比如用250Kbps打開CAN1(默認只有CAN1)。
DWORD dwCanNo = 1;
DWORD dwBaudRate = 250000;
can.OpenCAN( dwCanNo, dwBaud );

關閉CAN
調用EM335X_CAN類的CloseCAN方法。
can.CloseCAN( );

發CAN數據包
調用EM335X_CAN類的WriteCAN方法。
can.WriteCAN(&canmsg );

接收CAN數據包

例程中使用了一個獨立的線程來接收。然后將收到的數據傳遞給PackagePro函數處理。參數一為數據buffer指針,參數二為數據的長度。
int EM335X_CAN::PackagePro(char* pBuf , int len)

用戶可以根據應用具體需求,添加相應的邏輯代碼。

CAN發送接收數據包結構體定義
不論是CAN發送,還是CAN接收,都是以數據包為單位發送接收的。單個數據包大小為16字節,結構體定義如下:
typedef struct {
CAN_ID id;
BYTE dlc;
BYTE data[8];
}CAN_MESSAGE,*PCAN_MESSAGE;

id,一個CAN_ID的結構體,該結構體定義在下面說明。
dlc,1字節,數據長度,取值0-8;
data,8字節,傳輸的數據。

注:因為結構體對齊的原因,該結構體大小為16字節。

CAN_ID結構體是一個整型,32位,用來記錄CAN通信所需的ID信息
typedef struct{
unsigned int id:29;
unsigned int reserved:1;
unsigned int remote:1;
unsigned int extended:1;
}CAN_ID;

id,結構體整型的低29位,表示id號。
reserved,第30位,用來標記是接收的數據包,還是發送的數據包,默認設置為0即可。
remote,第31位,用來設置是數據幀還是遠程幀。0為數據幀,1為遠程幀。
extended,第32位,用來設置是標準幀還是擴展幀。0為標準幀,1為擴展幀。

CAN過濾條件Filter設置
EM335x同樣支持數據包過濾功能,設置Filter可以使得CAN只接收自己需要的數據包。

調用EM335X_CAN類的SetFilter方法,可以添加一個過濾條件,或者刪除一個已有的過濾條件。例如:
bResult = can.SetFilter( &Filter, FALSE );

第一個參數為過濾條件參數,為一個CAN_FILTER的結構體,在下面有說明。第二個參數如果為FALSE,則表示添加該過濾條件,如果為TRUE,則表示刪除已有的該過濾條件。

有多個過濾條件的情況下,只要數據包可以滿足任意一個過濾條件,那么該數據包就可以被接收。

CAN過濾條件Filter結構體定義
CAN_FILTER結構體定義如下:(CAN_ID結構體的定義前面數據包結構體里有說明)
typedef struct {
CAN_ID id;
CAN_ID mask;
}CAN_FILTER,*PCAN_FILTER;

這里的過濾邏輯如下:


假設收到的數據包里的id,我們記為id_message,與過濾條件中的filter參數里的id和mask滿足條件:(id_message&mask) == (id&mask),那么該數據包就可以接收,也就是說,mask表示需要進行對比的位,如果數據包的id這幾位與filter設置里的id的這幾位相同,那么該數據包就可以接收。

比如:
一個filter的mask = 0x03,即2進制的b0000 0011,即需要比較最后的兩位。
filter的id = 0x02,即2進制的b0000 0010。
那么數據包id如果最后兩位為 10,該數據包就可以通過過濾條件被接收。
數據包id = 0xF7,即2進制b1111 0111,無法接收。
數據包id = 0xE6,即2進制b1110 0110,可以接收。
數據包id = 0x2E,即2進制b0010 1110,可以接收。

CAN環回模式設置
環回模式為,可以選擇板子自己發送的數據包,是否自己也能同時接收到。

調用EM335X_CAN類的CAN_Loopback方法,如果希望自己發送的CAN包,自己也能接收到,那么設置第二個參數為TRUE。如果希望關閉環回功能,那么第二個參數設置為FALSE。

CAN其它命令
EM335X_CAN類的CanCommand方法可以控制CAN復位,啟動和停止。
BOOL CanCommand( CAN_COMMAND eCommand);

參數CAN_COMMAND是一個枚舉型,它的定義如下,STOP= 0,START =1,RESET=3:
typedef enum {
STOP,
START,
RESET
} CAN_COMMAND;

1、復位CAN
CAN復位會重置CAN驅動里的各個寄存器值,并執行相關的初始化操作。

在打開CAN的時候,OpenCAN函數里已經調用了該函數實現CAN復位。用戶可以根據自己應用的實際情況,決定在什么時機執行CAN復位。

2、啟動CAN
在設置好CAN波特率,環回,filter等參數后,CAN驅動線程并沒有馬上啟動,需要執行CAN啟動,CAN線程才開始工作。

在打開CAN的時候,OpenCAN函數在設置完參數后調用CAN啟動。用戶可以根據自己應用的實際情況,決定在什么時機執行該函數,例如:當CAN接收線程的接收到錯誤事件時,可以在錯誤處理代碼里添加停止CAN,和重新啟動CAN的調用。

3、停止CAN
停止CAN會關閉CAN驅動線程,在關閉CAN的時候,CloseCAN函數調用CAN停止。

C#代碼

C#代碼參考了C代碼,相對C接口稍微做了調整。我們同樣封裝了一個CAN的類在EM335x_CAN_API.cs中,方便客戶添加到自己工程中。

打開CAN
打開CAN的流程為:打開CAN設備,獲得設備句柄,初始化CAN,然后設置CAN的參數(波特率,環回模式),創建CAN接收線程,最后啟動CAN,然后CAN驅動線程開始工作。

1、打開CAN設備
int CanNo = 1;
hCAN = CAN.OpenCAN(CanNo);

2、重置CAN
執行Reset操作,初始化CAN。
bRet = CAN.CAN_Command(hCAN, (uint)CAN_COMMAND.RESET);

3、設置波特率
設置CAN的波特率,如250Kbps:
uBaud = 250000;
bRet = CAN.CAN_SetBaudRate(hCAN, uBaud);

4、設置CAN環回模式
如果希望自己發送的CAN包,自己也能接收到,那么可以設置第二個參數為1,例程中暫時關閉該功能,所以設置的0。
bRet = CAN.CAN_Loopback(hCAN, 0);

5、創建單獨的接收線程
因為接收時,函數需要等待CAN接收事件,為阻塞狀態,不宜直接寫在主線程中,這里添加一個接收線程,專門處理CAN數據接收。
創建線程:
revThread = new Thread(new ThreadStart(BeginReceive));
threadStop = false;
revThread.Start();//啟動waitforMessage線程

6、啟動CAN
當準備就緒,就可以啟動CAN設備了。
bRet = CAN.CAN_Command(hCAN, (uint)CAN_COMMAND.START);

關閉CAN
主要是結束接收線程,停止CAN,及關閉CAN設備句柄等。
revThread.Abort();//結束線程
revThread.Join();
bRet = CAN.CAN_Command(hCAN, (uint)CAN_COMMAND.STOP);
bRet = CAN.CloseCAN(hCAN);

發CAN數據包
調用WriteFile發送CAN數據包。
bRet = CAN.WriteFile(hCAN, ref pktSend, CAN.sizePacket, ref uLen, 0);

接收CAN數據包
調用ReadFile發送CAN數據包。
bResult = CAN.ReadFile(hCAN, ref pktRev, CAN.sizePacket, ref uLen, 0);

CAN發送接收數據包結構體定義
不論是CAN發送WriteFile,還是CAN接收ReadFile,都是以數據包為單位發送接收的。單個數據包大小為16字節,結構體定義如下:
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct CAN_MESSAGE
{
[FieldOffset(0)]
public uint id;
[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] data;//數據字節
}

id是一個整型4字節,32位,用來記錄CAN通信所需的ID信息。
id的低29位,表示id號。
id的第30位,用來標記是接收的數據包,還是發送的數據包。
id的第31位,用來設置是數據幀還是遠程幀。該位為0則是數據幀,該位為1則是遠程幀。
id的第32位,用來設置是標準幀還是擴展幀。該位為0則是標準幀,該位為1則是擴展幀。

data為12字節byte數組。
data[0]為CAN數據包內數據的長度,取值0-8;
data[1]-data[8],8字節,為CAN數據包內傳輸的數據。
data[9]-data[11]未使用。

注:結構體這樣設計的主要原因還是因為要和C代碼的驅動接口,做成這樣效率會高些。

例如,我們要發送一個,id為5的標準數據幀,數據長度為3,分別是0x01,0x02,0x03,代碼如下:
CAN_MESSAGE pktSend = new CAN_MESSAGE();
pktSend.id = 5;
//如果是數據幀就不變,如果是遠程幀就
//pktSend.id = pktSend.id | 0x20000000;//remote
//如果是標準幀就不變,如果是擴展幀就
//pktSend.id = pktSend.id | 0x40000000;//extended
pktSend.data[0] = 3;
pktSend.data[1] = 0x01;
pktSend.data[2] = 0x02;
pktSend.data[3] = 0x03;

例如,我們要發送一個,id為55的擴展幀,數據長度為6,分別是0x04,0x04,0x04,0x05,0x05,0x05,代碼如下:
CAN_MESSAGE pktSend = new CAN_MESSAGE();
pktSend.id = 5;
//如果是數據幀就不變,如果是遠程幀就
//pktSend.id = pktSend.id | 0x20000000;//remote
//如果是標準幀就不變,如果是擴展幀就
pktSend.id = pktSend.id | 0x40000000;//extended
pktSend.data[0] = 6;
pktSend.data[1] = 0x04;
pktSend.data[2] = 0x04;
pktSend.data[3] = 0x04
pktSend.data[4] = 0x05;
pktSend.data[5] = 0x05;
pktSend.data[6] = 0x05;

CAN過濾條件Filter設置
EM335x同樣支持數據包過濾功能,設置Filter可以使得CAN只接收自己需要的數據包。

調用EM335X_CAN類的SetFilter方法,可以添加一個過濾條件,或者刪除一個已有的過濾條件。例如:
CAN.CAN_SetFilter (hCAN, Filter, false );

第一個參數為CAN句柄,第二個參數為過濾條件參數,為一個CAN_FILTER的結構體,在下面有說明。第三個參數如果為FALSE,則表示添加該過濾條件,如果為TRUE,則表示刪除已有的該過濾條件。

有多個過濾條件的情況下,只要數據包可以滿足任意一個過濾條件,那么該數據包就可以被接收。

CAN過濾條件Filter結構體定義
CAN_FILTER結構體定義如下:
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct CAN_FILTER
{
[FieldOffset(0)]
public uint id;
[FieldOffset(4)]
public uint mask;
}

這里的過濾邏輯如下:

假設收到的數據包里的id,我們記為id_message,與過濾條件中的filter參數里的id和mask滿足條件:(id_message&mask) == (id&mask),那么該數據包就可以接收,也就是說,mask表示需要進行對比的位,如果數據包的id這幾位與filter設置里的id的這幾位相同,那么該數據包就可以接收。

比如:
一個filter的mask = 0x03,即2進制的b0000 0011,即需要比較最后的兩位。
filter的id = 0x02,即2進制的b0000 0010。
那么數據包id如果最后兩位為 10,該數據包就可以通過過濾條件被接收。
數據包id = 0xF7,即2進制b1111 0111,無法接收。
數據包id = 0xE6,即2進制b1110 0110,可以接收。

詳細信息,可以電話,郵件或論壇提問方式咨詢英創工程師。

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

    關注

    7

    文章

    6086

    瀏覽量

    35617
收藏 人收藏

    評論

    相關推薦

    dsPIC33C Touch-CAN-LIN Curiosity開發板用戶指南

    電子發燒友網站提供《dsPIC33C Touch-CAN-LIN Curiosity開發板用戶指南.pdf》資料免費下載
    發表于 01-22 16:18 ?0次下載
    dsPIC33<b class='flag-5'>C</b> Touch-<b class='flag-5'>CAN</b>-LIN Curiosity<b class='flag-5'>開發</b>板用戶指南

    液顯ID讀卡器C#小程序開發

    液顯WIFI無線讀卡器ID-10F用C#語音開發HTTP協議讀卡小程序。讀卡器圖片如下:? ID讀卡器的特點: ?UDP通訊協議,設備主動讀取EM4100及兼容的低頻RFID卡并即時將卡號發送到
    的頭像 發表于 01-10 15:31 ?90次閱讀
    液顯ID讀卡器<b class='flag-5'>C#</b>小程序<b class='flag-5'>開發</b>

    C#通過Halcon實現3D點云重繪

    C# 通過 Halcon 實現 3D 點云重繪
    發表于 01-05 09:16 ?0次下載

    C#基于Halcon實現Basler相機采圖

    C#基于Halcon實現Basler相機采圖
    發表于 01-05 09:16 ?0次下載

    C6748開發板求助

    求助各位大佬,使用龍的C6748開發板,運行LINE_IN例程,為什么輸入正弦波后,輸出的是雜波
    發表于 12-27 17:01

    運動控制卡網絡通訊的心跳檢測之C#上位機編程

    使用C#上位機編程實現運動控制卡網絡通訊的心跳檢測功能
    的頭像 發表于 12-24 10:54 ?248次閱讀
    運動控制卡網絡<b class='flag-5'>通訊</b>的心跳檢測之<b class='flag-5'>C#</b>上位機編程

    以太網IO控制卡:C#實時讀寫時間測試

    C#語言進行ECI IO卡的項目開發和快速讀取多個IO狀態與上位機交互速度的測試結果
    的頭像 發表于 11-21 13:50 ?288次閱讀
    以太網IO控制卡:<b class='flag-5'>C#</b>實時讀寫時間測試

    中科達榮獲2024年軟件和信息技術服務優秀企業

    及前百家企業”名單。中科達憑借非凡的技術實力與持續的創新能力,成功入選“2024年度軟件和信息技術服務競爭力百強企業”以及“2024年軟件和信息技術服務優秀企業”。
    的頭像 發表于 10-30 11:44 ?557次閱讀

    加速鯤鵬落地!拓維信息遷移工具榮獲鯤鵬原生開發技術認證

    認證。圖/拓維·數據庫適配中間件取得鯤鵬原生開發N認證在數字化時代的大潮中,信戰略作為國家推動信息技術應用創新、保障信息安全與自主可控的關鍵舉措,其重要性日益凸顯
    的頭像 發表于 09-10 08:03 ?505次閱讀
    加速鯤鵬落地!拓維<b class='flag-5'>信息</b>信<b class='flag-5'>創</b>遷移工具榮獲鯤鵬原生<b class='flag-5'>開發</b><b class='flag-5'>技術</b>認證

    技術分享】CAN總線相關知識探討以及Model3C兩路CAN的應用

    CAN總線相關知識,以個位數價格的工業級HMI芯片–Model3C為例, 2路CAN的應用
    的頭像 發表于 09-05 10:59 ?641次閱讀
    【<b class='flag-5'>技術</b>分享】<b class='flag-5'>CAN</b>總線相關知識探討以及Model3<b class='flag-5'>C</b>兩路<b class='flag-5'>CAN</b>的應用

    [can開發板] 一款低價can/obd2總線Linux開發

    CAN總線/汽車CAN總線/OBD2通訊/OBD分析儀/USB轉CAN/DBC編解碼/帶遠程訪問功能的CAN/OBD
    發表于 07-05 16:46

    如何檢測can通訊電路的好壞

    CAN(Controller Area Network)是一種基于總線通信的局域網技術,廣泛應用于汽車電子、工業控制等領域。在實際應用中,CAN通訊電路的好壞對整個系統的穩定性和可靠性
    的頭像 發表于 06-16 09:42 ?3565次閱讀

    簡單易用的以太網數據采集卡應用開發C#

    C#語言以太網數據采集卡的開發
    的頭像 發表于 05-17 14:25 ?842次閱讀
    簡單易用的以太網數據采集卡應用<b class='flag-5'>開發</b>之<b class='flag-5'>C#</b>

    MGMF442L1C7-MINAS A6N系列 介紹 松下

    電子發燒友網為你提供Panasonic(Panasonic)MGMF442L1C7-MINAS A6N系列 介紹相關產品參數、數據手冊,更有MGMF442L1C7-MINAS A6N系列 介紹
    發表于 05-09 19:08
    MGMF442L1<b class='flag-5'>C7</b>-MINAS A6N系列 <b class='flag-5'>介紹</b> 松下

    MGMF132L1C7-MINAS A6N系列 介紹 松下

    電子發燒友網為你提供Panasonic(Panasonic)MGMF132L1C7-MINAS A6N系列 介紹相關產品參數、數據手冊,更有MGMF132L1C7-MINAS A6N系列 介紹
    發表于 03-04 18:37
    MGMF132L1<b class='flag-5'>C7</b>-MINAS A6N系列 <b class='flag-5'>介紹</b> 松下
    百家乐官网赌场软件| 百家乐官网境外赌博| 新2娱乐城| 真人百家乐官网来博| 澳门百家乐官网的公式| 豪门百家乐官网的玩法技巧和规则| 大发888com| 澳门百家乐官网赢钱公式不倒翁| 太阳百家乐娱乐| 百家乐官网博彩平| 88娱乐城备用网址| 百家乐开户送彩网址| 通州区| 七胜百家乐娱乐平台| 大发888网页游戏| 发中发百家乐官网的玩法技巧和规则 | 百家乐官网群必胜打朽法| 百家乐分析软件| 真人百家乐导航| 百家乐官网筹码多少钱| 大发888网页版体育| 百家乐视频计牌器| 百家乐官网赌法博彩正网| 全讯网信息| 百家乐官网园sun811| 德州扑克大小顺序| 百家乐投注外挂| 百家乐官网网站是多少| 六合彩最快开奖| 百家乐发牌靴遥控| 线上百家乐官网是如何作弊| 博彩通| 财富百家乐的玩法技巧和规则 | 百家乐真人娱乐场开户注册| 百家乐官网怎么看大小| 皇冠开户网址| 百家乐八卦九| 立博百家乐官网的玩法技巧和规则| 连州市| 大发888 游戏下载| 澳门百家乐大家乐眼|