pic24f Остающаяся ошибка кадрирования UART

Я получаю сообщение об ошибке после каждого сообщения, отправленного с моего pic24f. Неважно, как долго сообщение или сколько сообщений я отправляю. После отправки последнего символа ('\0' или 0x00) в моем случае я получаю сообщение об ошибке кадрирования и не знаю почему. Я думал, что это проблема скорости передачи, но это должно привести к сэмплированию в одном и том же месте или вне его независимо от длины сообщения, что приведет к ошибке кадрирования в этой точке. Это не вариант. Ошибка возникает после последнего отправленного символа.

Вот код инициализации:

_TRISF5 = 0;    //TX pin to output
_TRISF3 = 1;    //RX pin to input

iPPSOutput(OUT_PIN_PPS_RP17,OUT_FN_PPS_U1TX);   //RP17 tied to TX
iPPSInput(IN_FN_PPS_U1RX,IN_PIN_PPS_RP16);      //RP26 tied to RX

U1MODE = 0;                 //disable, set defaults

//setup
U1MODEbits.STSEL=0;//one stop bit
U1MODEbits.PDSEL=0;//8 bit no parity
U1MODEbits.BRGH=1;//High speed mode (baud clock from Fcy/4)
U1MODEbits.RXINV=0;//UxRX idle state is '1' (don't invert)
U1MODEbits.ABAUD=0;//baud rate measurement disabled or completed
U1MODEbits.LPBACK=0;//loopback disabled
U1MODEbits.WAKE=0;//No wake up enabled
U1MODEbits.UEN1=0;//TX,RX enabled (others controlled by latch)
U1MODEbits.UEN0=0;//TX,RX enabled (others controlled by latch)
U1MODEbits.RTSMD=0;//RTS pin in flow control mode (don't think this applies for UEN = 0)
U1MODEbits.IREN=0;//irda encoder and decoder disabled
U1MODEbits.USIDL=1;//stop in idle mode

IFS0bits.U1RXIF = 0;        //clear rx flag
IFS0bits.U1TXIF = 0;        //clear tx flag
IEC0bits.U1RXIE = 1;        //enable rx interrupt
IEC0bits.U1TXIE = 1;        //enable tx interrrupt

U1BRG = 34;                 //115200, -0.62% Error

U1STAbits.URXISEL = 0;      //Interupt when RX buffer has one or more characters
U1STAbits.UTXISEL1 = 0;     //Interrupt when all transmit operations are complete
U1STAbits.UTXISEL0 = 0;     //Interrupt when all transmit operations are complete

U1STAbits.UTXEN = 1;

U1MODEbits.UARTEN = 1;      //enable

Вот код передачи:

void send_msg(const char* msg){
    char* p = (char*) msg;
    U1STAbits.UTXEN = 1;
    while(*p != '\0'){
        while(U1STAbits.UTXBF);  //wait for buffer room (1: buffer full, 0: buffer has room)
            U1TXREG = *p++;
        }
    while(!U1STAbits.TRMT); //wait for transmission to complete
    U1STAbits.UTXEN = 0; //disable the transmitter
}

Ссылка на захват логики salae:

1 ответ

Решение

Глядя здесь, я вижу это:

Передача UART активируется путем установки бита включения UTXEN (UxSTA<10>). Фактическая передача не произойдет до тех пор, пока UxTXREG не будет загружен данными, а генератор скорости передачи не сгенерирует тактовую частоту сдвига в соответствии со значением в регистре UxBRG. Передача также может быть начата с первой загрузки регистра UxTXREG и установки бита включения UTXEN.

Очистка бита UTXEN во время передачи приведет к прерыванию передачи и сбросу передатчика. В результате вывод UxTX вернется в состояние с высоким импедансом.

[Смелая шахта.]

Я не знаком с PIC, но мне кажется, что вы не должны включать и отключать передатчик. Вывод TX, идущий в высокий-Z, приведет к тому, что вход преобразователя уровня станет плавающим, что, вероятно, является источником ошибок кадрирования.

Я бы предложил включить передатчик во время инициализации и оставить его включенным. Пока вы не кормите UART новым символом передачи, он должен оставаться бездействующим.

Если вы хотите использовать прерывания, когда передатчик находится в режиме ожидания, замаскируйте прерывание вместо отключения передатчика.

Другие вопросы по тегам