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

標題: RS485通信主機呼叫單片機從機,1主15從,發(fā)送地址問題 [打印本頁]

作者: chenxinxian    時間: 2022-6-13 19:21
標題: RS485通信主機呼叫單片機從機,1主15從,發(fā)送地址問題
問題:主機由按鍵啟動,按下按鍵后開始隨機發(fā)送地址,最多15次呼叫地址,但是在while這個循環(huán)里面地址是一直發(fā)送狀態(tài)會堵塞RS485總線,而沒有進入狀態(tài)機的第二步進行應答確認,包括第三部的接收數據確認,請教一下 這個呼叫地址如何不會堵塞總線的方式。

單片機程序在2樓

作者: chenxinxian    時間: 2022-6-13 19:22
while(1)                 {                                          if(KEY0 == 0)                          {                                   delay_ms(20);                                   if(KEY0 == 0)                                         {                                key_flag =!key_flag;                             }                          }                                                    if(key_flag == 1 && send_datacnt<= 15)                          {                                  volatile uchar step = 0;                                                              switch(step)                                         {                                                 //進入地址發(fā)送步驟                                                 case 0 :                                                                                              send_data();                //發(fā)送一幀數據                                                                                 send_datacnt++;             //發(fā)送數據計數                                                                                 send_addrflag = 1;         //開啟發(fā)送完成標志位后定時器開始計時                           step = 1;                                                                                                          break;                                                                                                                                          case 1 :                                                                                                                                  if(ack_flag == 1)      //等待接收應答信號,如果沒有應答信號表示設備不在線就馬上再次發(fā)送下一個地址                                                                                                 {                                                                                                            ack_flag = 0;    //                                                                                                          step = 2;                                                                                                                 // led1 = 1;                                                                                                          clr_recvbuffer(recv_buf); //        清除這一幀應答數據,等待下一幀數據過來                                                                                                                                                                         }                                                                                 else                                                                                                  {                                                                                                                                                                                                                           step = 0;                                                                                                                                                                         }                                                                                                                                                                                                                  break;                                                                                                                                                                                                                                                            case 2:                                                                                                                 revc_data();    //接收數據                                                                                  if(noeffec_dataflag == 1)  //如果接收到的是無效數據就再次從發(fā)數據                                                                                 {                                                                                          noeffec_dataflag = 0;   //數據狀態(tài)標志位清零                                                                                          step = 0;     //狀態(tài)機返回第0步                                                                                                                                                                          }                                                                         else if(effec_dataflag ==1)     //如果接收到的是有效數據就轉入第二步                                                                                 {                                                                                          effec_dataflag = 0;                                                                                          step = 3;                                                                                 }                                                                                         break;                                                                                                                                          case 3:                                                                                                         if(send_datacnt >= 15)   //如果發(fā)送的次數大于15  游戲停止                                                                                         {                                                                                                         //game_stop = 1;                                                                                                                                                                    //step = 0;                                                                                                   key_flag = 0;                                                                                                   send_datacnt = 0;                                                                                         }                                                                                         else                                                                                                  {                                                                                                         step = 0;     //如果發(fā)送的次數小于15  游戲繼續(xù)                                                                                                 }                                                                          break;                                                                                                                                                   }                                                     }                           //                        else  //         { //                                   return; //                                 }                         //KeyRead();   //掃描按鍵是否按下                         //KeyProc();         //按下就啟動游戲                                                                  while(1)         {               if (Intrcnt>20)     // 一直在等,直到20ms時間到,每隔20ms掃描一次大循環(huán)               {                    Intrcnt=0;                    break;       // 返回主循環(huán)               }         }
作者: wojiaoguogai    時間: 2022-6-14 09:11
先把排版整理下吧
作者: lkc8210    時間: 2022-6-14 10:11
請用代碼模式來貼代碼



作者: lkc8210    時間: 2022-6-14 10:20
本帖最后由 lkc8210 于 2022-6-14 10:47 編輯

你case 1到case 2 的時間有多長有算過或測過嗎?
這時間足以讓從機收到信號并返回應答信號嗎?
作者: chenxinxian    時間: 2022-6-15 09:11
  1. unsigned char keyscan()
  2. {
  3.         unsigned char keynum = 0;
  4.         if(KEY0 == 0)
  5.         {
  6.                  delay_ms(10);
  7.            if(KEY0 == 0)
  8.                  {
  9.                     //keynum =!keynum;       
  10.                           keynum = 1;       
  11.                  }while(KEY0 == 0);       
  12.         }
  13.         return keynum;
  14. }
復制代碼


掃描按鍵,按下就啟動發(fā)送向從機發(fā)送數據
  1.                         switch(step)
  2.                         {
  3.                                 //進入地址發(fā)送步驟
  4.                                 case 0 :   
  5.                                                              
  6.                                          send_data();                //發(fā)送一幀數據
  7.                                         send_datacnt++;             //發(fā)送數據計數
  8.                                         send_addrflag = 1;         //開啟發(fā)送完成標志位后定時器開始計時
  9.                                       if(ack_flag)      //等待接收應答信號,如果沒有應答信號表示設備不在線就馬上再次發(fā)送下一個地址
  10.                                         {  
  11.                                                  ack_flag = 0;    //
  12.                                                 step = 1;       
  13.                                                                                
  14.                                                clr_recvbuffer(recv_buf); //        清除這一幀應答數據,等待下一幀數據過來                                                                       
  15.                                                 }
  16.                                             else
  17.                                                 {         
  18.                                                  
  19.                                                         step = 0;                                                                       
  20.                                                 }                               
  21.                                    break;
  22.                                                                        
  23.                                  case 1:                               
  24.                                         revc_data();    //接收數據
  25.                                                                 if(noeffec_dataflag)  //如果接收到的是無效數據就再次從發(fā)數據
  26.                                                                 {
  27.                                                                          noeffec_dataflag = 0;   //數據狀態(tài)標志位清零
  28.                                                                          step = 0;     //狀態(tài)機返回第0步
  29.                                                                        
  30.                                                                 }
  31.                                                   else if(effec_dataflag)     //如果接收到的是有效數據就轉入第二步
  32.                                                                 {
  33.                                                                          effec_dataflag = 0;
  34.                                                                          step = 2;
  35.                                                                 }                       
  36.                                     break;
  37.                                                                
  38.                                   case 2:                       
  39.                                                     if(send_datacnt >= 15)   //如果發(fā)送的次數大于15 停止
  40.                                                                         {
  41.                                                                                   //跳出發(fā)送程序                                                          
  42.                                                                             return;
  43.                                                                         }       
  44.                                                                        else
  45.                                                                                 {
  46.                                                                                   step = 0;     //如果發(fā)送的次數小于15  游戲繼續(xù)
  47.                                                                                 }
  48.                                                          break;
  49.                                                                                
  50.                                           default:         break;       
  51.    
  52.                                                                                
  53.                            }
復制代碼


發(fā)送后超時檢測,發(fā)送一幀數據后就開啟定時器,因為從機收到數據成功后會立馬回發(fā)數據,所以
超時檢測先定在50ms測試,但是在switch里面無法轉入到第二步
  1.                         if(send_addrflag == 1)    //發(fā)送一幀數據后開始倒計時,超時重發(fā)地址
  2.                                
  3.                         {
  4.                                    send_timecnt ++;                       
  5.                                        
  6.                                         if(send_timecnt<= 50 && recv_flag == 1)  //在50毫秒內接收到應答信號
  7.                                         {

  8.                                                          ack_flag = 1;    //下位機應答成功
  9.                                                          send_timecnt = 0;       //停止計時標志位
  10.                                                          send_addrflag = 0;           //重新將標志位清零
  11.                                                                                          
  12.                                         }
  13.                                         else
  14.                                         {
  15.                                                
  16.                                                 ack_flag = 0;         //下位機超時為回應
  17.                                                 send_timecnt = 0;       //停止計時標志位
  18.                                                 send_addrflag = 0;
  19.                                         }                                 
  20.                                                                                  
  21.                           }
復制代碼

作者: chenxinxian    時間: 2022-6-15 09:18
lkc8210 發(fā)表于 2022-6-14 10:20
你case 1到case 2 的時間有多長有算過或測過嗎?
這時間足以讓從機收到信號并返回應答信號嗎?

我好像也沒找到多機通信超時重發(fā)的帖子參考,從機的回應是接收成功后會馬上向主機重發(fā) 主機發(fā)過去的數據表示在線,所以第一步我在發(fā)送完成一幀數據后就開啟定時50ms后判斷串口是否有接收到一幀數據,如果有表示應答成功,然后轉到第二步,但是這個第二步由應答信號來跳轉好像不行,所以一直卡在這里面


  1.                         if(send_addrflag == 1)    //發(fā)送一幀數據后開始倒計時,超時重發(fā)地址
  2.                                
  3.                         {
  4.                                    send_timecnt ++;                       
  5.                                        
  6.                                         if(send_timecnt<= 50 && recv_flag == 1)  //在50毫秒內接收到應答信號
  7.                                         {

  8.                                                          ack_flag = 1;    //下位機應答成功
  9.                                                          send_timecnt = 0;       //停止計時標志位
  10.                                                          send_addrflag = 0;           //重新將標志位清零
  11.                                                                                          
  12.                                         }
  13.                                         else
  14.                                         {
  15.                                                
  16.                                                 ack_flag = 0;         //下位機超時為回應
  17.                                                 send_timecnt = 0;       //停止計時標志位
  18.                                                 send_addrflag = 0;
  19.                                         }                                 
  20.                                                                                  
  21.                           }
復制代碼

作者: lkc8210    時間: 2022-6-15 11:55
chenxinxian 發(fā)表于 2022-6-15 09:18
我好像也沒找到多機通信超時重發(fā)的帖子參考,從機的回應是接收成功后會馬上向主機重發(fā) 主機發(fā)過去的數據 ...

沒有send_data()的代碼,不知道里面有沒有延時

還是那個問題
從第5行結束到第8行比較的時間有多長有算過或測過嗎?
這時間足以讓從機收到信號并返回應答信號嗎?



應該加一個case來等待應答和超時
另外,在沒有應答的情況下,根本到不了case2,檢測不了send_datacnt
于是死循環(huán)了

以下是一點代碼改法建議










作者: chenxinxian    時間: 2022-6-15 19:42
lkc8210 發(fā)表于 2022-6-15 11:55
沒有send_data()的代碼,不知道里面有沒有延時

還是那個問題

您說得對 確實是時間問題,發(fā)送出來到接收的時間太久了,基本上切換不到case 2, 按照您建議的增加了一個case 延時還是不行,這種情況不知道如何解決




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 中文字幕视频在线看5 | 天天操夜夜骑 | 国产在线一区二区 | 国产精品久久久久久久免费观看 | 久久久久资源 | 91精品国产综合久久香蕉麻豆 | 午夜精品影院 | 成人一区av | 91资源在线| 中文字幕免费 | 国产精品久久一区二区三区 | 国产精品中文字幕在线 | 久久亚洲天堂 | 国产一区二区三区四区三区四 | 久久成人免费视频 | 国产高清精品一区二区三区 | 激情久久网 | 欧美中文一区 | 亚洲欧美一区二区三区1000 | 国产成人综合在线 | 丝袜久久| av片网站 | 爽爽免费视频 | 国产精品1区2区 | 在线观看免费av网站 | 日本黄色激情视频 | 羞羞的视频在线看 | av色站 | 综合九九| 亚洲精品www | 91精品国产91久久综合桃花 | 91精品一区二区三区久久久久 | 成人欧美一区二区三区在线观看 | 国产在视频一区二区三区吞精 | www.天堂av.com | 国产精品免费一区二区 | 国产精品国产三级国产播12软件 | 国产一区二区在线播放 | 天天干天天操天天爽 | 国产99久久久国产精品 | 中文福利视频 |