欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: 51單片機(jī)控制74LS164芯片輸出64位的數(shù)組 [打印本頁]

作者: izhonguo    時間: 2019-2-12 02:37
標(biāo)題: 51單片機(jī)控制74LS164芯片輸出64位的數(shù)組
本帖最后由 izhonguo 于 2019-3-7 00:59 編輯

各位大神新年好,想請教一個簡單的程序如何寫。想利用51單片機(jī)的P00和P01兩個串口輸出一個16位的數(shù)組【0 0 0 1 1 1 0 0 ****】等數(shù)據(jù),然后利用LS164這個芯片實現(xiàn)并口輸出,寫的程序如下,請各位大佬看一下是哪里有問題,為何不能按照想要的結(jié)果輸出?

#include <reg52.h>
sbit LS164_DATA = P0^0;  //74LS164數(shù)據(jù)線
sbit LS164_CLK = P0^1;  //74LS164時鐘線


/********************************************************************
* 名稱 : delay()
* 功能 : 延時
* 輸入 : i
* 輸出 : 無
***********************************************************************/


void LS164_Write(unsigned long state, unsigned long state2)  //74LS164寫32位擴(kuò)展引腳函數(shù)
{
        unsigned char i;
        for(i=0;i<32;i++)  //循環(huán)寫后32位擴(kuò)展引腳狀態(tài)
        {
                LS164_CLK = 0;
                if(state2 & 0x00000001)
                {
                        LS164_DATA = 1;
                }
                else
                {
                        LS164_DATA = 0;
                }
                LS164_CLK = 1;
                state2 = state2>>1;
        }
        for(i=0;i<32;i++)  //循環(huán)寫前32位擴(kuò)展引腳狀態(tài)
        {
                LS164_CLK = 0;
                if(state & 0x00000001)
                {
                        LS164_DATA = 1;
                }
                else
                {
                        LS164_DATA = 0;
                }
                LS164_CLK = 1;
                state = state>>1;
        }
}

