读了三遍后就冻结了

2024-06-06 19:46:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我们正在编程一个pic,我们已经诊断出,如果我们在串行端口试图向我们发送数据时发送数据,程序就会锁定(我们的python代码和超级终端在测试时都会崩溃)。它在超级终端中工作,输入速度慢(笔划之间间隔0.5秒),当键盘被敲击时会崩溃。我们所做的就是介绍时间。睡觉时间超过0.5秒,但它仍然不工作。在

这是我们的测试代码。在

import serial
import time

ser = serial.Serial("COM1")
ser.baudrate=2400

while 1:
    for i in range(23):
        ser.write(0x41)       
        time.sleep(.5)
        print("ok")

    rec = ser.read()
    rec2 = ser.read()
    rec3 = ser.read()
    print(rec)
    print(rec2)
    print(rec3)

    for i in range(23):
        data = ser.read()
        print(data)
        print("ok")
    time.sleep(5)

我们的接收数据功能。我们曾经让“ok”在每次收到char时被发送(这就是为什么我们知道它在3次迭代后冻结)。我们把它带到循环之外,看看这是否是导致问题的原因,事实并非如此。它根本不发送“确定”与此代码。在

^{pr2}$

Tags: 代码inimportforreadtimeserialrange
2条回答

来自PIC的通信是否利用串行端口的RTS/CTS lines?可能PIC需要某种流控制,而你在没有任何流控制的情况下向它发送数据太快了。阅读PIC的限制,如果需要,请打开启用flow control的端口。在

(此答案假设您使用的是PIC16,由某些寄存器的名称表示。)

简而言之,它看起来像是缓冲区溢出加上receiveData循环中的一个bug。连续发送三个字符后会冻结,这可能是手册第117页的解释:

It is possible for two bytes of data to be received and transferred to the RCREG FIFO and a third byte to begin shifting to the RSR register

这就解释了神奇的数字3。在

逐步浏览PIC代码,考虑以下场景(只是一个示例)。第一次:

// One character already in RCREG - RCIF set
while(PIR1bits.RCIF==0);
// Reads ONE character - RCIF clear
rxData[index]= RCREG;
// While waiting here, two more characters are received - RCIF set
Delay1KTCYx(5);
index++;

第二次:

^{pr2}$

现在,循环的其余部分将继续从RCREG读取数据,直到index == length,但是由于一些字符在UART FIFO已满时被丢弃,您将永远无法到达那里并且看起来冻结!在

更可能的情况是,你甚至在使用该函数之前就已经收到了字符,因此UART FIFO在你到达之前就已经填满了。在

有几种方法可以解决这个问题。在

  1. 在中断中执行此操作,这样可以更快地将传入字符移动到缓冲区中。在
  2. 使用一个循环从RCREG:while(RCIF) rxData[index]= RCREG;这可以确保在从UART缓冲区读取时清空缓冲区,但它不会阻止此函数之外或延迟期间的溢出。在
  3. 检查OERR标志-如果设置了它,假设发生了不好的事情并重新开始。在
  4. 有一个停止字符或开始字符(如行尾、标点符号等),它告诉你一个有效的命令何时开始或停止。如果你得到了两个没有停止字符的开始字符,或者其他一些令人困惑的组合,假设你的状态不好,然后重新开始。在

一些额外的建议:你可以疯狂地尝试去解释和补偿你的PIC代码中的每一个遗漏的字符或问题,但最终它只是另一个通信错误。PIC代码中的优先事项应该是:从错误中快速恢复,而不是锁定。错误检测和正常恢复应该由客户机代码来处理,因为这样做非常容易。在

相关问题 更多 >