你說的是這個程序吧:http://www.zg4o1577.cn/bbs/dpj-3033-1.html 首先來理解程序開頭的這句話的意思:“通信協(xié)議: 第1字節(jié),MSB為1,為第1字節(jié)標志,第2字節(jié),MSB為0,為非第一字節(jié)標志,其余類推……,最后一個字節(jié)為前幾個字節(jié)后7位的異或校驗和” 這里說的MSB就是指字節(jié)的最高位!白詈笠粋字節(jié)為前幾個字節(jié)后7位的異或校驗和”也就是說他把每個字節(jié)的最高位當作首字節(jié)的標志用了,因而每個字節(jié)所能表示的數(shù)只有0-127(7個bit),至于最高位的那一個bit,只和是否為首字節(jié)有關(guān),只有首字節(jié)的最高位為“1”其他的字節(jié)最高位都為“0”。
再來看程序,我這里加上一些注釋。 //串口接收中斷函數(shù) void serial () interrupt 4 using 3 //串口中斷號為4,后面的using為寄存器組切換 { if (RI) //判斷是否是接收中斷 { unsigned char ch; //在這里定義了一個 字符變量 “ch” RI = 0 ; //清標志位 ch=SBUF; //這里把接收到的數(shù)據(jù)從串口緩存讀到了變量ch里 if (ch> 127 ) //注意這里,ch>127的話其最高位必須是1才可以。也就是說,只有首字節(jié)才并且必然大于127。換句話說在這里判斷了首字節(jié) { //是首字節(jié)的話。。。 count3= 0 ; //給count3賦初值,這個count3就是用來計數(shù)接收到的字符的個數(shù)的。 inbuf1[count3]=ch; //把接收到的數(shù)據(jù)放到字符串inbuf1[]中,這inbuf1[]他定義的是全局變量,因而可以傳回去。(他好像忘了去掉最高位的首字節(jié)標志了) checksum= ch- 128 ; //這就是計算所謂的校驗和了吧,先把首位放進去,之所以減了個128就是要把最高位的標志減掉,只計算后七位的校驗和。 } else //不是首字節(jié)的話。。。 { count3++; //接收計數(shù)自增 inbuf1[count3]=ch; //隨著每次count3的自增,依次把接收到的數(shù)據(jù)放到字符串inbuf1[]中 checksum ^= ch; //依次按位異或,也就是說每收到一個字節(jié)都拿來異或一下。 if ( (count3==(INBUF_LEN- 1 )) && (!checksum) ) //邏輯表達式有點長啊,最外層是與,每個元素都為真才可以,前面count3==(INBUF_LEN- 1 )也就是說接收到了最后一個字符(他定義的INBUF_LEN =4,count3從0加到3,一共接收了四個字符),后面!checksum當依次按位異或的結(jié)果歸0時才為真。 { read_flag= 1 ; //如果串口接收的數(shù)據(jù)達到INBUF_LEN個,且校驗沒錯, //就置位取數(shù)標志 } } } }
“95 10 20 25” 這是四個字節(jié)的16進制數(shù),全都轉(zhuǎn)成二進制的數(shù)字看的清楚。 95——10010101 10——00010000 20——00100000 25——00100101 看到了吧,只有第一個0x95的最高位是1。其他的幾個字節(jié)最高位都是0。 至于校驗和,你查查每一縱列的1是不是都是偶數(shù)個(當然除了第一列)?偶數(shù)個1異或就是0。
按照這個格式,如果你發(fā)送 95 11 20 24 ,依然能得到返回數(shù)據(jù). 95——10010101 11——00010001 20——00100000 24——00100100
不知道這樣解釋樓主是否明白了?
|