首页 > 解决方案 > PIC18 UART 从 PC 接收损坏的字节

问题描述

我似乎无法从 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”后剪切读取。这似乎更好,我可以获取更多数据,但最终接收到的数据已损坏:某些整数错误等。

它清楚地表明这是一个同步问题,看起来 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% 的 Web 结果将显示异步方式,这让我觉得我更好地调试我正在做的事情。

任何想法?建议?谢谢

标签: c#asynchronousuartpic18

解决方案


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

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

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

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

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


推荐阅读