性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

串口通信CRC校驗大小端之分

      從沒想過串口通信CRC校驗不通過是因為大小端引起的,真是好痛的領(lǐng)悟。。。假設(shè)你是玩單片機的,又和安卓屏或者其它類型的屏幕通信,那要注意了。對方的通信協(xié)議數(shù)據(jù)可能是這樣定義的:

  data.D1_SN = Mcont.chipId;
  data.D2_warning = Mcont.warning;      
  data.D3_fliter_time = Mcont.save_data.filter_time;
  data.D4_ecell_time  = Mcont.save_data.vtimer_all;
  data.D5_mcu1_ver = MCU1_SVER;
  data.D6_muc2_ver = Mcont.slave.D16_ver;
  data.D7_main_state = Mcont.status;
  data.D8_work_state = Mcont.point;

      data.Dx:內(nèi)存有可能是一個字節(jié),也有可能是兩個以上的字節(jié),假設(shè)是兩個字節(jié),數(shù)據(jù)只發(fā)送一個uint16_t類型的數(shù)據(jù),數(shù)值為0x1234,那么這個數(shù)據(jù)通過串口實際的輸出是什么?

串口發(fā)送: 第一個字節(jié)     第二個字節(jié)

                     0x12                0x34(大端)

                     0x34                0x12(小端)

      實際痛苦的經(jīng)歷是這樣的,接收數(shù)據(jù)和發(fā)送方確認是對的,但是CRC校驗無論如何都通不過,經(jīng)過一番仔細操作后發(fā)現(xiàn),CRC校驗高低字節(jié)順序是不對的,于是呼呼呼。。。問發(fā)送端要了他的CRC校驗代碼(實錘了):

//***CRC校驗 CRC16-MODBUS類型  eof為幀尾0表示沒有  web尾0x23    endian 大小端模式 0大端 1小端**********************************************
void addCrc16_MODBUS(uint8_t *data1, uint16_t len,uint8_t eof,uint8_t endian)
{
    uint16_t i, pos, crc = 0xFFFF;

    for (pos = 0; pos < len; pos++)
    {
        if ((signed char)data1[pos] < 0)
        {
            crc ^= (int)((signed char)data1[pos]) + 256;
        }
        else
            crc ^= (int)((signed char)data1[pos]);
        for (i = 8; i != 0; i--)
        {
            if ((crc & 0x0001) != 0)
            {
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
                crc >>= 1;
            }
        }
    }
    if(endian)
    {
    data1[len] = crc;
    data1[len + 1] = crc >> 8;
    }
    else{
    data1[len] = crc >> 8;
    data1[len + 1] = crc;
    }

    if(eof)
    data1[len + 2] = eof; //幀尾
}

第一次見CRC還有帶大小端轉(zhuǎn)換的功能,長見識了:

我們接觸大部分單片機都是小端模式,但是也有大端模式例如經(jīng)典的51單片機。

如何寫一段代碼判斷設(shè)備是大端還是小端模式:

    #include <stdio.h>
    int main(){
        union{
            int n;
            char ch;
        } data;
        data.n = 0x00000001;  //也可以直接寫作 data.n = 1;
        if(data.ch == 1){
            printf("Little-endian\n");
        }else{
            printf("Big-endian\n");
        }
        return 0;
    }

在電腦上的運行結(jié)果是:

Little-endian

實際大小端模式在內(nèi)存中的區(qū)別如下:

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 4
收藏 7
關(guān)注 150
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