99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

英創(chuàng)信息技術(shù)C/C#開發(fā)基于WEC7的CAN通訊介紹

英創(chuàng)信息技術(shù) ? 來源:英創(chuàng)信息技術(shù) ? 作者:英創(chuàng)信息技術(shù) ? 2020-01-17 10:01 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

C代碼

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

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

關(guān)閉CAN
調(diào)用EM335X_CAN類的CloseCAN方法。
can.CloseCAN( );

發(fā)CAN數(shù)據(jù)包
調(diào)用EM335X_CAN類的WriteCAN方法。
can.WriteCAN(&canmsg );

接收CAN數(shù)據(jù)包

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

用戶可以根據(jù)應(yīng)用具體需求,添加相應(yīng)的邏輯代碼。

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

id,一個CAN_ID的結(jié)構(gòu)體,該結(jié)構(gòu)體定義在下面說明。
dlc,1字節(jié),數(shù)據(jù)長度,取值0-8;
data,8字節(jié),傳輸?shù)臄?shù)據(jù)。

注:因為結(jié)構(gòu)體對齊的原因,該結(jié)構(gòu)體大小為16字節(jié)。

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

id,結(jié)構(gòu)體整型的低29位,表示id號。
reserved,第30位,用來標(biāo)記是接收的數(shù)據(jù)包,還是發(fā)送的數(shù)據(jù)包,默認(rèn)設(shè)置為0即可。
remote,第31位,用來設(shè)置是數(shù)據(jù)幀還是遠(yuǎn)程幀。0為數(shù)據(jù)幀,1為遠(yuǎn)程幀。
extended,第32位,用來設(shè)置是標(biāo)準(zhǔn)幀還是擴(kuò)展幀。0為標(biāo)準(zhǔn)幀,1為擴(kuò)展幀。

CAN過濾條件Filter設(shè)置
EM335x同樣支持?jǐn)?shù)據(jù)包過濾功能,設(shè)置Filter可以使得CAN只接收自己需要的數(shù)據(jù)包。

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

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

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

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

這里的過濾邏輯如下:


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

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

CAN環(huán)回模式設(shè)置
環(huán)回模式為,可以選擇板子自己發(fā)送的數(shù)據(jù)包,是否自己也能同時接收到。

調(diào)用EM335X_CAN類的CAN_Loopback方法,如果希望自己發(fā)送的CAN包,自己也能接收到,那么設(shè)置第二個參數(shù)為TRUE。如果希望關(guān)閉環(huán)回功能,那么第二個參數(shù)設(shè)置為FALSE。

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

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

1、復(fù)位CAN
CAN復(fù)位會重置CAN驅(qū)動里的各個寄存器值,并執(zhí)行相關(guān)的初始化操作。

在打開CAN的時候,OpenCAN函數(shù)里已經(jīng)調(diào)用了該函數(shù)實現(xiàn)CAN復(fù)位。用戶可以根據(jù)自己應(yīng)用的實際情況,決定在什么時機(jī)執(zhí)行CAN復(fù)位。

2、啟動CAN
在設(shè)置好CAN波特率,環(huán)回,filter等參數(shù)后,CAN驅(qū)動線程并沒有馬上啟動,需要執(zhí)行CAN啟動,CAN線程才開始工作。

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

3、停止CAN
停止CAN會關(guān)閉CAN驅(qū)動線程,在關(guān)閉CAN的時候,CloseCAN函數(shù)調(diào)用CAN停止。

C#代碼

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

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

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

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

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

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

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

6、啟動CAN
當(dāng)準(zhǔn)備就緒,就可以啟動CAN設(shè)備了。
bRet = CAN.CAN_Command(hCAN, (uint)CAN_COMMAND.START);

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

發(fā)CAN數(shù)據(jù)包
調(diào)用WriteFile發(fā)送CAN數(shù)據(jù)包。
bRet = CAN.WriteFile(hCAN, ref pktSend, CAN.sizePacket, ref uLen, 0);