/********************************************************************
* 名稱 : Main()
* 功能 : 主函數(shù)
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void main(void)
{
        unsigned char state_in[] = {0,0,0,0,0,0,0,1,
                                                                0,0,0,0,0,0,1,1,
                                                                0,0,0,0,0,1,1,1,
                                                                0,0,0,0,1,1,1,1,
                                                                1,0,0,0,0,0,0,0,
                                                                1,1,0,0,0,0,0,0,
                                                                1,1,1,0,0,0,0,0,
                                                                1,1,1,1,0,0,0,0};
        unsigned char j;
        unsigned long state=0x0;         //0x0103070F
        unsigned long state2=0x0;         //0x80C0E0F0
        LS164_Write(0x0,0x0);  //所有繼電器無動作,開關(guān)常閉NC(24V接NO)
        for(j=0;j<32;j++)  //循環(huán)寫數(shù)組內(nèi)前32位的狀態(tài)為一個32位的long類型的4字節(jié)(32bit)
        {
                if(state_in[j]==1)
                {
                        state = state^(0x80000000>>j); //按位異或運算:兩個二進(jìn)制位不同時,結(jié)果為 1,相同時結(jié)果為 0。例如0^1為1,0^0為0,1^1為0。
                }
        //        state=0x01;
        //        LS164_Write(state);
        }
        for(j=32;j<64;j++)  //循環(huán)寫數(shù)組內(nèi)前32位的狀態(tài)為一個32位的long類型的4字節(jié)(32bit)
        {
                if(state_in[j]==1)
                {
                        state2 = state2^(0x80000000>>(j-32));
                }
        //        state=0x01;
        //        LS164_Write(state);
        }
        LS164_Write(state,state2);
//        state=0x10;         //1 0 0 0 0 0 1 1
        while(1);
//        {
//                   LS164_Write(state);
//                delayms(100);
//        }
}




異或運算.png (69.55 KB, 下載次數(shù): 54)

異或運算

異或運算

作者: wulin    時間: 2019-2-12 16:54
標(biāo)題與內(nèi)容描述不符,內(nèi)容描述與程序不符,程序中數(shù)據(jù)類型定義與實際需要不符,看不明白樓主最終目的是什么。
作者: izhonguo    時間: 2019-2-12 18:08
用仿真跑的輸入結(jié)果顯示是正確的,但是把相同的hex文件燒入單片機(jī)去控制真實的LS164卻出現(xiàn)不一樣的結(jié)果,這個是為什么呢?

TIM截圖20190212180715.png (51.66 KB, 下載次數(shù): 51)

TIM截圖20190212180715.png

作者: yaoji123    時間: 2019-2-13 07:39
AT89C52的P0口在用時要加上拉電阻,否則電平不對
作者: izhonguo    時間: 2019-2-13 15:36
wulin 發(fā)表于 2019-2-12 16:54
標(biāo)題與內(nèi)容描述不符,內(nèi)容描述與程序不符,程序中數(shù)據(jù)類型定義與實際需要不符,看不明白樓主最終目的是什么 ...

總工程師您好,因為自己一直再改代碼,所以最終放上去的一個和題目描述的不對,就是我現(xiàn)在需要處理一個64位的數(shù)組,這里面隨機(jī)的分布著0或者1, 然后我需要8個LS164的位移芯片共計64個輸出端口上輸出這個數(shù)組里的高電平和低電平。仿真結(jié)果我看是正確的,但是打上實物,用萬用表量LS164的輸出端口電壓不能和仿真上的結(jié)果一樣。

64位數(shù)組.png (158.65 KB, 下載次數(shù): 41)

64位數(shù)組.png

作者: izhonguo    時間: 2019-2-13 15:40
yaoji123 發(fā)表于 2019-2-13 07:39
AT89C52的P0口在用時要加上拉電阻,否則電平不對

您好,請問P0的上拉電阻如何接線?是和51單片機(jī)的最小系統(tǒng)里的上拉電阻一樣接法就可以嗎?直接插一個10KΩ的電阻接地就可以嗎?謝謝!
作者: izhonguo    時間: 2019-2-13 17:29
這兩天又改了一下代碼,現(xiàn)在可以正確按照順序輸出我自己定義的64bit的數(shù)組里面的0或者1,但是我有個疑問想向論壇的大牛確認(rèn)一下,這樣子用位移寄存器的64個輸出端一個一個推出我64bit數(shù)組里的高電平和低電平取控制比如說5V的繼電器的閉合狀態(tài)的話,會不會導(dǎo)致位移高電平過程中,意外導(dǎo)致其他繼電器不斷被打開。比如說不幸情況下64bit的數(shù)組最右的是個1,然后我需要推64步才能把這個1推到我第8塊的74LS164芯片的第八位輸出上,但是推這個1到指定位置的時候不是要經(jīng)過前面63個位置嗎?這樣這63個位置的繼電器不是都要被觸發(fā)一遍嗎?還望各位大佬耐心指點。多謝!
還有一個問題,我用這個生成的HEX文件燒入單片機(jī)然后在面包板上測量LS164輸出的電壓,發(fā)現(xiàn)和仿真結(jié)果完全不同,是亂七八槽的。是仿真有問題還是實物接線有其他特別需要注意的地方(74LS164在面包板上的接線檢查了很多遍,應(yīng)該不會有問題)。再次感謝大家的時間。



64位數(shù)組.png (116.32 KB, 下載次數(shù): 57)

64位數(shù)組.png

作者: wulin    時間: 2019-2-13 20:39
izhonguo 發(fā)表于 2019-2-13 15:36
總工程師您好,因為自己一直再改代碼,所以最終放上去的一個和題目描述的不對,就是我現(xiàn)在需要處理一個64 ...

建議改用74HC595連級輸出。ST_CP(12腳):上升沿時移位寄存器的數(shù)據(jù)進(jìn)入數(shù)據(jù)存儲寄存器,下降沿時存儲寄存器數(shù)據(jù)不變。通常將ST_CP置為低電平,這樣在移位過程中各輸出端狀態(tài)保持不變,當(dāng)移位結(jié)束后,在ST_CP端產(chǎn)生一個正脈沖(5V時,大于幾十納秒就行了。通常都選微秒級),更新輸出數(shù)據(jù)。
作者: wulin    時間: 2019-2-14 08:48
izhonguo 發(fā)表于 2019-2-13 17:29
這兩天又改了一下代碼,現(xiàn)在可以正確按照順序輸出我自己定義的64bit的數(shù)組里面的0或者1,但是我有個疑問想 ...

你的上述疑問是真實存在的,如果改用74HC595連級輸出可以解決你的上述疑問。給你一個示例程序和仿真。




#include <reg51.H>
#define uint unsigned int
#define uchar unsigned char
sbit        P_HC595_SER   = P0^0;
sbit        P_HC595_SRCLK = P0^1;
sbit        P_HC595_RCLK  = P0^2;

/*******************定義8個字節(jié)64 bit緩存數(shù)組*************************/
uchar data dis_buf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//

