找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2056|回复: 4
打印 上一主题 下一主题
收起左侧

关于单片机与Python上位机通信问题

[复制链接]
跳转到指定楼层
楼主
100黑币
上位机用的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))//接收一行的第一个字符是本行字符数,此处确认接收和发送数目相等,-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;//开始执行
  20.      }
  21.     }
  22.     else            //接收发送数目不一致,通知上位机重新发送
  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'):#发送与接收不一致,重新发送本行
  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'):#等待一行发送完成得到回应A
  61.       msg=ser.read(1)
  62.       print(msg)
  63.     if(j ==10 ):#发送完10行,等待单片机处理完毕,返回B再继续发送下10行
  64.       print("%d条代码发送完,正在等待处理"%(i+1))
  65.       while(msg!=b'B'):#发完10行等待再次发送的指令B
  66.         msg=ser.read(1)
  67.         j=0
  68.         
  69.   ser.write('

  70. 下面是传送情况,不一定卡在什么位置,程序有确定性找不到原因,求教大神们
  71. <img src="http://www.51hei.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.51hei.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;//开始执行
  77.    }
  78.    RI=0;
  79.   }
  80. }
复制代码

下面是Python上位机程序:
import serial #导入模块

[        DISCUZ_CODE_1        ]

下面是传送情况,不一定卡在什么位置,程序有确定性找不到原因,求教大神们


.encode('UTF-8'))#写完完毕,发结束信号
  print("传送完成完毕")  
  ser.close()#关闭串口
except Exception as e:
    print("---异常---:",e)


下面是传送情况,不一定卡在什么位置,程序有确定性找不到原因,求教大神们


)//传送结束标志
   {
    recbuf[compos][recpos]=0;
    recf=0;//暂停接收
    wrif=1;//开始执行
   }
   RI=0;
  }
}
下面是Python上位机程序:
import serial #导入模块

[        DISCUZ_CODE_1        ]

下面是传送情况,不一定卡在什么位置,程序有确定性找不到原因,求教大神们


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:827243 发表于 2021-5-8 10:54 | 只看该作者
你读SBUF写的不太规范,可能会导致多读一个字符。改成下面试试
   recbuf[compos][recpos]=SBUF;//数据存入缓存
   recpos++;
   if(recbuf[compos][recpos-1]=='\n')        //如果收到的是\n,说明接收完一行
回复

使用道具 举报

板凳
ID:889094 发表于 2021-5-8 11:02 | 只看该作者
daemondong 发表于 2021-5-8 10:54
你读SBUF写的不太规范,可能会导致多读一个字符。改成下面试试
   recbuf[compos][recpos]=SBUF;//数据存 ...

谢谢回复,确实是问题,我修改一下
回复

使用道具 举报

地板
ID:889094 发表于 2021-5-8 21:33 | 只看该作者
我好像找到问题原因了,主要是在发送串口数据中,仔细学习了芯片手册,发送例程里面有一个busy还帮助获取串口发送状态,加进去后就没再出现卡在半路的情况。
也没再出现接收丢失数据现象,看来接收和发送两个还是相关联的?还是我程序本来就乱。。。。。
总结:
1、看例程要仔细,重点地方要做笔记
2、自己写代码一定要结构清楚,注释清楚
回复

使用道具 举报

5#
ID:889094 发表于 2021-5-8 22:28 | 只看该作者
if(TI)
{
  TI=0;
  busy=0;
}
重点中地重点,就在这个busy上面,每次发送之前:while(busy);busy=1;然后SBUF='A',如此才能确保发送时一定能发,发了一定会发出。
原来程序里面接收数据有问题估计也是因为穿插其中的发送使整个数据出问题了
现在几百行数据做过去几次了,再没出现状况。g指令传到单片机,单片机控制步进电机,总算出来几个字了

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表