0

我们正在对图片进行编程,并且我们已经诊断出,如果我们在尝试向我们发送数据时将数据发送到串行端口,则程序将锁定(我们的 python 代码和超级终端在测试时都会崩溃)。它在超级终端中工作并缓慢输入(笔画之间>.5 秒),并且在敲击键盘时会崩溃。所以我们所做的是引入一个超过 0.5 秒的 time.sleep,但它仍然无法正常工作。

这是我们的测试代码。

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”(这就是我们知道它在 3 次迭代后冻结的方式)。我们把它带到了循环之外,看看这是否导致了问题,但事实并非如此。它根本没有用这个代码发送“ok”。

unsigned char receiveData(unsigned char *rxData, int length){
  // 1. Flag bit, RCIF, will be set when reception is complete and an interrupt will be generated if enable bit, RCIE, was set.
 char send[3] = "ok";

 int index = 0;

 if(rxData==(void*)0 || rxInitialized==FALSE) return FAILURE;
 while(index<length){
  while(PIR1bits.RCIF==0);       
  rxData[index]= RCREG;
  Delay1KTCYx(5);
  index++;
 }
    configureTransmission();
    sendData(send,3);

  // 2. Read the RCSTA register to get the 9th bit (if enabled) and   determine if any error occurred during reception.
  // 3. Read the 8-bit received data by reading the RCREG register.
  // 4. If any error occurred, clear the error by clearing enable bit   CREN.
 return SUCCESS;
}
4

2 回答 2

2

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

简而言之,它看起来像是缓冲区溢出以及receiveData. 手册的 p117 可以解释在连续发送三个字符后冻结的事实:

可以接收两个字节的数据并将其传输到 RCREG FIFO,第三个字节开始转移到 RSR 寄存器

这将解释神奇的数字三。

单步执行您的 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++;

第二次:

// RCIF set from before
while(PIR1bits.RCIF==0);
// Reads ONE character - RCIF STILL set, ONE character remains in UART FIFO!
rxData[index]= RCREG;
// While waiting here, three more characters are received
// RCIF set, RCREG fills up and the third character is discarded!
Delay1KTCYx(5);
index++;

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

更有可能的是,您甚至在使用该功能之前就已经接收到字符,因此 UART FIFO 在您到达之前就已填满。

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

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

一些额外的建议:你可以疯狂地尝试在你的 PIC 代码中解释和补偿每一个错过的字符或问题,但最终它只是另一个通信错误。PIC 代码中的优先级应该是:从错误中快速恢复并且不锁定。错误检测和健全的恢复应该由客户端代码处理,这要容易得多。

于 2010-11-19T00:43:01.403 回答
1

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

于 2010-11-18T23:43:52.320 回答