久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1335|回復: 0
打印 上一主題 下一主題
收起左側

51單片機主,從機一拖二通信程序問題分析

[復制鏈接]
跳轉到指定樓層
樓主
ID:479916 發表于 2019-4-22 14:02 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
用51單片機設計了一拖二的控制系統一套。主機定時發送數據給從機,并要求從機回傳數據給主機。主機發送的數據為2個字節,第一個字節為地址,第二個為數據,從機回復的數據也一樣。主機將數據發送出去后,進行計時,在計時范圍內接收到數據,即完成收發通信,計時完成后,仍然無法收到數據,認為數據接收失敗。現在主機和從機之間通信正常.主,從機通信正常.從機設計了一個當無按鍵操作達到一定時間后,程序將進入一循環程序,一直執行循環程序,除非按下“喚醒”按鍵,程序跳出循環。現在程序好像無法進入循環,疑為通信程序影響所致。用STC-ISP的串口助手調試,將從機與電腦連接,點擊"發送緩沖區---自動發送,可以定時休眠,點擊"多字符串發送,勾選第1,2字符,此時就無法正常進入休眠狀態.目前無法分析出原因,更不要提如何修改。求哪位敬愛的大師給予指導。貼程序:

主機程序
  1. # include "config.h"
  2. void UartDriver();                                          //串口驅動函數
  3. void DelayX50ms(uchar8 t);                          //延時函數
  4. void ConfigTimer0();                                 //定時器配置函數,定時3ms.模式1
  5. void ConfigUART();                                   //串口配置函數
  6. void OCProtect();                                         //過流檢測函數
  7. void PowCheck(uchar8 t,uchar8 addr);       // 供電檢測函數,     主機要發送給從機的數據  
  8. void UartSend(uchar8 addr);                     //串口發送函數
  9. void DelayX10us(uchar8 t);                           //延時函數
  10. void UartReceive();                                   //串口接收函數
  11. void UartAction(uchar8 addr);                   //串口數據解析函數
  12. void LedDisp(uchar8 temp);                     //LED顯示函數
  13. void ReturnPos(uchar8 addr);                  //復位函數
  14. void UartRxMonitor(uchar8 ms);              //總線監控函數


  15. uchar8 OCBuf[2];
  16. uchar8 RxdBuf[4];
  17. uchar8 TxdBuf[4];
  18. uchar8 buf[4];
  19. uchar8 cntRxd=0;                    //字節接收計數
  20. uchar8 PowCNTR=0;                   //供電檢測計數
  21. uchar8 PowSta=0xFF;                 //供電狀態存儲變量
  22. bit OCflag=0;                       //過流標志
  23. bit Txdflag=0;                      //字節發送完成標志
  24. bit TxFr_Succ=0;                    //幀發送完成標志
  25. bit RxFr_Succ=0;                    //幀接收完成標志
  26. bit RxFr_Fail=0;                      //幀接收失敗標志


  27. main()
  28. {
  29.    ROE=1;RA3=1;RA2=1;RA1=1;         //釋放所有繼電器
  30.    Buz=0;
  31.    DelayX50ms(5);
  32.    Buz=1;                           //蜂鳴器響
  33.    P1=0x00;
  34.    DelayX50ms(5);
  35.    P1=0xFF;                         //數碼管全亮,檢測數碼管是否能正常亮起,并提示系統啟動
  36.    DIR485=0;
  37.    EA=1;
  38.    ConfigTimer0();
  39.    ConfigUART();
  40.    while(1)
  41.    {
  42.       OCProtect();
  43.       UartDriver();
  44.    }
  45. }

  46. //串口驅動函數
  47. void UartDriver()
  48. {
  49.    static uchar8 sl_select=1;                             //從機選擇索引
  50.    switch(sl_select)
  51.    {
  52.       case 1:PowCheck(4,0x01);                            //檢測供電狀態,并發送
  53.                if(RxFr_Succ)                                //從機數據接收成功標志
  54.                {
  55.                   RxFr_Succ=0;
  56.                   UartReceive();                            //串口讀取函數
  57.                   UartAction(0x01);                         //數據解析函數
  58.                   if((buf[1]<0x03)||(buf[1]>0x11))                        //有按鍵按下,有數據
  59.                   {
  60.                      sl_select++;                                                                              
  61.                   }
  62.                }
  63.                else if(RxFr_Fail)                           //從機數據接收失敗標志
  64.                {
  65.                   RxFr_Fail=0;
  66.                   buf[1]=0xFF;
  67.                   UartAction(0x01);
  68.                   //ROE=1;RA3=1;RA2=1;RA1=1; Dis_Pin=0xFF;
  69.                   sl_select++;
  70.                }
  71.                break;
  72.       case 2:PowCheck(4,0x02);
  73.                if(RxFr_Succ)
  74.                {
  75.                   RxFr_Succ=0;
  76.                   UartReceive();
  77.                   UartAction(0x02);
  78.                   if((buf[1]<0x03)||(buf[1]>0x11))                        //有按鍵按下,有數據
  79.                   {
  80.                       sl_select--;                                                                                       
  81.                   }
  82.                }
  83.                else if(RxFr_Fail)
  84.                {
  85.                   RxFr_Fail=0;
  86.                   buf[1]=0xFF;
  87.                   UartAction(0x02);
  88.                   //ROE=1;RA3=1;RA2=1;RA1=1; Dis_Pin=0xE2;
  89.                   sl_select--;
  90.                }
  91.                break;
  92.       default:sl_select=1;break;
  93.    }
  94. }

  95. //延時函數,延時時間為t*50ms
  96. void DelayX50ms(uchar8 t)
  97. {
  98.    ........
  99. }

  100. //T0配置函數,模式1,3ms.
  101. void ConfigTimer0()
  102. {
  103.    ...........
  104. }

  105. //串口配置函數,    方式1,    9600
  106. void ConfigUART()
  107. {
  108.    ........................      
  109. }

  110. //過流保護函數,
  111. void OCProtect()
  112. {
  113.    ....................
  114. }

  115. //供電狀態檢測,并發送給從機,t為檢測時間控制變量,addr為從機地址
  116. void PowCheck(uchar8 t,uchar8 addr)
  117. {
  118.    if(PowCNTR>=t)
  119.    {
  120.       PowCNTR=0;
  121.       if(PowSta==0xFF)                    
  122.       {
  123.          TxdBuf[1]=0x12;                     //DC供電
  124.       }
  125.       else if(PowSta==0x00)
  126.       {
  127.          TxdBuf[1]=0x13;                     //BAT供電
  128.       }
  129.       else;
  130.       UartSend(addr);                        //將供電數據發送出去
  131.    }
  132. }

  133. //串口發送函數
  134. void UartSend(uchar8 addr)
  135. {
  136.    uchar8 len=0;
  137.    DIR485=1;
  138.    DelayX10us(2);
  139.    TxdBuf[0]=addr;                        //將即要發送的地址裝入緩沖數組中
  140.    for(;len<2;len++)
  141.    {
  142.       Txdflag=0;
  143.       SBUF=TxdBuf[len];
  144.       while(!Txdflag);
  145.       DelayX10us(5);
  146.    }
  147.    DelayX10us(5);
  148.    DIR485=0;
  149.    //DelayX10us(5);
  150.    TxFr_Succ=1;                           //幀發送完成標志
  151. }

  152. //延時10us函數
  153. void DelayX10us(uchar8 t)
  154. {
  155.    ....................
  156. }

  157. //串口接收函數
  158. void UartReceive()
  159. {
  160.    uchar8 len=0;
  161.         while(len<2)
  162.         {
  163.                 buf[len]=RxdBuf[len];
  164.       len++;
  165.         }
  166.         cntRxd=0;
  167. }

  168. //串口接收數據解析函數,addr為發送地址
  169. void UartAction(uchar8 addr)
  170. {
  171.    if(buf[0]!=addr)                                    //地址解析,接收到的地址字節與發送地址不相同,
  172.       { return;   }                                         //返回
  173.    switch(buf[1])                                       //數據解析,解析接收到的數據字節
  174.    {
  175.       case 0x03:ReturnPos(addr);break;
  176.                 case 0x04:ROE=0;RA3=0;RA2=0;RA1=0; LedDisp(1); break;                 //C1P為低電平
  177.                 case 0x05:ROE=0;RA3=0;RA2=1;RA1=0; LedDisp(2); break;                 //C2P向頭平移
  178.                 case 0x06:ROE=1;RA3=0;RA2=1;RA1=0; LedDisp(5); break;                 //C5P背板上升
  179.                 case 0x07:ROE=0;RA3=1;RA2=1;RA1=0; LedDisp(11);break;                //1#Y6  剎車
  180.                 case 0x08:ROE=0;RA3=0;RA2=1;RA1=1; LedDisp(7); break;                //C2N向腳平移
  181.                 case 0x09:ROE=1;RA3=0;RA2=1;RA1=1; LedDisp(10);break;                //C5N背板下降
  182.                 case 0x0A:ROE=0;RA3=0;RA2=0;RA1=1; LedDisp(6); break;                //C1N下降
  183.                 case 0x0B:ROE=1;RA3=1;RA2=0;RA1=0; LedDisp(13);break;                //2#Y4  腰升
  184.                 case 0x0C:ROE=1;RA3=0;RA2=0;RA1=0; LedDisp(4); break;                //C4P左傾
  185.                 case 0x0D:ROE=0;RA3=1;RA2=1;RA1=1; LedDisp(12);break;                //1#Y7 松剎車
  186.                 case 0x0E:ROE=0;RA3=1;RA2=0;RA1=1; LedDisp(8); break;                //C3N頭降腳升
  187.                 case 0x0F:ROE=1;RA3=1;RA2=0;RA1=1; LedDisp(14);break;                //2#Y5  腰降
  188.                 case 0x10:ROE=0;RA3=1;RA2=0;RA1=0; LedDisp(3); break;                //C3P頭升腳降
  189.                 case 0x11:ROE=1;RA3=0;RA2=0;RA1=1; LedDisp(9); break;                //C4N右傾      
  190.                 case 0xFF:ROE=1;RA3=1;RA2=1;RA1=1; Dis_Pin=0xFF;break;                //釋放所有繼電器
  191.                 default:ROE=1;RA3=1;RA2=1;RA1=1;Dis_Pin=0xFF;break;
  192.    }
  193. }

  194. //數碼管顯示函數
  195. void LedDisp(uchar8 temp)
  196. {
  197. .................
  198. }

  199. //復位函數
  200. void ReturnPos(uchar8 addr)
  201. {
  202. .......................      
  203. }

  204. //串口接收監控函數,從發送完成后開始監控,監控的結果:1.接收成功,2.接收失敗
  205. void UartRxMonitor(uchar8 ms)
  206. {
  207.         static uchar8 cntbkp=0;
  208.         static uchar8 idletmr=0;                //總線空閑時間
  209.         if(TxFr_Succ)                             //幀發送成功后,才開始進行計時接收
  210.         {     
  211.                 if(cntRxd>0)                                                              //接收計數大于0,接收到字節,監控總線空閑時間
  212.                 {
  213.                         if(cntbkp!=cntRxd)                                           //接收計數器改變,有新字節數據,清零總線空閑計數器
  214.                         {
  215.                                 cntbkp=cntRxd;
  216.                                 idletmr=0;
  217.                         }
  218.                         else                                                                         //接收計數器不改變,沒有新字節數據,空閑計數器開始計數
  219.                         {
  220.                                 if(idletmr<10)                     //小于20ms.
  221.                                 {
  222.                                         idletmr+=ms;
  223.                                         if(idletmr>=10)                //大于等于20ms
  224.                                         {
  225.                                                 RxFr_Succ=1;                                   //接收成功
  226.                                                 TxFr_Succ=0;                                 //幀發送成功標志歸0,不再進行總線空閑監控
  227.                                                 idletmr=0;
  228.                                         }
  229.                                 }
  230.                         }
  231.                 }
  232.                 else                                   //從機不在線,未接收到從機數據
  233.                 {
  234.                         cntbkp=0;
  235.                         if(idletmr<20)
  236.                         {
  237.                                 idletmr+=ms;
  238.                                 if(idletmr>=20)
  239.                                 {
  240.                                         RxFr_Fail=1;                                      //接收失敗
  241.                                         TxFr_Succ=0;
  242.                                         idletmr=0;
  243.                                 }
  244.                         }
  245.                 }
  246.         }
  247. }

  248. //T0中斷函數
  249. void InterruptTimer0() interrupt 1
  250. {
  251.    static uchar8 j=0;
  252.    static uchar8 i=0;
  253.    TH0=0xF5;
  254.    TL0=0x33;
  255.    OCBuf[0]=(OCBuf[0]<<1)|GL1;                  //第1路過流數據采集
  256.         OCBuf[1]=(OCBuf[1]<<1)|GL2;                  //第2路過流數據采集
  257.         if((OCBuf[0]==0x00)||(OCBuf[1]==0x00))       //有過流
  258.         {
  259.                 i++;
  260.                 OCBuf[0]=0xFF;
  261.                 OCBuf[1]=0xFF;
  262.                 if(i>=2)
  263.                 {
  264.                         i=0;
  265.                         OCflag=1;                              //過流標志
  266.                 }
  267.         }
  268.    PowSta=(PowSta<<1)|DcBat;                                         //每隔2ms讀取供電狀態一次
  269.         j++;
  270.         if(j>=8)
  271.         {
  272.                 j=0;
  273.                 PowCNTR++;
  274.         }
  275.    UartRxMonitor(3);                            //UART空閑監控,
  276. }
  277. //串口中斷函數
  278. void InterruptUART() interrupt 4
  279. {
  280.    if(RI)
  281.    {
  282.       RI=0;
  283.       RxdBuf[cntRxd]=SBUF;
  284.       cntRxd++;
  285.    }
  286.    if(TI)
  287.    {
  288.       TI=0;
  289.       Txdflag=1;
  290.    }
  291. }