/**************** 向HC595發(fā)送一個字節(jié)函數(shù) ******************/
void Send_595(uchar dat)
{               
        uchar i;
        for(i=0;i<8;i++)
        {
                dat <<= 1;
                P_HC595_SER  = CY; //溢出位賦值數(shù)據(jù)輸出端
                P_HC595_SRCLK = 1; //移位時鐘
                P_HC595_SRCLK = 0;
        }
}
/**************** 向HC595發(fā)送八個字節(jié)函數(shù) ******************/
void DisplayScan()
{       
        uchar j;
        for(j=0;j<8;j++)
        {
                Send_595(dis_buf[j]);//向HC595發(fā)送一個字節(jié)
        }
        P_HC595_RCLK = 1;//鎖存輸出數(shù)據(jù)
        P_HC595_RCLK = 0;
}

void main()
{
        P_HC595_SRCLK = 0;//初始化移位時鐘端
        P_HC595_RCLK  = 0;//初始化鎖存輸出端
        DisplayScan();                //發(fā)送八個字節(jié)
        while(1);
}


作者: izhonguo    時間: 2019-2-19 20:47
wulin 發(fā)表于 2019-2-14 08:48
你的上述疑問是真實存在的,如果改用74HC595連級輸出可以解決你的上述疑問。給你一個示例程序和仿真。

...

太感謝大神了!看的小弟我熱淚盈眶
作者: 笨笨兔    時間: 2019-2-20 13:45
樓主:設(shè)計不是想的那么簡單,實現(xiàn)相同的功能,選用什么樣的器件,很重要。
慢慢體會!
作者: kmsj    時間: 2019-2-20 16:01
先不談程序,51單片機(jī)的P0口是個非常扯淡的口,我的仿真器的仿真頭排線在左邊,插到目標(biāo)板上P1和P3口就擋住了,P1和P3口用起來就不太方便,P0和P2口沒有被擋住,P0口在左上角,接線最方便,所以我經(jīng)常用P0口仿真,直到有一次仿真74HC165,簡簡單單的移位程序,怎么都無法成功,搞的我焦頭爛額,后來用AVR單片機(jī)仿真,一次就成功。突發(fā)奇想,用51單片機(jī)的P2口仿真74HC165,也是一次成功。要知道,51單片機(jī)的P0口仿真CD4094、CD4014、CD4021都能成功,就是74HC165不能成功,我編了一些方波程序看P0口和其它口的差別,發(fā)現(xiàn)P0口下拉能力弱,速度也很慢,要想用P0口仿真74HC165成功,最簡單的方法就是降低速度,但是,如果使用和研究51單片機(jī),少用和慎用P0口是少走彎路的重要方法的之一。
作者: struct00    時間: 2019-2-20 17:42

