【问题标题】:PIC18 UART receiving corrupted bytes from PCPIC18 UART 从 PC 接收损坏的字节
【发布时间】:2021-04-13 09:46:15
【问题描述】:

我似乎无法从 PC 接收正确的字节到 PIC18F27J53。 PIC UART 设置为标准、异步、8 位、9600、无奇偶校验。 电脑是win 10,我做了一个简单的UART程序,发送了几个int,全部用逗号隔开,如下图。 "123,24,65,98,12,45,564,987,321,0,5.9,87,65,789,123,6554,213,8754\n"

我尝试了不同的方法,

  1. 尝试逐个发送每个字符,但 PIC 似乎在传输的中途或早期卡住了,并且 RX 标志不再变高。
  2. 我已尝试发送每个 int 后跟“\n”和我的 PIC 来解析每个字符并在找到“\n”后切断读取。这似乎更好,我可以获取更多数据,但最终接收到的数据已损坏:某些 int 错误等。

它清楚地表明这是一个同步问题,看起来 PC 对 PIC 来说太快了? 如果是这样,我正在考虑使用同步 uart,但是根据网络,这似乎与选择的方法相去甚远,这让我觉得我必须在异步模式下解决另一个问题?

我的问题是,进行 PIC 到 PC UART 全双工通信的最流行的稳健方式是什么?

这是我的 PIC 接收 API,相当标准和简单(我认为)。

void int_receive_data(void)
{
    char input_element[10] = { 0 };
    char full_rx[128] = { 0 };

    for (int i = 0; i < 22; i++) {
        p18f47j53_uart2_read_text(input_element, sizeof(input_element));
        strncat(full_rx, input_element, strlen(input_element));
        strncat(full_rx, ",", 1);
    }
}
void p18f47j53_uart2_read_text(char *output, uint8_t max_length)
{
    uint8_t c;
    char buffer[64] = { 0 };

    for (uint8_t i = 0; i < max_length; i++) {
        c = p18f47j53_uart2_receive_u8();
        buffer[i] = c;

        if ((c == 10) || (c == '\n')) {
            buffer[i] = 0;
            memcpy(output, buffer, i);
            i = max_length;
        }
    }
}

uint8_t p18f47j53_uart2_receive_u8(void)
{
    // wait for the flag
    while (!PIR3bits.RC2IF);

    // reset receiver if over run error
    if (RCSTA2bits.OERR) {
        RCSTA2bits.CREN = 0;
        RCSTA2bits.CREN = 1;
        return PIC_RC_FAIL;
    }

    // reset if frame error
    if (RCSTA2bits.FERR) {
        RCSTA2bits.SPEN = 0;
        RCSTA2bits.SPEN = 1;
        return PIC_RC_FAIL;
    }

    return RCREG2;
}

在 PC C# 端,我的发送看起来像这样

        string[] full_separated = full_tx.Split(',');

        foreach (string s in full_separated)
            my_port.WriteLine(s);

PIC 以其内部时钟 8MHz 运行。 我从未尝试过同步方式,因为它看起来更复杂,而且 99% 的网络结果都会显示异步方式,这让我觉得我更好地调试我正在做的事情。

有什么想法吗?建议?谢谢

【问题讨论】:

    标签: c# asynchronous uart pic18


    【解决方案1】:

    这不是真正的解决方案,而是替代方案。您应该将框架分成小块。并且如果可能的话,接收者会用一个字符来确认,以通知发送者继续处理另一个块。

    我这么说的原因是,我有一个带有类似 PIC 的 mikroE 开发板,并且在运行“开箱即用”示例时,并发送 “111,222,333,444,555,666,777,888,999” 看起来“999”正在造成问题,字节过多,可能是缓冲区问题,可能在几个字节后会产生不完美的波特率不匹配?

    每 50 毫秒、500 毫秒或 1000 毫秒重复发送一次并不会使其变得更好。 也不改变波特率。 只删除“,999”,它似乎可以正常工作。

    如果没有“,999”,我猜它仍然处于“工作边缘”,所以也许只需删除“666,777,888,999”,沟通应该会感觉更舒服。

    更多代码,更多流量,但至少它有效..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2017-05-11
      • 2013-07-01
      相关资源
      最近更新 更多