接收CAN數(shù)據(jù)包
調(diào)用ReadFile發(fā)送CAN數(shù)據(jù)包。
bResult = CAN.ReadFile(hCAN, ref pktRev, CAN.sizePacket, ref uLen, 0);

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

id是一個整型4字節(jié),32位,用來記錄CAN通信所需的ID信息。
id的低29位,表示id號。
id的第30位,用來標(biāo)記是接收的數(shù)據(jù)包,還是發(fā)送的數(shù)據(jù)包。
id的第31位,用來設(shè)置是數(shù)據(jù)幀還是遠(yuǎn)程幀。該位為0則是數(shù)據(jù)幀,該位為1則是遠(yuǎn)程幀。
id的第32位,用來設(shè)置是標(biāo)準(zhǔn)幀還是擴(kuò)展幀。該位為0則是標(biāo)準(zhǔn)幀,該位為1則是擴(kuò)展幀。

data為12字節(jié)byte數(shù)組。
data[0]為CAN數(shù)據(jù)包內(nèi)數(shù)據(jù)的長度,取值0-8;
data[1]-data[8],8字節(jié),為CAN數(shù)據(jù)包內(nèi)傳輸?shù)臄?shù)據(jù)。
data[9]-data[11]未使用。

注:結(jié)構(gòu)體這樣設(shè)計的主要原因還是因為要和C代碼的驅(qū)動接口,做成這樣效率會高些。

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

例如,我們要發(fā)送一個,id為55的擴(kuò)展幀,數(shù)據(jù)長度為6,分別是0x04,0x04,0x04,0x05,0x05,0x05,代碼如下:
CAN_MESSAGE pktSend = new CAN_MESSAGE();
pktSend.id = 5;
//如果是數(shù)據(jù)幀就不變,如果是遠(yuǎn)程幀就
//pktSend.id = pktSend.id | 0x20000000;//remote
//如果是標(biāo)準(zhǔn)幀就不變,如果是擴(kuò)展幀就
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設(shè)置
EM335x同樣支持?jǐn)?shù)據(jù)包過濾功能,設(shè)置Filter可以使得CAN只接收自己需要的數(shù)據(jù)包。

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

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

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

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

這里的過濾邏輯如下:

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

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

