Question

I'm receiving a framing error after each message I send from my pic24f. It does not matter how long the message, or how many messages I send. After the last character is sent ('\0' or 0x00) in my case, I receive a framing error and I don't know why. I thought it was a baud rate issue, but that should result in an off bit sample at or around the same place regardless of the message length, thereby resulting in a framing error at that point. This is not the case. The error occurs after the last character sent.enter image description here

Here's the initialization code:

_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

Here's the transmit code:

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
}

Link to salae logic capture:

Était-ce utile?

La solution

Looking here, I see this:

The UART transmission is enabled by setting the UTXEN enable bit (UxSTA<10>). The actual transmission will not occur until the UxTXREG has been loaded with data and the baud rate generator has produced a shift clock, in accordance with the value in the register UxBRG. The transmission can also be started by first loading the UxTXREG register and the setting the UTXEN enable bit.

Clearing the UTXEN bit during a transmission will cause the transmission to be aborted and will reset the transmitter. As a result, the UxTX pin will revert to a high-impedance state.

[Bolding mine.]

I am not familiar with the PIC but it sounds to me like you should not be enabling and disabling the transmitter. The TX pin going High-Z will cause the input to the level converter to become floating which is probably the source of the framing errors.

I'd suggest enabling the transmitter during initialization and leaving it enabled. As long as you don't feed the UART a new transmit character, it should remain idle.

If you want to use interrupts, when the transmitter is idle, mask the interrupt instead of disabling the transmitter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top