標(biāo)題與內(nèi)容描述不符,內(nèi)容描述與程序不符,程序中數(shù)據(jù)類型定義與實際需要不符,最終全體不服!
作者: izhonguo    時間: 2019-2-21 08:31
kmsj 發(fā)表于 2019-2-20 16:01
先不談程序,51單片機(jī)的P0口是個非常扯淡的口,我的仿真器的仿真頭排線在左邊,插到目標(biāo)板上P1和P3口就擋住 ...

多謝經(jīng)驗分享,剛接觸單片機(jī),還需要多向各位大牛勤快請教。
作者: kmsj    時間: 2019-2-21 13:34
izhonguo 發(fā)表于 2019-2-21 08:31
多謝經(jīng)驗分享,剛接觸單片機(jī),還需要多向各位大牛勤快請教。

不用謝!51單片機(jī)的P0口驅(qū)動LED、通過三極管驅(qū)動繼電器,讀開關(guān)狀態(tài)之類的低速應(yīng)用問題不大,高速讀寫的情況下就要注意了,比如I2C、SPI接口等等
作者: izhonguo    時間: 2019-3-7 00:53
wulin 發(fā)表于 2019-2-14 08:48
你的上述疑問是真實存在的,如果改用74HC595連級輸出可以解決你的上述疑問。給你一個示例程序和仿真。

...

總工,您好:
我自己學(xué)習(xí)了一下51單片機(jī)的串口接收程序,我想把您這個程序改進(jìn)一下,
做到可以接收比如說從XCOM這類軟件發(fā)來的八個字符串(比如說1A2B3C4D),
然后寫入到dis_buf[8]定義的這個定義的緩存數(shù)組中。下面這樣子寫正確嗎?還望不吝賜教!謝謝!


  1. #include <reg51.H>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit        P_HC595_SER   = P0^0;
  5. sbit        P_HC595_SRCLK = P0^1;
  6. sbit        P_HC595_RCLK  = P0^2;

  7. /*******************定義8個字節(jié)64 bit接收緩存數(shù)組*************************/
  8. uchar data dis_buf[8]={0};//初始化字符串

  9. /*******************串口初始化函數(shù)*************************/
  10. void   URATinit( )
  11. {  
  12.         TMOD=0x20;  
  13.         SCON=0x50;  
  14.         EA=1;  
  15.         ES=1;  
  16.         TR1=1;  
  17.         TH1=0xfd;  
  18.         TL1=0xfd;
  19. }

  20. /*******************中斷函數(shù)*************************/
  21. void receive() interrupt 4
  22. {
  23.         uchar i;        
  24.         if(RI) { //PC機(jī)向單片機(jī)發(fā)送命令是否被識別      
  25.                 dis_buf[i]=SBUF;   
  26.                 RI=0; //清0準(zhǔn)備下一次接收  
  27.         }
  28.         while(!TI);   
  29.         TI=0;  
  30.         i++;  
  31.         if(i>=8){ //防止大于8溢出
  32.                 i=0;  
  33.         }
  34. }  
  35. /**************** 向HC595發(fā)送一個字節(jié)函數(shù) ******************/
  36. void Send_595(uchar dat)
  37. {               
  38.         uchar i;
  39.         for(i=0;i<8;i++)
  40.         {
  41.                 dat <<= 1;
  42.                 P_HC595_SER  = CY; //溢出位賦值數(shù)據(jù)輸出端
  43.                 P_HC595_SRCLK = 1; //移位時鐘
  44.                 P_HC595_SRCLK = 0;
  45.         }
  46. }
  47. /**************** 向HC595發(fā)送八個字節(jié)函數(shù) ******************/
  48. void DisplayScan()
  49. {        
  50.         uchar j;
  51.         for(j=0;j<8;j++)
  52.         {
  53.                 Send_595(dis_buf[j]);//向HC595發(fā)送一個字節(jié)
  54.         }
  55.         P_HC595_RCLK = 1;//鎖存輸出數(shù)據(jù)
  56.         P_HC595_RCLK = 0;
  57. }

  58. void main()
  59. {
  60.         P_HC595_SRCLK = 0;//初始化移位時鐘端
  61.         P_HC595_RCLK  = 0;//初始化鎖存輸出端
  62.         URATinit( );
  63.         DisplayScan();                //發(fā)送八個字節(jié)
  64.         while(1);
  65. }
