標題: 關于單片機與Python上位機通信問題 [打印本頁]

作者: birdzhyli    時間: 2021-5-7 23:35
標題: 關于單片機與Python上位機通信問題
上位機用的PYTHON網上抄的程序,用于將G指令傳遞給單片機
目前存在的問題如下:
1、單片機有時會在一行指令中少收一兩個字符(小概率),為什么會丟字符?這個沒查到原因,求指教
2、單片機返回給PC端用于交互的字符有時上位機也收不到,可能原因是什么?
下面附串口接收代碼:
  1. if(RI)
  2. {
  3.   if(recf==1)//接收g指令
  4.   {
  5.    recbuf[compos][recpos]=SBUF;//數據存入緩存
  6.    recpos++;
  7.    if(SBUF=='\n')        //如果收到的是\n,說明接收完一行
  8.    {
  9.     if(recbuf[compos][0]==(recpos-1))//接收一行的第一個字符是本行字符數,此處確認接收和發(fā)送數目相等,-1是首字符記錄個數
  10.     {
  11.      SBUF='A';//收完一行返回一個A
  12.      while(!TI)
  13.       TI=0;
  14.      recpos=0;   //接收完一行,將接收位置重置,接收數組+1
  15.      compos++;
  16.      if(compos==10)//已經接收10行,暫停接收,置位處理數據flag
  17.      {
  18.       recf=0;//暫停接收
  19.       wrif=1;//開始執(zhí)行
  20.      }
  21.     }
  22.     else            //接收發(fā)送數目不一致,通知上位機重新發(fā)送
  23.     {
  24.      SBUF='E';
  25.      while(!TI)
  26.       TI=0;
  27.      recpos=0;//準備重新接收
  28.     }
  29.    }
  30.    if(SBUF=='
  31. 下面是Python上位機程序:
  32. import serial #導入模塊

  33. <div class="blockcode"><blockquote>f1=open('1.gcode','r')   #輸入.mmg刀具路徑
  34. data1=f1.readlines()
  35. f1.close()
  36. try:
  37.   #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  38.   portx="COM7"
  39.   #波特率,標準值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  40.   bps=9600#115200
  41.   #超時設置,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒)
  42.   timex=5
  43.   # 打開串口,并得到串口對象
  44.   ser=serial.Serial(portx,bps,timeout=timex)
  45.   # 寫數據到串口
  46.   j=0
  47.   for i in range(len(data1)):
  48.     j=j+1
  49.     print(data1[i],end="")#打印數據到屏幕,便于觀察
  50.     ser.write(chr(len(data1[i])).encode('UTF-8'))#寫本行長度到串口
  51.     result=ser.write(data1[i].encode('UTF-8'))#寫本行數據到串口
  52.     print(result)#打印本行字符數,包括\n
  53.     msg=ser.read(1)#讀取串口,單片機返回值
  54.     print(msg)
  55.     while(msg==b'E'):#發(fā)送與接收不一致,重新發(fā)送本行
  56.       ser.write(chr(len(data1[i])).encode('UTF-8'))
  57.       ser.write(data1[i].encode('UTF-8'))
  58.       msg=ser.read(1)
  59.       print(msg)
  60.     while(msg!=b'A'):#等待一行發(fā)送完成得到回應A
  61.       msg=ser.read(1)
  62.       print(msg)
  63.     if(j ==10 ):#發(fā)送完10行,等待單片機處理完畢,返回B再繼續(xù)發(fā)送下10行
  64.       print("%d條代碼發(fā)送完,正在等待處理"%(i+1))
  65.       while(msg!=b'B'):#發(fā)完10行等待再次發(fā)送的指令B
  66.         msg=ser.read(1)
  67.         j=0
  68.         
  69.   ser.write('

  70. 下面是傳送情況,不一定卡在什么位置,程序有確定性找不到原因,求教大神們
  71. <img src="http://www.torrancerestoration.com/bbs/forum.php?mod=image&aid=269927&size=300x300&key=85739febd9026e1e&nocache=yes&type=fixnone" aid="attachimg_269927" alt="" border="0" width="300"><img src="http://www.torrancerestoration.com/bbs/forum.php?mod=image&aid=269928&size=300x300&key=e3e4704a245fc88b&nocache=yes&type=fixnone" aid="attachimg_269928" alt="" border="0" width="300">

  72. )//傳送結束標志
  73.    {
  74.     recbuf[compos][recpos]=0;
  75.     recf=0;//暫停接收
  76.     wrif=1;//開始執(zhí)行
  77.    }
  78.    RI=0;
  79.   }
  80. }
復制代碼

下面是Python上位機程序:
import serial #導入模塊

[        DISCUZ_CODE_1        ]

下面是傳送情況,不一定卡在什么位置,程序有確定性找不到原因,求教大神們


.encode('UTF-8'))#寫完完畢,發(fā)結束信號
  print("傳送完成完畢")  
  ser.close()#關閉串口
except Exception as e:
    print("---異常---:",e)


下面是傳送情況,不一定卡在什么位置,程序有確定性找不到原因,求教大神們


)//傳送結束標志
   {
    recbuf[compos][recpos]=0;
    recf=0;//暫停接收
    wrif=1;//開始執(zhí)行
   }
   RI=0;
  }
}
下面是Python上位機程序:
import serial #導入模塊

[        DISCUZ_CODE_1        ]

下面是傳送情況,不一定卡在什么位置,程序有確定性找不到原因,求教大神們



作者: daemondong    時間: 2021-5-8 10:54
你讀SBUF寫的不太規(guī)范,可能會導致多讀一個字符。改成下面試試
   recbuf[compos][recpos]=SBUF;//數據存入緩存
   recpos++;
   if(recbuf[compos][recpos-1]=='\n')        //如果收到的是\n,說明接收完一行
作者: birdzhyli    時間: 2021-5-8 11:02
daemondong 發(fā)表于 2021-5-8 10:54
你讀SBUF寫的不太規(guī)范,可能會導致多讀一個字符。改成下面試試
   recbuf[compos][recpos]=SBUF;//數據存 ...

謝謝回復,確實是問題,我修改一下
作者: birdzhyli    時間: 2021-5-8 21:33
我好像找到問題原因了,主要是在發(fā)送串口數據中,仔細學習了芯片手冊,發(fā)送例程里面有一個busy還幫助獲取串口發(fā)送狀態(tài),加進去后就沒再出現(xiàn)卡在半路的情況。
也沒再出現(xiàn)接收丟失數據現(xiàn)象,看來接收和發(fā)送兩個還是相關聯(lián)的?還是我程序本來就亂。。。。。
總結:
1、看例程要仔細,重點地方要做筆記
2、自己寫代碼一定要結構清楚,注釋清楚
作者: birdzhyli    時間: 2021-5-8 22:28
if(TI)
{
  TI=0;
  busy=0;
}
重點中地重點,就在這個busy上面,每次發(fā)送之前:while(busy);busy=1;然后SBUF='A',如此才能確保發(fā)送時一定能發(fā),發(fā)了一定會發(fā)出。
原來程序里面接收數據有問題估計也是因為穿插其中的發(fā)送使整個數據出問題了
現(xiàn)在幾百行數據做過去幾次了,再沒出現(xiàn)狀況。g指令傳到單片機,單片機控制步進電機,總算出來幾個字了






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