詳細(xì)信息,可以電話,郵件或論壇提問方式咨詢英創(chuàng)工程師。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式主板
    +關(guān)注

    關(guān)注

    7

    文章

    6100

    瀏覽量

    36296
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    C#上位機(jī)與運(yùn)動控制卡網(wǎng)絡(luò)通訊的周期上報

    使用C#上位機(jī)編程實現(xiàn)運(yùn)動控制卡網(wǎng)絡(luò)通訊的周期上報功能
    的頭像 發(fā)表于 06-26 13:59 ?128次閱讀
    <b class='flag-5'>C#</b>上位機(jī)與運(yùn)動控制卡網(wǎng)絡(luò)<b class='flag-5'>通訊</b>的周期上報

    科普|信創(chuàng)是什么?一文讀懂“信息技術(shù)應(yīng)用創(chuàng)新”戰(zhàn)略

    什么是信創(chuàng)?信創(chuàng),即“信息技術(shù)應(yīng)用創(chuàng)新”,是國家推動IT系統(tǒng)自主可控、安全可控的重要戰(zhàn)略工程。它不僅是技術(shù)層面的創(chuàng)新,更承載著保障國家網(wǎng)絡(luò)安全、推動產(chǎn)業(yè)升級和實現(xiàn)數(shù)字主權(quán)的重任。簡單來
    的頭像 發(fā)表于 06-13 10:06 ?1915次閱讀
    科普|信<b class='flag-5'>創(chuàng)</b>是什么?一文讀懂“<b class='flag-5'>信息技術(shù)</b>應(yīng)用創(chuàng)新”戰(zhàn)略

    基于CAN的娛樂車通信網(wǎng)絡(luò)RV-C介紹

    電子發(fā)燒友網(wǎng)站提供《基于CAN的娛樂車通信網(wǎng)絡(luò)RV-C介紹.pdf》資料免費(fèi)下載
    發(fā)表于 04-19 17:01 ?0次下載

    玩轉(zhuǎn)C#/LABVIEW,斯撩

    **labview軟件開發(fā) C#軟件開發(fā) C#自定義控件Labview調(diào)用 labview和C#組合開發(fā)
    發(fā)表于 04-02 22:44

    如何在C#中部署飛槳PP-OCRv4模型

    《超4萬6千星的開源OCR黑馬登場,PaddleOCR憑什么脫穎而出?》收到了讀者熱烈反響c,很多讀者提出:如何在C#中部署飛槳PP-OCRv4模型?本文從零開始詳細(xì)介紹整個過程。
    的頭像 發(fā)表于 02-17 10:58 ?1777次閱讀
    如何在<b class='flag-5'>C#</b>中部署飛槳PP-OCRv4模型

    C#中使用OpenVINO?:輕松集成AI模型!

    作者:算力魔方創(chuàng)始人/英特爾創(chuàng)新大使劉力 C#不僅在PC游戲開發(fā)、大型商業(yè)系統(tǒng)領(lǐng)域應(yīng)用廣泛,還成為開源測控、機(jī)器視覺與運(yùn)動控制,以及PC數(shù)集與分析領(lǐng)域中的主流開發(fā)語言! 在開源測控、機(jī)器視覺、數(shù)采
    的頭像 發(fā)表于 02-07 14:05 ?846次閱讀
    <b class='flag-5'>C#</b>中使用OpenVINO?:輕松集成AI模型!

    dsPIC33C Touch-CAN-LIN Curiosity開發(fā)板用戶指南

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

    C#通過Halcon實現(xiàn)3D點云重繪

    C# 通過 Halcon 實現(xiàn) 3D 點云重繪
    發(fā)表于 01-05 09:16 ?0次下載

    C#基于Halcon實現(xiàn)Basler相機(jī)采圖

    C#基于Halcon實現(xiàn)Basler相機(jī)采圖
    發(fā)表于 01-05 09:16 ?0次下載

    創(chuàng)C6748開發(fā)板求助

    求助各位大佬,使用創(chuàng)龍的C6748開發(fā)板,運(yùn)行LINE_IN例程,為什么輸入正弦波后,輸出的是雜波
    發(fā)表于 12-27 17:01

    運(yùn)動控制卡網(wǎng)絡(luò)通訊的心跳檢測之C#上位機(jī)編程

    使用C#上位機(jī)編程實現(xiàn)運(yùn)動控制卡網(wǎng)絡(luò)通訊的心跳檢測功能
    的頭像 發(fā)表于 12-24 10:54 ?1111次閱讀
    運(yùn)動控制卡網(wǎng)絡(luò)<b class='flag-5'>通訊</b>的心跳檢測之<b class='flag-5'>C#</b>上位機(jī)編程

    以太網(wǎng)IO控制卡:C#實時讀寫時間測試

    C#語言進(jìn)行ECI IO卡的項目開發(fā)和快速讀取多個IO狀態(tài)與上位機(jī)交互速度的測試結(jié)果
    的頭像 發(fā)表于 11-21 13:50 ?656次閱讀
    以太網(wǎng)IO控制卡:<b class='flag-5'>C#</b>實時讀寫時間測試

    中科創(chuàng)達(dá)榮獲2024年軟件和信息技術(shù)服務(wù)優(yōu)秀企業(yè)

    及前百家企業(yè)”名單。中科創(chuàng)達(dá)憑借非凡的技術(shù)實力與持續(xù)的創(chuàng)新能力,成功入選“2024年度軟件和信息技術(shù)服務(wù)競爭力百強(qiáng)企業(yè)”以及“2024年軟件和信息技術(shù)服務(wù)優(yōu)秀企業(yè)”。
    的頭像 發(fā)表于 10-30 11:44 ?958次閱讀

    加速鯤鵬落地!拓維信息創(chuàng)遷移工具榮獲鯤鵬原生開發(fā)技術(shù)認(rèn)證

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

    技術(shù)分享】CAN總線相關(guān)知識探討以及Model3C兩路CAN的應(yīng)用

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