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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

RS485通信主機呼叫單片機從機,1主15從,發送地址問題

[復制鏈接]
跳轉到指定樓層
樓主
問題:主機由按鍵啟動,按下按鍵后開始隨機發送地址,最多15次呼叫地址,但是在while這個循環里面地址是一直發送狀態會堵塞RS485總線,而沒有進入狀態機的第二步進行應答確認,包括第三部的接收數據確認,請教一下 這個呼叫地址如何不會堵塞總線的方式。

單片機程序在2樓
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:973561 發表于 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)                                         {                                                 //進入地址發送步驟                                                 case 0 :                                                                                              send_data();                //發送一幀數據                                                                                 send_datacnt++;             //發送數據計數                                                                                 send_addrflag = 1;         //開啟發送完成標志位后定時器開始計時                           step = 1;                                                                                                          break;                                                                                                                                          case 1 :                                                                                                                                  if(ack_flag == 1)      //等待接收應答信號,如果沒有應答信號表示設備不在線就馬上再次發送下一個地址                                                                                                 {                                                                                                            ack_flag = 0;    //                                                                                                          step = 2;                                                                                                                 // led1 = 1;                                                                                                          clr_recvbuffer(recv_buf); //        清除這一幀應答數據,等待下一幀數據過來                                                                                                                                                                         }                                                                                 else                                                                                                  {                                                                                                                                                                                                                           step = 0;                                                                                                                                                                         }                                                                                                                                                                                                                  break;                                                                                                                                                                                                                                                            case 2:                                                                                                                 revc_data();    //接收數據                                                                                  if(noeffec_dataflag == 1)  //如果接收到的是無效數據就再次從發數據                                                                                 {                                                                                          noeffec_dataflag = 0;   //數據狀態標志位清零                                                                                          step = 0;     //狀態機返回第0步                                                                                                                                                                          }                                                                         else if(effec_dataflag ==1)     //如果接收到的是有效數據就轉入第二步                                                                                 {                                                                                          effec_dataflag = 0;                                                                                          step = 3;                                                                                 }                                                                                         break;                                                                                                                                          case 3:                                                                                                         if(send_datacnt >= 15)   //如果發送的次數大于15  游戲停止                                                                                         {                                                                                                         //game_stop = 1;                                                                                                                                                                    //step = 0;                                                                                                   key_flag = 0;                                                                                                   send_datacnt = 0;                                                                                         }                                                                                         else                                                                                                  {                                                                                                         step = 0;     //如果發送的次數小于15  游戲繼續                                                                                                 }                                                                          break;                                                                                                                                                   }                                                     }                           //                        else  //         { //                                   return; //                                 }                         //KeyRead();   //掃描按鍵是否按下                         //KeyProc();         //按下就啟動游戲                                                                  while(1)         {               if (Intrcnt>20)     // 一直在等,直到20ms時間到,每隔20ms掃描一次大循環               {                    Intrcnt=0;                    break;       // 返回主循環               }         }
回復

使用道具 舉報

板凳
ID:415064 發表于 2022-6-14 09:11 | 只看該作者
先把排版整理下吧
回復

使用道具 舉報

地板
ID:161164 發表于 2022-6-14 10:11 | 只看該作者
請用代碼模式來貼代碼


回復

使用道具 舉報

5#
ID:161164 發表于 2022-6-14 10:20 | 只看該作者
本帖最后由 lkc8210 于 2022-6-14 10:47 編輯

你case 1到case 2 的時間有多長有算過或測過嗎?
這時間足以讓從機收到信號并返回應答信號嗎?
回復

使用道具 舉報

6#
ID:973561 發表于 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. }
復制代碼


掃描按鍵,按下就啟動發送向從機發送數據
  1.                         switch(step)
  2.                         {
  3.                                 //進入地址發送步驟
  4.                                 case 0 :   
  5.                                                              
  6.                                          send_data();                //發送一幀數據
  7.                                         send_datacnt++;             //發送數據計數
  8.                                         send_addrflag = 1;         //開啟發送完成標志位后定時器開始計時
  9.                                       if(ack_flag)      //等待接收應答信號,如果沒有應答信號表示設備不在線就馬上再次發送下一個地址
  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)  //如果接收到的是無效數據就再次從發數據
  26.                                                                 {
  27.                                                                          noeffec_dataflag = 0;   //數據狀態標志位清零
  28.                                                                          step = 0;     //狀態機返回第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)   //如果發送的次數大于15 停止
  40.                                                                         {
  41.                                                                                   //跳出發送程序                                                          
  42.                                                                             return;
  43.                                                                         }       
  44.                                                                        else
  45.                                                                                 {
  46.                                                                                   step = 0;     //如果發送的次數小于15  游戲繼續
  47.                                                                                 }
  48.                                                          break;
  49.                                                                                
  50.                                           default:         break;       
  51.    
  52.                                                                                
  53.                            }
復制代碼


發送后超時檢測,發送一幀數據后就開啟定時器,因為從機收到數據成功后會立馬回發數據,所以
超時檢測先定在50ms測試,但是在switch里面無法轉入到第二步
  1.                         if(send_addrflag == 1)    //發送一幀數據后開始倒計時,超時重發地址
  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.                           }
復制代碼
回復

使用道具 舉報

7#
ID:973561 發表于 2022-6-15 09:18 | 只看該作者
lkc8210 發表于 2022-6-14 10:20
你case 1到case 2 的時間有多長有算過或測過嗎?
這時間足以讓從機收到信號并返回應答信號嗎?

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


  1.                         if(send_addrflag == 1)    //發送一幀數據后開始倒計時,超時重發地址
  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.                           }
復制代碼
回復

使用道具 舉報

8#
ID:161164 發表于 2022-6-15 11:55 | 只看該作者
chenxinxian 發表于 2022-6-15 09:18
我好像也沒找到多機通信超時重發的帖子參考,從機的回應是接收成功后會馬上向主機重發 主機發過去的數據 ...

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

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



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

以下是一點代碼改法建議









回復

使用道具 舉報

9#
ID:973561 發表于 2022-6-15 19:42 | 只看該作者
lkc8210 發表于 2022-6-15 11:55
沒有send_data()的代碼,不知道里面有沒有延時

還是那個問題

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文二区 | 手机av在线| 黄视频免费 | 一区二区三区电影网 | 国产精品久久777777 | 91精品一区二区 | 国产精品爱久久久久久久 | 亚洲激情在线 | 欧美日韩一区二区在线播放 | 亚洲精品免费视频 | 国产视频精品在线 | 久久在线视频 | 国产美女久久久 | 欧美精品欧美精品系列 | 久久久www成人免费无遮挡大片 | 日本福利片 | 欧美午夜影院 | 999久久久久久久久6666 | 日美女逼逼 | 中文字幕精品一区二区三区精品 | 精品美女久久久 | 少妇无套高潮一二三区 | 日本成人午夜影院 | 草草草草视频 | 国产成人在线播放 | 国产精品69久久久久水密桃 | 伊人二区 | 久久精品免费 | 激情五月婷婷在线 | 国产成人精品网站 | 91免费在线 | av中文字幕在线播放 | 久久久久久久电影 | 日韩精品一区二区三区在线观看 | 欧州一区二区三区 | 天天草天天干 | 夜夜爽99久久国产综合精品女不卡 | 日韩高清国产一区在线 | 亚洲福利| 国产激情视频网站 | 国产日韩欧美激情 |