復制代碼

從機程序
  1. # include "config.h"


  2. uint16 KeyBuf=0x0000;                        //按鍵緩沖
  3. uint16 SlpCNTR=0x0000;                                        //休眠索引
  4. //uchar8 Slpbuf=0xFF;                                //休眠喚醒緩沖
  5. uchar8 buf[4];                                                //讀取數組
  6. uchar8 TxdBuf[4];                                    //發送緩沖
  7. bit ScanKeyCNTR=0;                        //按鍵掃描索引
  8. uchar8 PowCNTR=0;                    //供電狀態采集計數
  9. uchar8 PowSta;
  10. uchar8 RxdBuf[4];                         //接收緩沖
  11. uchar8 cntRxd=0;                         //接收計數
  12. uchar8 Cobuf=0xFF;                                                                                //按鍵編碼緩沖


  13. bit flagFrame=0;                                        //幀接收完成標志
  14. bit flagTxd=0;                                                //字節接收完成標志


  15. void UartDriver();                                      //串口驅動函數
  16. void ConfigTimer0();                                 //T0配置函數,3ms,模式1
  17. void ConfigUART();                                    //UART配置函數,方式1
  18. void Delay60us();                                    //延時函數
  19. void ScanKey();                                        //按鍵掃描函數
  20. void KeyCode();                                       //按鍵編碼函數
  21. void SlpMode();                                                 //休眠函數
  22. void UartReceive();                                        //串口接收函數
  23. void UartSend(uchar8 addr,uchar8 Txdata);              //串口發送函數
  24. void UartRxMonitor(uchar8 ms);                           //總線監控函數
  25. void PowStaDisp();                                             //供電狀態監控函數




  26. void main()
  27. {
  28.         P3M1=0x00;
  29.         P3M0=0x40;
  30.         P1M1=0x00;
  31.         P1M0=0x03;
  32.    _nop_();_nop_();
  33.    SleepDisp=1;
  34.    _nop_();_nop_();
  35.         PowDisp=0;                                       
  36.         DIR_485=0;                                       
  37.         ConfigTimer0();
  38.         ConfigUART();
  39.         while(1)
  40.         {
  41.                 if(ScanKeyCNTR)
  42.                 {
  43.                         ScanKeyCNTR=0;
  44.                         ScanKey();
  45.                         KeyCode();
  46.                 }
  47.                SlpMode();
  48.                 PowStaDisp();
  49.                 UartDriver();
  50.         }
  51. }
  52. //串口驅動函數
  53. void UartDriver()
  54. {
  55.         if(flagFrame)
  56.         {
  57.                 flagFrame=0;
  58.                 UartReceive();
  59.                 if(buf[0]!=0x01)
  60.                 {
  61.                         return;
  62.                 }
  63.                 switch(buf[1])
  64.                 {
  65.                         case 0x12:PowSta=buf[1];break;
  66.                         case 0x13:PowSta=buf[1];break;
  67.                         default:break;
  68.                 }
  69.                 UartSend(buf[0],Cobuf);
  70.         }
  71. }
  72. //定時器配置函數
  73. void ConfigTimer0()
  74. {
  75.         ................
  76. }
  77. //UART配置函數
  78. void ConfigUART()
  79. {
  80.         ....................
  81. }
  82. //軟件延時函數
  83. void Delay60us()   //?ó2? -0.049913194444us
  84. {
  85.    ...........................
  86. }
  87. //讀取按鍵狀態函數
  88. void ScanKey()
  89. {
  90.         ...................
  91. }
  92. //按鍵編碼函數,定時調用,執行
  93. void KeyCode()
  94. {
  95.         ....................
  96. }
  97. //休眠函數
  98. void SlpMode()
  99. {
  100.         if(SlpCNTR>=SleepTime)
  101.         {
  102.                 while(Wake_up!=0)
  103.                 {
  104.          SlpCNTR=0;                             //休眠燈亮
  105.          SleepDisp=0;                                          
  106.          PowStaDisp();
  107.                         if(flagFrame)
  108.                         {
  109.                                 flagFrame=0;
  110.                                 UartReceive();
  111.                                 if(buf[0]!=0x01)
  112.                                 {
  113.                                         return;
  114.                                 }
  115.                                 switch(buf[1])
  116.                                 {
  117.                                         case 0x12:PowSta=buf[1];break;
  118.                                         case 0x13:PowSta=buf[1];break;
  119.                                         default:break;
  120.                                 }
  121.                                 UartSend(buf[0],0xFF);
  122.                         }
  123.                 }
  124.                 SleepDisp=1;
  125.         }
  126. }
  127. //串口接收函數
  128. void UartReceive()
  129. {
  130.         uchar8 len=0;
  131.         while(len<2)
  132.         {
  133.                 buf[len]=RxdBuf[len];
  134.       len++;
  135.         }
  136.         cntRxd=0;
  137. }
  138. //串口發送函數
  139. void UartSend(uchar8 addr,uchar8 Txdata)
  140. {
  141.         uchar8 len=0;
  142.         DIR_485=1;
  143.         TxdBuf[0]=addr;
  144.         TxdBuf[1]=Txdata;
  145.         for(;len<2;len++)
  146.         {
  147.                 flagTxd=0;
  148.                 SBUF=TxdBuf[len];
  149.                 while(!flagTxd);
  150.                 Delay60us();
  151.         }
  152.    Delay60us();
  153.         DIR_485=0;
  154. }
  155. //串口接收監控函數,由空閑時間判斷幀接收是否完成,在T0中斷中調用,ms為定時間隔
  156. void UartRxMonitor(uchar8 ms)
  157. {
  158.         static uchar8 cntbkp=0;
  159.         static uchar8 idletmr=0;
  160.         if(cntRxd>0)                                                        //接收計數大于0,監控總線空閑時間
  161.         {
  162.                 if(cntbkp!=cntRxd)                                        //接收計數器改變,有新字節數據,清零總線空閑計數器
  163.                 {
  164.                         cntbkp=cntRxd;
  165.                         idletmr=0;
  166.                 }
  167.                 else                                                                //接收計數器不改變,沒有新字節數據,空閑計數器開始計數
  168.                 {
  169.                         if(idletmr<10)
  170.                         {
  171.                                 idletmr+=ms;
  172.                                 if(idletmr>=10)
  173.                                 {
  174.                                         flagFrame=1;
  175.                                 }
  176.                         }
  177.                 }
  178.         }
  179.         else
  180.         {
  181.                 cntbkp=0;
  182.         }
  183. }
  184. //供電狀態顯示函數,通過PowSta的值進行判斷,PowSta的值來自串口接收
  185. void PowStaDisp()
  186. {
  187.         if(PowSta==0x12)
  188.         {
  189.                 if(PowCNTR>=5)
  190.                 {
  191.                         PowCNTR=0;
  192.                         PowDisp=(!PowDisp);
  193.                 }
  194.         }
  195.         else if(PowSta==0x13)
  196.         {
  197.                 if(PowCNTR>=160)
  198.                 {
  199.                         PowCNTR=0;
  200.                         PowDisp=(!PowDisp);                        //LED燈每400ms亮滅一次
  201.                 }
  202.         }
  203. }
  204. //T0中斷函數
  205. void InterruptTimer0() interrupt 1
  206. {
  207.         TH0=0xF5;
  208.         TL0=0x33;
  209.         ScanKeyCNTR=(!ScanKeyCNTR);                                        //按鍵掃描索引+1
  210.         if(KeyBuf==0xFFFF)
  211.         {
  212.                 SlpCNTR++;
  213.         }
  214.         else
  215.         {
  216.                 SlpCNTR=0;
  217.         }
  218.         PowCNTR++;
  219.         UartRxMonitor(3);
  220.         //Slpbuf=(Slpbuf<<1)|Wake_up;
  221. }
  222. //串口中斷函數
  223. void InterruptUART() interrupt 4
  224. {
  225.         if(RI)
  226.         {
  227.                 RI=0;
  228.                 RxdBuf[cntRxd]=SBUF;
  229.       cntRxd++;
  230.         }
  231.         if(TI)
  232.         {
  233.                 TI=0;
  234.                 flagTxd=1;
  235.         }
  236. }
復制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久精品国产一区二区电影 | 亚洲女人天堂成人av在线 | 亚洲自拍偷拍视频 | 九九热免费观看 | 国产精品视频在线观看 | 亚洲天天干 | 99久久精品国产一区二区三区 | 国产精品一区二区无线 | 色婷婷综合久久久久中文一区二区 | 久久亚洲免费 | 国产精品99久久久精品免费观看 | 成人av在线播放 | 久久久久国产精品免费免费搜索 | 黄色片网站在线观看 | 91精品久久 | 国产一区二区三区免费观看视频 | 成人欧美一区二区 | 国产日韩欧美在线 | 超碰97免费在线 | 中文字幕一区二区三区四区 | 在线观看免费av网 | 精品一区二区久久久久久久网站 | 99看片网| 极品在线| 欧美高清hd| www免费视频 | 日韩精品视频在线播放 | 视频三区 | 黄色片视频 | 国产精品美女久久久久久免费 | 999热在线视频 | 日本不卡一区 | 污视频免费在线观看 | 欧美a级成人淫片免费看 | 国产色网 | 成人在线 | 男人天堂网址 | caoporn国产精品免费公开 | 欧美大片在线观看 | 亚洲国产精品99久久久久久久久 | 色本道|