復(fù)制代碼




作者: wulin    時間: 2019-3-7 15:54
izhonguo 發(fā)表于 2019-3-7 00:53
總工,您好:
我自己學(xué)習(xí)了一下51單片機(jī)的串口接收程序,我想把您這個程序改進(jìn)一下,
做到可以接收比 ...

給你改了一下,已經(jīng)實物驗證,供參考。

  1. //模擬數(shù)據(jù):0數(shù)據(jù)頭  1~8有效數(shù)據(jù)               9數(shù)據(jù)尾  
  2. //HEX模式:    AA     01 0A 02 0B 03 0C 04 0D       38
  3. #include <reg51.H>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. sbit P_HC595_SER   = P0^0;//使用P0口需外接5~10K上拉電阻
  7. sbit P_HC595_SRCLK = P0^1;
  8. sbit P_HC595_RCLK  = P0^2;

  9. uchar table0[] ="OK\n";        //用于串口助手返回驗證
  10. uchar table1[]="ERROR\n";//用于串口助手返回驗證
  11. uchar dis_buf[10];                //串口接收緩存
  12. bit flag=0;                                        //接收完成標(biāo)志
  13. /*******************串口初始化函數(shù)*************************/
  14. void URATinit()
  15. {  
  16.         PCON &= 0x7F;                //波特率不倍速9600
  17.         SCON = 0x50;                //8位數(shù)據(jù),可變波特率
  18.         TMOD= 0x20;                        //設(shè)定定時器1為8位自動重裝方式
  19.         TL1 = 0xFD;                        //設(shè)定定時初值
  20.         TH1 = 0xFD;                        //設(shè)定定時器重裝值
  21.         ET1 = 0;                                //禁止定時器1中斷
  22.         TR1 = 1;                                //啟動定時器1
  23.         EA = 1;                                //開總中斷
  24.         ES = 1;                                //開串口中斷
  25. }

  26. /**************** 向HC595發(fā)送一個字節(jié)函數(shù) ******************/
  27. void Send_595(uchar dat)
  28. {               
  29.         uchar i;
  30.         for(i=0;i<8;i++)
  31.         {
  32.                 dat <<= 1;
  33.                 P_HC595_SER  = CY; //溢出位賦值數(shù)據(jù)輸出端
  34.                 P_HC595_SRCLK = 1; //移位時鐘
  35.                 P_HC595_SRCLK = 0;
  36.         }
  37. }
  38. /**************** 向HC595發(fā)送八個字節(jié)函數(shù) ******************/
  39. void DisplayScan()
  40. {        
  41.         uchar j;
  42.         for(j=0;j<8;j++)
  43.         {
  44.                 Send_595(dis_buf[j+1]);//向HC595發(fā)送一個字節(jié)
  45.         }
  46.         P_HC595_RCLK = 1;//鎖存輸出數(shù)據(jù)
  47.         P_HC595_RCLK = 0;
  48. }
  49. /**********串口發(fā)送函數(shù)*************/
  50. void SendOneByte(uchar i)
  51. {
  52.     SBUF = i;                //發(fā)送數(shù)據(jù)
  53.     while(!TI);        //等待發(fā)送完成
  54.     TI = 0;                        //發(fā)送中斷請求標(biāo)志位清0
  55. }
  56. /************數(shù)據(jù)解析程序*************/
  57. void analysis()
  58. {
  59.         uchar i,j=0;                //臨時變量
  60.         if(flag==1)                //10個字節(jié)數(shù)據(jù)串接收完成
  61.         {
  62.                 ES=0;                        //關(guān)串口中斷
  63.                 flag=0;                //接收完成標(biāo)志清0
  64.                 for(i=0;i<8;i++)
  65.                 {
  66.                         j+=dis_buf[i+1];//讀取緩存里8個字節(jié)有效數(shù)據(jù)和,溢出部分拋棄
  67.                 }
  68.                 if(dis_buf[9]==j)//驗證數(shù)據(jù)和
  69.                 {
  70.                         for(i=0;i<3;i++)
  71.                         {
  72.                                 SendOneByte(table0[i]);//返回PC "OK"(用串口助手文本模式接收)
  73.                         }
  74.                         DisplayScan();    //向HC595發(fā)送緩存收到的8個有效字節(jié)
  75. //                        for(i=0;i<10;i++)//返回PC,緩存收到的10個字節(jié)(用串口助手HEX模式接收)
  76. //                        {
  77. //                                SendOneByte(dis_buf[i]);
  78. //                        }
  79.                 }
  80.                 else
  81.                 {
  82.                         for(i=0;i<6;i++)
  83.                         {
  84.                                 SendOneByte(table1[i]);//返回PC "ERROR"
  85.                         }
  86.                         for(i=0;i<10;i++)
  87.                         {
  88.                                 dis_buf[i]=0;                        //清空緩存
  89.                         }
  90.                 }
  91.                 ES=1;                                                //開串口中斷
  92.         }
  93. }
  94. /*******主函數(shù)********/
  95. void main()
  96. {
  97.         P_HC595_SRCLK = 0;                        //初始化移位時鐘端
  98.         P_HC595_RCLK  = 0;                        //初始化鎖存輸出端
  99.         URATinit();                                        //初始化串口
  100.         while(1)
  101.         {
  102.                 analysis();                                //數(shù)據(jù)解析程序
  103.         }
  104. }
  105. /*******************中斷函數(shù)*************************/
  106. void receive() interrupt 4
  107. {
  108.         static uchar i=0;                //靜態(tài)計數(shù)變量

  109.         RI=0;                                        //接收中斷請求標(biāo)志位清0
  110.         dis_buf[i]=SBUF;                //接收到的數(shù)據(jù)串保存在緩存數(shù)組中
  111.         if(dis_buf[0]==0xAA)        //驗證數(shù)據(jù)頭(起始位),否則重收覆蓋
  112.         {
  113.                 i++;
  114.                 if(i>=10)
  115.                 {
  116.                         flag=1;                        //接收完成標(biāo)志置1(完成1幀10bit)
  117.                         i=0;                        //計數(shù)變量清0
  118.                 }
  119.         }
  120. }  
