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

           sub short CRC_16(short dataddr, short len)
            short i, j
            unsigned short crc_reg = 0x0000
            unsigned short current
            unsigned char dattmp[128]    //申請(qǐng)一定長(zhǎng)度的數(shù)組來(lái)保存要進(jìn)行校驗(yàn)的數(shù)據(jù)。
            GetData(dattmp[0], "Local HMI", LW, dataddr, len)//將暫存區(qū)的數(shù)據(jù)復(fù)制到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

          上面綠色部分是進(jìn)行CRC計(jì)算的,這里不做研究。下面來(lái)講講紅色部分。紅色部分就是申請(qǐng)數(shù)組空間,然后,將LW,暫存空間的數(shù)據(jù),轉(zhuǎn)移到所申請(qǐng)的數(shù)組中,交給下面計(jì)算。
          這里的疑惑是為何要申請(qǐng)數(shù)組,然后在拷貝數(shù)據(jù),這么麻煩,而不是用下面的方式進(jìn)行,下面的算法是每次循環(huán)開始先讀取暫存空間數(shù)據(jù),先不說(shuō)犧牲時(shí)間什么的,最起碼這
        中不用申請(qǐng)上面那128大的數(shù)組。理論可行,但是實(shí)際上確實(shí)錯(cuò)誤的。其主要GetData和SetData 函數(shù)實(shí)現(xiàn)原理,以及數(shù)據(jù)在LW中存儲(chǔ)方式不清楚造成的。
        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 函數(shù)實(shí)現(xiàn)原理,以及數(shù)據(jù)在LW中存儲(chǔ)方式
        先來(lái)說(shuō)說(shuō)LW中的數(shù)據(jù)存儲(chǔ) (吐槽:為何網(wǎng)上關(guān)于這方面的資料很少,幾乎沒有LW存儲(chǔ)空間的詳細(xì)說(shuō)明)
        目前 筆者使用 軟件 EB8000 V4.65

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


        例如 0x1234 存儲(chǔ)方式為高字節(jié) 0x12 ,低字節(jié)0x34.

        SetData 當(dāng)用SetData 來(lái)寫LW中的數(shù)據(jù)的時(shí)候,會(huì)根據(jù)第一個(gè)參數(shù)的類型來(lái)指導(dǎo)操作

                            如下程序,這是正常的操作程序。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的第一個(gè)參數(shù)是第一個(gè)char類型的數(shù)組如下
        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 型數(shù)據(jù)的時(shí)候,為了節(jié)省空間進(jìn)行了特別處理
        理論上b[0]應(yīng)該保存在LW0000,b[1]保存在LW0001.但是實(shí)際上確實(shí)b[0]保存在 LW0000的低字節(jié),b[1]保存在LW0000的高字節(jié)。

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

        現(xiàn)在能回答為何不能采用第二種子函數(shù)寫法.主要原因是 每次循環(huán)都是讀取一個(gè)字的底字節(jié)。高字節(jié)數(shù)據(jù)被丟棄了。
        假如寫入內(nèi)存的是b[0]到b[10],則通過(guò)下面循環(huán)讀取的是b[0],b[2],b[4].....,請(qǐng)好好體會(huì)。
            for i = 0 to len

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

        再需要調(diào)用CRC函數(shù)的時(shí)候,可用如下的方法操作
                char sendbus[26]

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

        版權(quán)申明:本文章由逸創(chuàng)論壇(www.yeecon.com)原創(chuàng),轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.yeecon.com/forum.php?mod=viewthread&tid=74&fromuid=1
        (出處: 逸控BBS)

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

        主站蜘蛛池模板: 午夜A理论片在线播放| 欧美人与动牲交A免费观看| 丁香五月亚洲综合在线国内自拍 | 亚洲国产一区二区精品专| 精品亚洲精品日韩精品| 女人高潮被爽到呻吟在线观看 | 午夜精品福利亚洲国产| 亚洲一区中文字幕第十页| 国产精品一线二线三线区| 日韩人妻精品中文字幕专区| 九九热免费在线观看视频| 91老熟女老女人国产老| 一区二区三区国产综合在线| A毛片终身免费观看网站| 国产精品日韩av在线播放| 涩涩爱狼人亚洲一区在线| 2021国产精品视频网站| 亚洲日本中文字幕天天更新| 国产精品一级久久黄色片| 正在播放酒店约少妇高潮| 无套内谢极品少妇视频| 日本少妇自慰免费完整版| 无码成人午夜在线观看 | 乱码中文字幕| 亚洲天堂成人黄色在线播放| 不卡一区二区国产精品| 欧美性猛交xxxx乱大交极品| 国产性三级高清在线观看| 粗壮挺进邻居人妻无码| 亚洲中文字字幕精品乱码| 国产乱码1卡二卡3卡四卡5| 亚洲人成电影在线天堂色| 岛国中文字幕一区二区| 国产欲女高潮正在播放| 国产精品白浆无码流出| 色综合天天综合网国产人| 成人福利国产午夜AV免费不卡在线| 高潮精品熟妇一区二区三区| 国产精品福利自产拍久久 | 久久精品国产福利一区二区| 91人妻无码成人精品一区91|