PIC18 UART получает поврежденные байты от ПК

Кажется, у меня проблема с приемом правильных байтов с ПК на PIC18F27J53. PIC UART установлен стандартный, асинхронный, 8 бит, 9600, без четности. ПК Win 10, я сделал простую программу UART и отправил несколько целых чисел, разделенных запятыми, как показано ниже. 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 найден. Это кажется лучше, я могу получить больше данных, но окончательные полученные данные повреждены: некоторые целые неверны и т. д.

Это ясно показывает, что это проблема синхронизации, похоже, ПК слишком быстр для PIC? Если это так, я рассматриваю синхронный UART, однако, согласно Интернету, это кажется далеким от выбранного метода, что заставляет меня думать, что у меня должна быть другая проблема для решения в асинхронном режиме?

Мой вопрос, какой самый популярный надежный способ сделать полнодуплексную связь PIC-PC UART?

Вот мои API-интерфейсы приема PIC, довольно стандартные и простые (я думаю).

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;
}

На стороне ПК С# моя отправка выглядит так

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

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

PIC работает от своих внутренних часов 8 МГц. Я никогда не пробовал синхронный способ, так как он кажется более сложным, и 99 процентов веб-результатов будут показывать асинхронный способ, что заставляет меня думать, что я лучше отлаживаю то, что делаю.

Есть идеи? совет? Спасибо


person random_name1978    schedule 13.04.2021    source источник


Ответы (1)


Точнее, не решение, а альтернатива. Вы должны разбить рамку на небольшие куски. И, если возможно, приемник должен подтвердить символом, чтобы уведомить передатчик о том, что нужно продолжить работу с другим фрагментом.

Причина, по которой я говорю, что у меня есть плата разработки mikroE с аналогичной PIC, и при запуске примера из коробки и отправке 111 222 333 444 555 666 777 888 999 Похоже, что 999 создает проблемы, слишком много байтов, возможно, проблема с буфером, может быть, нет идеальное несоответствие скорости передачи данных возникает после нескольких байтов?

Повторение отправки каждые 50 мс, 500 мс или 1000 мс не делает его лучше. Изменение скорости передачи данных также. Только удаление 999 и, кажется, работает нормально.

Я предполагаю, что без 999 он все еще находится на грани работы, поэтому, возможно, просто удалите 666 777 888 999, и общение станет более комфортным.

Больше кода, больше трафика, но, по крайней мере, это работает.

person random_name1978    schedule 14.04.2021