<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>
  • CAN接口COM組件在WinCE平臺(tái)上的實(shí)現(xiàn)

     2009-7-15              
            控制器局域網(wǎng)(CAN)是一個(gè)串行、異步、多主的通信協(xié)議,它以其高性能、高可靠性以及靈活的設(shè)計(jì)受到人們的重視,應(yīng)用越來越廣泛。英創(chuàng)公司的ARM9工控主板如EM9161,EM9260等均支持CAN總線接口,并實(shí)現(xiàn)了基于Windows CE規(guī)范的流式驅(qū)動(dòng)程序(Stream Device Driver),對于大多數(shù)基于C/C++開發(fā)環(huán)境的應(yīng)用,英創(chuàng)公司以靜態(tài)庫can_api.lib形式提供了相應(yīng)接口函數(shù),客戶通過相應(yīng)的API函數(shù)即可完成對CAN接口的操作。但對于使用像C#這樣高級語言的應(yīng)用,由于一般不支持靜態(tài)庫的調(diào)用,因此需要新的方法來解決這個(gè)問題。我們目前采用的基本方法是在該靜態(tài)庫的基礎(chǔ)上,針對CAN通訊接口的數(shù)據(jù)收發(fā)以及對出錯(cuò)情況監(jiān)測的應(yīng)用,封裝一個(gè)基于CAN通訊接口應(yīng)用的COM組件,該組件中提供了一套更為簡潔的接口方法函數(shù),可以方便多種開發(fā)工具的調(diào)用,如:C#、VB、LabView等。使用時(shí)客戶只需在系統(tǒng)中一次性注冊該組件,并在應(yīng)用程序中引用對應(yīng)的DLL或TLB文件,就能方便使用其相應(yīng)的接口方法函數(shù)了。

            本文介紹的基于英創(chuàng)工控主板CAN通訊接口的COM組件提供五個(gè)接口方法函數(shù):打開CAN接口,關(guān)閉CAN接口,向CAN接口寫數(shù)據(jù),從CAN接口讀取數(shù)據(jù)以及讀取接口錯(cuò)誤代碼??蛻舴秸{(diào)用COM組件打開CAN接口后,COM組件服務(wù)器便在組件內(nèi)部創(chuàng)建兩個(gè)線程,一個(gè)用于接收CAN接口數(shù)據(jù),一個(gè)用于CAN通訊錯(cuò)誤處理。數(shù)據(jù)接收線程里通過WaitForSingleObject來等待CAN接口的接收事件發(fā)生,當(dāng)CAN接口收到數(shù)據(jù)后,將數(shù)據(jù)放入指定的接收數(shù)據(jù)緩存中,客戶通過調(diào)用讀數(shù)據(jù)函數(shù),將數(shù)據(jù)從緩存中讀出。后面會(huì)對各函數(shù)做詳細(xì)的說明。

    1、數(shù)組作為組件參數(shù)

            作為通信類組件,數(shù)組常常作為接口方法函數(shù)參數(shù)傳遞,以交換數(shù)據(jù),COM 組件是運(yùn)行在分布式環(huán)境中的,對于一個(gè)組件程序(DLL或EXE),使用者可能是在本機(jī)的某個(gè)進(jìn)程內(nèi)加載組件(INPROC_SERVER),也可能是從另一個(gè)進(jìn)程中調(diào)用組件的進(jìn)程(LOCAL_SERVER),也可能是在這臺(tái)計(jì)算機(jī)上調(diào)用遠(yuǎn)程計(jì)算機(jī)上的組件(REMOTE_SERVER),同時(shí),組件也可能是跨語言調(diào)用的,因此對于將數(shù)組作為組件參數(shù)傳遞時(shí)與我們常用的參數(shù)傳遞方法有較大區(qū)別。

            在C語言中,通常用數(shù)組名作為函數(shù)參數(shù)。如下例程,求10次得分的總和。

          int Sum( int array[10] )
          {
                int i, sum;
                for( sum =0, i = 0;i<10; i++ )
                sum += array[i];
                return( sum );
          }

          main( )
          {
                int sum;
                int score[10] = {75,80,81,76,75,86,90,77,80,81};
                sum = Sum( score );
          }

            例中array是主調(diào)函數(shù)中的實(shí)參數(shù)組名,在被調(diào)函數(shù)中聲明了形參數(shù)組,且大小為10,但實(shí)現(xiàn)上,在形參中指定數(shù)組大小不起任何作用,因?yàn)閿?shù)組名作為實(shí)參傳遞時(shí),僅是把實(shí)參數(shù)組的起始地址傳遞給形參數(shù)據(jù),所以被調(diào)函數(shù)也可以聲明成如下形式:Sum( int array[ ] )或Sum( int *array )。

            在COM組件中,缺省情況下,指針參數(shù)總是被假設(shè)為指向單個(gè)實(shí)例的指針,而不是數(shù)組,在參數(shù)中傳遞一個(gè)數(shù)據(jù)最簡單的方法是使用固定數(shù)組技術(shù),也就是在參數(shù)中指名數(shù)組維數(shù)信息。假設(shè)Sum為一組件接口方法函數(shù),則其接口就應(yīng)該描述為:HRESULT Sum( [in] int array[10] )。然而,當(dāng)你自己用C++寫一個(gè)COM組件程序(dll形式),然后再用C++來本地調(diào)用(準(zhǔn)確的說是套間內(nèi)調(diào)用)這個(gè)組件是,也可以將接口方法描述為:HRESULT Sum( [in] int array[] )或HRESULT Sum( [in] int *array),并且程序也能得到正常的運(yùn)行結(jié)果,但這樣的接口方法描述存在兩個(gè)問題:1、當(dāng)用C#引用組件的DLL或TLB時(shí),array會(huì)被認(rèn)為是個(gè)指針,而在C#中聲明的數(shù)組,數(shù)組名不能作為實(shí)參傳遞。2、當(dāng)這個(gè)方法函數(shù)是跨套間調(diào)用時(shí),接口代理僅會(huì)將array[0]的值解析出來,通過COM的RPC通信協(xié)議將數(shù)據(jù)發(fā)送到COM服務(wù)器存根,此時(shí)在接口方法內(nèi)再操作其它array元素將出錯(cuò)。所以正確的接口描述應(yīng)該是HRESULT Sum( [in] int array[10] ),接口代理總是在OPRC請求消息中分配10*sizeof(int)個(gè)字節(jié)空間,將后把10個(gè)元素一起拷貝到消息中,一旦服務(wù)器收到些ORPC請求消息,接口存根直接用接收到的緩沖區(qū)作為函數(shù)的參數(shù)。

            固定數(shù)組是最簡單,最緊湊,執(zhí)行效率最高的數(shù)據(jù)表示形式,除了固定數(shù)組外,還可以采用可變數(shù)組、開放數(shù)組、安全數(shù)組等作為組件方法函數(shù)參數(shù)來傳遞一個(gè)數(shù)組,在本例中,由于CAN協(xié)議規(guī)定了一幀數(shù)據(jù)最多不會(huì)超過13個(gè)字節(jié)長度,因此采用13個(gè)字節(jié)的固定數(shù)組是一個(gè)較好的選擇。對于其它類型數(shù)組請參考相應(yīng)資料。

    2、CAN組件接口方法函數(shù)

    (1)StartCAN( /*[in]*/ UINT canNo, /*[in]*/ UCHAR baud, /*[in]*/ BYTE acceptanceFilter[9],
                             /*[in]*/ BYTE size, /*[out,retval]*/ BOOL *pBool )

          功能描述:打開指定CAN接口。

          參數(shù)說明:
          /*[in]*/ UINT canNo  設(shè)置要打開的CAN接口號(hào)
          canNo =1 :主板上帶的CAN接口
                     =2 :通過ISA總線擴(kuò)展的CAN接口
          /*[in]*/ UCHAR baud 設(shè)置通訊波特率
          baud  = 0 :10Kbps        1 :20Kbps       2 :50bps
                       3 :100bps        4 :125Kbps      5 :250Kbps
                       6 :500bps        7:1Mbps
          /*[in]*/BYTE acceptanceFilter[9] 根據(jù)通訊報(bào)文格式定義過濾器的配置,定義為9個(gè)字節(jié)的過濾器,其中前4個(gè)字節(jié)用于定義過濾器的接收碼,后4個(gè)字節(jié)用于定義過濾器的接收屏蔽碼,最后一個(gè)字節(jié)用于定義選擇單/雙濾波模式。
          acceptanceFilter[8] = 0:雙濾波
                                         = 1:單濾波
          /*[in]*/BYTE size定義的過濾器的大小(應(yīng)該設(shè)置為9)
          /*[out,retval]*/BOOL *pBool  CAN接口打開成功/失敗標(biāo)志
          TRUE:CAN接口打開成功
          FALSE:CAN接口打開失敗

    (2)WriteCAN(/*[in]*/ BYTE buf[13], /*[in]*/ DWORD bufLen, /*[out,retval]*/ BOOL *pBool )

          功能描述:向CAN接口寫數(shù)據(jù)

          參數(shù)說明:
          /*[in]*/ BYTE buf[13] 準(zhǔn)備通過CAN接口發(fā)送的數(shù)據(jù)包
          /*[in]*/ DWORD bufLen 發(fā)送數(shù)據(jù)包長度
          /*[out,retval]*/ BOOL *pBool 數(shù)據(jù)發(fā)送成功/失敗標(biāo)志
          TRUE:數(shù)據(jù)發(fā)送成功
          FALSE:數(shù)據(jù)發(fā)送失敗

    (3)ReadCAN( /*[out]*/ BYTE buf[13], /*[out,retval]*/ BOOL *pBool )

          功能描述:從接收緩存中讀取一幀CAN接口數(shù)據(jù)

          參數(shù)說明:
          /*[out]*/ BYTE buf[13] 數(shù)據(jù)接收緩存(緩存區(qū)需大于13個(gè)字節(jié))
          /*[out,retval]*/ BOOL *pBool CAN接口是否有數(shù)據(jù)標(biāo)志
          TRUE:CAN接口收到數(shù)據(jù)(返回值為TRUE時(shí)需再次調(diào)用本函數(shù),直到返回值FLASH,以將數(shù)據(jù)全部讀出)
          FALSE:CAN接口沒有收到數(shù)據(jù)

    (4)GetErrorCode(/*[out]*/ DWORD *ECCRegCode,/*[out]*/ DWORD errorArray[16],
                                   /*[out,retval]*/ int *errorCount)

          功能描述:得到錯(cuò)誤代碼

          參數(shù)說明:
          /*[out]*/ DWORD *ECCRegCode  CAN接口中錯(cuò)誤代碼捕捉寄存器的值
          /*[out]*/ DWORD errorArray[16] 最近16次的CAN接口通訊錯(cuò)誤編碼(緩存區(qū)需大于16個(gè)字節(jié))
          /*[out,retval]*/ int *errorCount 總錯(cuò)誤次數(shù)

    (5)StopCAN( )

          功能描述:關(guān)閉CAN通訊接口

    3、CAN組件調(diào)用

            在使用COM組件之前需要注冊組件,COM組件的注冊過程請參考本網(wǎng)站相關(guān)文章或參考相應(yīng)書籍,這里不再贅述。下面是在EVC中調(diào)用CAN組件接口方法函數(shù)的一些程序片段。

          //從Program ID得到Class ID 
          hr = CLSIDFromProgID( OLESTR( ' ComCAN.CoCAN ' ), &clsid );
          if( FAILED( hr ) )
          {
                return -1;
          }

          //從Class ID得到ICoSerial接口指針
          hr = CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(ICoCAN ),
                                                ( void** )&pICoCAN );
          if( FAILED( hr ))
          {
                return -1;
          }

          //打開CAN接口
          //過濾器設(shè)置
          Filter[0] = 0;         // ACR0
          Filter[1] = 0x5f;    // ACR1
          Filter[2] = 0;         // ACR2
          Filter[3] = 0x1f;    // ACR3
          Filter[4] = 0xff;     // AMR0
          Filter[5] = 0xff;     // AMR1
          Filter[6] = 0xff;     // AMR2
          Filter[7] = 0xff;     // AMR3
          Filter[8] = DUAL_FILTER_MODE; // 設(shè)置濾波器模式
          Baud = CAN_TIMING_250K;      // 波特率:250Kbps
          CanNo = 1; 
          bResult = pICoCAN->StartCAN( CanNo, Baud, (BYTE*)Filter, 9 );
          if( !bResult )
                return -1;

          //數(shù)據(jù)接收和發(fā)送
          while( TURE )
          {
                bResult = pICoCAN->ReadCAN( (BYTE*)buf );
                if( bResult )
                {
                      dLen = buf[0]&0x0f;
                      if( buf[0]&0x80 )     // 擴(kuò)展幀
                      {
                            pICoCAN->WriteCAN( (BYTE*)buf, dLen+5 );
                      }
                      else        // 標(biāo)準(zhǔn)幀
                      {
                            pICoCAN->WriteCAN( (BYTE*)buf, dLen+3 );
                      }
                }
                Sleep( 10 );
          }
    国产精品9999久久久久仙踪林| 国产成人精品高清在线观看93| 99精品热这里只有精品| 国产偷国产偷精品高清尤物| 国产精品国产三级国快看| 亚洲精品国产情侣av在线| 精品久久一区二区三区| 亚洲国产精品一区二区九九| 国产精品民宅偷窥盗摄| 精品免费人成视频app| 国产精品扒开腿做爽爽爽视频| 老司机精品福利在线| 亚洲国产aⅴ成人精品无吗 | 国产午夜久久精品| 久久精品桃花综合| 91精品国产91久久久久久蜜臀| 国产亚洲精品xxx| 久久丝袜精品中文字幕| www久久只有这里有精品| 国产精品成人四虎免费视频| 精品熟人妻一区二区三区四区不卡 | 亚洲精品综合一二三区在线 | 国产A级毛片久久久精品毛片| 国模吧一区二区三区精品视频| 精品福利一区二区三区免费视频 | 男人的天堂精品国产一区| 久久精品女人天堂AV| 人妻无码久久精品人妻| 国产成人精品1024在线| 91精品国产91久久久久久青草| 无码精品一区二区三区免费视频| 久久国产精品久久国产精品| 亚洲精品无码mv在线观看网站| 久久久久无码精品| 久久亚洲精品无码观看不卡| 国产精品极品美女自在线观看免费| 国产精品100页| 无码AⅤ精品一区二区三区| 国产成人一区二区动漫精品| 动漫精品一区二区三区3d| 步兵精品手机在线观看|