復(fù)制代碼




作者: izhonguo    時間: 2019-3-7 21:33
wulin 發(fā)表于 2019-3-7 15:54
給你改了一下,已經(jīng)實物驗證,供參考。

多謝總工!我再仔細(xì)學(xué)習(xí)一遍。。。
總工牛逼!
作者: izhonguo    時間: 2019-3-13 21:40
wulin 發(fā)表于 2019-3-7 15:54
給你改了一下,已經(jīng)實物驗證,供參考。

總工,您好,這周測試了一下實物,意識到AA開頭的可能會出現(xiàn)一個問題,比如說發(fā)出來的數(shù)據(jù)開頭不是AA,中間卻恰巧夾雜了一個AA,這樣的話,就會出現(xiàn)意外的錯誤,我的理解是中斷程序會從第一組中間的那個AA還是計算為接收10位數(shù)組的開頭,然后等待第二次發(fā)送的后幾位補(bǔ)足共計的10個Bit, 然后不出意外最后一位基本不會是前九位的和,所以肯定會觸發(fā)報錯程序。如圖所示。第一張圖,AA開頭發(fā)送,返回OK, 然后第二次發(fā)送前改起始位AA為AB,然后點擊發(fā)送,發(fā)送數(shù)增加為20,由于第九位是AA,所以此時中斷程序認(rèn)為第二次發(fā)送的10個數(shù)據(jù)里,前8為為無效,目前只接收到2位,即AA,和它后面的和F6,然后我再次點擊發(fā)送數(shù)據(jù),此時,AB位補(bǔ)位剛才不夠10個Bit的第三位,然后到AA前的數(shù)據(jù)27就完成i>=10的判斷條件,然后進(jìn)入數(shù)據(jù)解析,進(jìn)而由于末尾和不等于前8位有效數(shù)據(jù)導(dǎo)致報錯。



