• <cite id="uwv89"></cite>
      1. 亚洲综合小综合中文字幕,国产久爱免费精品视频,精品国产品香蕉在线,国产午夜精品在人线播放,精品一二三四区在线观看,国产成人无码免费看视频软件 ,色欲久久人妻内射,午夜在线观看成人av
        peteryi
        級別: 正式會員
        精華主題: 0
        發帖數量: 7 個
        工控威望: 97 點
        下載積分: 583 分
        在線時間: 2(小時)
        注冊時間: 2014-10-28
        最后登錄: 2019-07-31
        查看peteryi的 主題 / 回貼
        樓主  發表于: 2014-10-28 19:56
        最近手上有個威綸通MT6056I的HMI,需要與公司的一款板卡通訊,板卡遵循的是自由協議,但是采用的校驗方式CRC-16/XMODEM.
        這種校驗方式是CRC16校驗方式的一種,但是與MODBUS協議的CRC16的生成方式不同。威綸通的腳本語言庫中有CRC校驗函數,但是這個校驗
        函數是CRC-16/MODBUS版本的,不能為我所用,所以我計劃自己設計一個CRC16/XMODEM的函數,然后將這個函數保存到函數庫里,以備他用
        。由于第一次使用這個屏幕,經驗不做,遇到一些困難,但也努力解決了。
                首先不得不吐槽下,威綸通的宏指令說明書寫的太簡單了,在遇到問題的時候,可能無法從指令的說明手冊上找到答案,更多的是自己摸索。比如
        自己寫子函數時就遇到狗血的問題
               1:數組不能作為函數參數
                    比如
                                sub short function(char dat[],char len)
                    其中 char dat[] 參數將出錯。
                    解決方法,后面有表述
               2: 在調用子函數的時候,在函數的參數中不能出現常量,只能是變量的方式
                   例如我定義了子函數 function( short a,short b)
                   調用方式  function( 1000,1000)  編譯器將會告訴你參數類型錯誤
                   當我改成如下掉用方式就可以了
                    short i=1000
                    short j=1000
                    function(i,j)
          
              好進入正題吧,如何寫個CRC校驗函數,其實根本問題,是如何將一串數據傳給子函數,子函數將傳過來的數據根據特定算法,運算出計算結果,關于CRC算法,本文不做論述,只提供代碼。
        我首先想到的是這樣的思路:定義 這樣一個函數 short CRC16(short dat[],short len),用來計算CRC。
        但是卻遇到了上面1中的問題,數組參數無法作為函數的形參,官方也找不到解決方法。
        最后想到的解決方法是在LW存儲區開辟一塊暫存區域,將要進行CRC計算的數據搬運到這塊暫存區域上。再CRC校驗函數中根據LW的地址將數據取出,進行CRC計算。
        如此可解決無法傳遞數組參數的問題。操作如下。
                定義  sub short CRC_16(short dataddr, short len)
               參數說明 short dataddr,dataddr是位于LW暫存區的起始地址,short len len 數據長度。
                 下面紅色區域為重點區域,注意理解。

           sub short CRC_16(short dataddr, short len)
            short i, j
            unsigned short crc_reg = 0x0000
            unsigned short current
            unsigned char dattmp[128]    //申請一定長度的數組來保存要進行校驗的數據。
            GetData(dattmp[0], "Local HMI", LW, dataddr, len)//將暫存區的數據復制到dattmp中

            len=len-1
            for i = 0 to len
                current = dattmp
                current=current<<8
                crc_reg=crc_reg^current
              
                for j = 1 to 8
              
                    if (crc_reg & 0x8000) <> 0 then
                        crc_reg = (crc_reg << 1) ^ 0x1021
                    else
                        crc_reg=crc_reg << 1
                    end if
                next
              

            next
            return crc_reg;
        end sub

          上面綠色部分是進行CRC計算的,這里不做研究。下面來講講紅色部分。紅色部分就是申請數組空間,然后,將LW,暫存空間的數據,轉移到所申請的數組中,交給下面計算。
          這里的疑惑是為何要申請數組,然后在拷貝數據,這么麻煩,而不是用下面的方式進行,下面的算法是每次循環開始先讀取暫存空間數據,先不說犧牲時間什么的,最起碼這
        中不用申請上面那128大的數組。理論可行,但是實際上確實錯誤的。其主要GetData和SetData 函數實現原理,以及數據在LW中存儲方式不清楚造成的。
        sub short CRC_16_2(short dataddr, short len)
            short i, j
            unsigned short crc_reg = 0x0000
            unsigned short current
            unsigned char dattmp
            short addr
            addr=dataddr
            len=len-1
          
            for i = 0 to len

               GetData(dattmp, "Local HMI", LW, addr, 1)
                addr=addr+1
                current = dattmp

                current=current<<8
                crc_reg=crc_reg^current
              
                for j = 1 to 8
              
                    if (crc_reg & 0x8000) <> 0 then
                        crc_reg = (crc_reg << 1) ^ 0x1021
                    else
                        crc_reg=crc_reg << 1
                    end if
                next
              
            next
            return crc_reg;
        end sub



        GetData和SetData 函數實現原理,以及數據在LW中存儲方式
        先來說說LW中的數據存儲 (吐槽:為何網上關于這方面的資料很少,幾乎沒有LW存儲空間的詳細說明)
        目前 筆者使用 軟件 EB8000 V4.65

        LW 可理解為計算機的RAM ,掉電數據不保存,但是存取速度快。每個存儲單元是16bit。分為高字節 (bit15-bit8)和低字節(bit7 -bit 0)
        bit15                                                            bit0


        例如 0x1234 存儲方式為高字節 0x12 ,低字節0x34.

        SetData 當用SetData 來寫LW中的數據的時候,會根據第一個參數的類型來指導操作

                            如下程序,這是正常的操作程序。a的類型是short
        unsigned short a=0x1234
        unsigned char b[2]
        unsigned char c
        SetData(a, "Local HMI", LW, 0, 1)
        GetData(c, "Local HMI", LW, 0, 1)
        GetData(b[0], "Local HMI", LW, 0, 2)
        TRACE("C = %d", c)                    //c=0x34
        TRACE("b[0] = %d", b[0])          //b[0]=0x34
        TRACE("b[1] = %d", b[1])         //b[1]=0x12

        但是SetData的第一個參數是第一個char類型的數組如下
        unsigned short a
        unsigned char b[2]
        b[1]=0x12
        b[0]=0x34
        SetData(b[0], "Local HMI", LW, 0, 2)
        GetData(a, "Local HMI", LW, 0, 1)
        TRACE("a = %d", a) //a=0x1234

        可以看出,在保存char 型數據的時候,為了節省空間進行了特別處理
        理論上b[0]應該保存在LW0000,b[1]保存在LW0001.但是實際上確實b[0]保存在 LW0000的低字節,b[1]保存在LW0000的高字節。

        同樣的道理GetData 也遵循相同的操作。

        現在能回答為何不能采用第二種子函數寫法.主要原因是 每次循環都是讀取一個字的底字節。高字節數據被丟棄了。
        假如寫入內存的是b[0]到b[10],則通過下面循環讀取的是b[0],b[2],b[4].....,請好好體會。
            for i = 0 to len

               GetData(dattmp, "Local HMI", LW, addr, 1)
                addr=addr+1
                current = dattmp
            next

        再需要調用CRC函數的時候,可用如下的方法操作
                char sendbus[26]

                short lwadd=7000 //lw 暫存區開始地址
                short len=26        
                SetData(sendbuf[1], "Local HMI", LW, lwadd, len)   //將得計算的數阻搬到LW7000開始的空間,具體在什么地址,可自己安排,只要注意LW 范                                                                                        //0-9000
                tmp = CRC_16(lwadd, len)                                //CRC計算

        版權申明:本文章由逸創論壇(www.yeecon.com)原創,轉載請標明出處:http://www.yeecon.com/forum.php?mod=viewthread&tid=74&fromuid=1
        (出處: 逸控BBS)

        由于本人知識有限,文中如有錯誤,請告知。
        作者:semonpic    
        E-Mail: semonping@163.com
        企鵝號 442999791
        [ 此帖被peteryi在2014-10-28 20:45重新編輯 ]

        主站蜘蛛池模板: 高清有码国产一区二区| 色综合天天色综合久久网| аⅴ天堂中文在线网| 亚洲欧美成人a∨观看| 日韩女同在线二区三区| 亚洲精品香蕉一区二区| 亚洲中文字幕国产综合| 四虎国产精品永久在线下载| 四虎在线中文字幕一区| 久青草视频在线视频在线| 国产麻豆一区二区精彩视频| 热久久这里只有精品99| 亚洲精品成人一二三专区| 亚洲精品tv久久久久久久久久| 99久久99久久久精品久久| 国产亚洲精品成人aa片新蒲金| 国产精品亚洲av三区色| 国内自拍小视频在线看| 国产真实伦在线观看视频| 亚欧洲乱码视频一二三区| 亚洲国产日韩一区三区| 成人免费无码大片A毛片抽搐色欲| 国产成人精品中文字幕| 99久久久国产精品免费无卡顿| 亚洲欧洲日韩精品在线| 草草浮力影院| 亚洲国产超清无码专区| 国语精品自产拍在线观看网站| 中文字幕国产精品自拍| 久久综合久中文字幕青草| 国产亚洲精品AA片在线播放天| 翘臀少妇被扒开屁股日出水爆乳| 美女爽到高潮嗷嗷嗷叫免费网站| 虎白女粉嫩尤物福利视频| 亚洲成人免费一级av| 精品国产精品中文字幕| 国产精品SM捆绑调教视频| 99久久亚洲综合精品成人网| 精品人妻中文字幕在线| 国产精品午夜福利合集| 成人无码午夜在线观看|