Проблема с EUSART pic16F18877 в асинхронном режиме

Я пытаюсь установить связь с EUSART pic16F18877, но безуспешно. Получив некоторые комментарии, я внес некоторые изменения в функцию RxChar().

С компа отправляю 0xFE05 на контроллер через интерфейс usb to ttl (USB To RS232 TTL PL2303HX). Последовательный монитор между ними не показывает ошибок. Символ отправки выходит правильно. Со стороны микроконтроллера я время от времени получаю ошибки кадров.

Все еще пытаюсь заставить работать EUSART. Пока безуспешно. Чтобы выяснить, откуда возникла проблема, я вернулся к исходному шестнадцатеричному файлу (код в основном), чтобы уменьшить возможные источники ошибок. Оригинальная программа написана для pic16F887A, и после программирования PIC16F877A последовательная связь работает правильно. Последовательная связь для PIC16F877A должна быть в библиотеке, так как я не могу найти ее в базовом коде. Даны только определения порта и скорости передачи.

Это выше заставляет меня поверить, что проблема должна быть где-то в настройках или коде моего проекта с PIC16F18877. Но я понятия не имею. Любая помощь в дальнейших действиях приветствуется.

fosc = 20.000000
void UART_Init(void) 
{    

    RC1STAbits.SPEN = 0;     // begin of setup disable serial port.
    // transmitter
    TX1STAbits.TXEN     = 1;    // continues transmit enable bit
    TX1STAbits.TX9      = 0;    // 8 bit transmission
    TX1STAbits.SYNC = 0;        // asynchronous operation
    ANSELCbits.ANSC6    = 0;    // digital
    TRISCbits.TRISC6    = 0;    // output

    // receiver
    RC1STAbits.CREN    = 1;   // continues receive enable bit
    RC1STAbits.RX9     = 0;
    // there is only one sync
    ANSELCbits.ANSC7   = 0;   // digital
    TRISCbits.TRISC7   = 1;   // input

    // baudrate.
    TX1STAbits.BRGH    = 1;
    BAUD1CONbits.BRG16 = 1;
    SPBRG = 520;               // baudrate 9600

    RC1STAbits.SPEN   = 1;     // end of setup enable serial port
}

void UART_TxChar(uchar ch) 
{ 
     while(TXIF==0);    
     TXREG=ch;
}

uchar UART_RxChar()
{  
    uchar Discard;
    while(1){
        while(RCIF==0);       // Wait till the data is received 
        if (RCSTAbits.FERR)
        {    
            Discard = RCREG;   Read the register and wait for the next byte
            break;
        }    
        if (RCSTAbits.OERR)
        {    
            RCSTAbits.CREN = 0;
            break;
        }
        return RCREG;   // Return the received data to calling function  
    }
}
Ваша 1-я строка кода не «отключает» порт, как говорится в вашем комментарии...
@brhans Ошибка копирования. Результат без изменений
Почему вы устанавливаете флаги прерывания в 0? Вы не должны этого делать. И вы не показали, как все это используется
Убедитесь, что вы сбросили флаги ошибок UART, особенно OERR. Кроме того, как заметил Юджин, вам не следует/не нужно очищать флаги прерывания - они все равно доступны только для чтения.
Я просматриваю его, вношу изменения и прихожу с ответом. Пока только пытаюсь получить чар. На внешнем последовательном мониторе отображается символ. В RCREG этого нет.
@ЕвгенийШ. Я обновил свой вопрос с дополнительной информацией. Вы можете помочь?
@brhans. Я обновил свой вопрос с дополнительной информацией. Вы можете помочь?
Ошибки кадрирования указывают на вероятную проблему со скоростью передачи данных, но ваша настройка скорости передачи данных выглядит нормально. Это оставляет ваши часы. Вы уверены, что правильно настроили его для 20 МГц?
@brhans #pragma config FEXTOSC = HS ; _XTAL_FREQ = 20000000.
- а вы уверены, что ваш кристалл действительно колеблется на частоте 20 МГц? Если вы не можете исследовать напрямую, вы можете настроить таймер для переключения вывода и вывести из него частоту осциллятора. Возможно, попробуйте другой кристалл и/или другую частоту (и соответствующим образом настройте SPBRG). Если вы передаете байт с PIC, можете ли вы получить его на ПК (и/или посмотреть синхронизацию битов на «прицеле»)?
XTAL и т. д. должны быть в порядке. Для PIC16F877A я поменял только микроконтроллер. Это работает
@brhans. Обнаружена ошибка. Смотри мой ответ

Ответы (1)

После тщательного повторного чтения кода и перекомпиляции я обнаружил, где была допущена ошибка. Меня ввела в заблуждение информация в таблице 33-4, где SPBRG=520 в сочетании с SYNC=0; BRGH=1 и BRG16=1; Это десятичное значение не может использоваться в этом формате.

//Therefore not: 
 SPRG = 520;
//but:
 SPBRGH = 0x02;
 SPBRGL = 0x08;

После перекомпиляции и тестирования я обнаружил, что информация поступает правильно; Итак, пора переходить к остальной части программы.