所以在HEX模式下,是否可以使用出了0~F之外的特殊字符比如說#或者##作為接收數(shù)據(jù)的起始位判別,在中斷函數(shù)里用命令判別:
        if(dis_buf[0]=='#')        //驗證數(shù)據(jù)頭(起始位),否則重收覆蓋
        {
                i++;
                if(i>=10)
                {
                        flag=1;    //接收完成標(biāo)志置1(完成1幀10bit)
                        i=0;      //計數(shù)變量清0
                }
        }
        else

        {
                P_HC595_OE = 1; //拉高OE引腳,復(fù)位所有繼電器
                for(j=0;j<6;j++)
                {
                    SBUF = table2[j];   //發(fā)送數(shù)據(jù) NOTAA\n
                         while(!TI);        //等待發(fā)送完成
                         TI = 0;
                 }

         }

中斷函數(shù)的else部分如果觸發(fā),返回錯誤信息經(jīng)過測試發(fā)現(xiàn)會自動循環(huán)三次(可能是中斷函數(shù)自身的循環(huán)設(shè)定),結(jié)果如圖:




所以如果我不用AA作為起始位驗證的話,能否改用后續(xù)有效數(shù)據(jù)中不會出現(xiàn)的特殊字符如#字符串來驗證,文本模式和HEX模式是否可以混用?

如果不可混用必須用HEX模式下的有效0~F作為起始位的話,我自己想的一個解決方案是中斷函數(shù)不判別,僅無腦接收上層發(fā)過來的10個BIT, 然后我可以在數(shù)據(jù)解析里進(jìn)行判別如,如計算完有效數(shù)據(jù)的和j之后,同時判別dis_buf[9]==j && dis_buf[0]==0xAA是否成立。成立則進(jìn)行HC595發(fā)送函數(shù),否則返回PC錯誤信息(這樣也可以解決判別不是AA開頭的話,錯誤信息重復(fù)三次的問題)。但是不確定這種方法是否會在中斷函數(shù)中引起什么不良影響?

如果更嚴(yán)謹(jǐn)點的話,作為被動接收的中斷函數(shù),程序如何判別說到的數(shù)據(jù)不夠10位?難道需要再增加一個判別數(shù)據(jù)結(jié)尾的特殊字符如!這樣的方式嗎?

謝謝!



作者: wulin    時間: 2019-3-14 08:46
本帖最后由 wulin 于 2019-3-14 13:17 編輯
izhonguo 發(fā)表于 2019-3-13 21:40
總工,您好,這周測試了一下實物,意識到AA開頭的可能會出現(xiàn)一個問題,比如說發(fā)出來的數(shù)據(jù)開頭不是AA,中 ...

izhonguo你好,很贊賞你勤于思考。給你的示例只是我隨手寫的,簡單展示了自定義通訊協(xié)議的框架。實際運用的自定義通訊協(xié)議要比這復(fù)雜些。由于使用環(huán)境因素,數(shù)據(jù)頭往往由好幾個字節(jié)組成,甚至在數(shù)據(jù)頭前加0x00無效數(shù)據(jù)引導(dǎo)以防數(shù)據(jù)頭錯碼。驗證有效數(shù)據(jù)的正確性是非常重要的措施。方法也很多,有用數(shù)據(jù)和、數(shù)據(jù)和取反+1、計算字節(jié)長度等等。目的都是為了保證有效數(shù)據(jù)的正確性。由于傳輸?shù)臄?shù)據(jù)幀包含的字節(jié)可能不確定,還要增加結(jié)束碼等等。串口中斷函數(shù)中還要有自動紀(jì)錄字節(jié)長度,超時不等侯措施。




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1