Hot!UART sending unknown data on PIC24F

Author
northernLad
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2018/07/17 01:43:27
  • Location: 0
  • Status: offline
2018/08/09 04:36:05 (permalink)
0

UART sending unknown data on PIC24F

Hi, 
I am using: PIC24FJ256GA705 Curiosity development board, with a Max2323 -> RS232 -> USB into PC adapter, connected to the UART1 module inside the uC.
I have managed to get the transmission to PC, but after every transmission there are some random characters that are gibberish. (shown in picture)
Please could someone explain why these are here? I would be incredibly grateful if you could point out any mistakes and possible improvements to my code.
I apologise for the length of code, I have removed most of the irrelevant code. Sorry if my formatting isn't very good, this is my first forum post. (posting says access denied so will edit post once posted)
Thanks for any help!
 

UART.c

 
 
 
typedef union {
    struct {
        uint8_t full:1;
        uint8_t empty:1;
        uint8_t reserved:6;
    }s;
    uint8_t status;
}UART_BYTEQ_STATUS;

typedef struct {
    uint8_t *rxTail ;
    uint8_t *rxHead ;
    uint8_t *txTail ;
    uint8_t *txHead ;
    UART_BYTEQ_STATUS rxStatus ;
    UART_BYTEQ_STATUS txStatus ;
} UART_OBJECT ;
static UART_OBJECT uart1_obj ;

#define UART1_CONFIG_TX_BYTEQ_LENGTH 8
#define UART1_CONFIG_RX_BYTEQ_LENGTH 8

static uint8_t uart1_txByteQ[UART1_CONFIG_TX_BYTEQ_LENGTH] ;
static uint8_t uart1_rxByteQ[UART1_CONFIG_RX_BYTEQ_LENGTH] ;
 
 
 
 
 
 
 

void UART1_Initialize (void) {
    U1MODE = 0x8808;
    U1STA = 0x2750;
    U1ADMD = 0x0000;

    IEC0bits.U1RXIE = 1;
    IEC0bits.U1TXIE = 1;

    uart1_obj.txHead = uart1_txByteQ;
    uart1_obj.txTail = uart1_txByteQ;
    uart1_obj.rxHead = uart1_rxByteQ;
    uart1_obj.rxTail = uart1_rxByteQ;
    uart1_obj.rxStatus.s.empty = true;
    uart1_obj.txStatus.s.empty = true;
    uart1_obj.txStatus.s.full = false;
    uart1_obj.rxStatus.s.full = false;

    U1MODEbits.BRGH = 0;
    U1BRG = 0x19;

    U1MODEbits.UARTEN = 1; // enabling UART ON bit
    U1STAbits.UTXEN = 1;
    U1STAbits.URXEN = 1;
}

void UART1_Write(const uint8_t byte) {
    IEC0bits.U1TXIE = false;
    *uart1_obj.txTail = byte;
    uart1_obj.txTail++;
    if (uart1_obj.txTail == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH)) {
        uart1_obj.txTail = uart1_txByteQ;
    }
    uart1_obj.txStatus.s.empty = false;
    if (uart1_obj.txHead == uart1_obj.txTail) {
        uart1_obj.txStatus.s.full = true;
    }
    IEC0bits.U1TXIE = true ;
}

unsigned int UART1_WriteBuffer(const uint8_t *buffer , const unsigned int bufLen) {
    unsigned int numBytesWritten = 0 ;
    while ( numBytesWritten < ( bufLen )) {
        if((uart1_obj.txStatus.s.full)) {
            break;
        } else {
            UART1_Write(buffer[numBytesWritten++] ) ;
        }
    }
    return numBytesWritten ;
}

unsigned int UART1_TransmitBufferSizeGet(void) {
    if(!uart1_obj.txStatus.s.full) {
        if(uart1_obj.txHead > uart1_obj.txTail) {
            return(uart1_obj.txHead - uart1_obj.txTail);
        } else {
            return(UART1_CONFIG_TX_BYTEQ_LENGTH - (uart1_obj.txTail - uart1_obj.txHead));
        }
    }
    return 0;
}

 
main.c

 
 
 
char *char_array[] = {"example1","eightbit"}; //example transfer data

void putU1(const uint8_t *buf){
    const unsigned int bufLen = UART1_TransmitBufferSizeGet();
    while (U1STAbits.UTXBF == 1)
        ; // wait while Tx buffer full
    UART1_WriteBuffer(buf, bufLen);
}

void getU1(void) {
    uint8_t bufferRx = U1RXREG;
    const unsigned int bufLen = UART1_ReceiveBufferSizeGet();
    while (!U1STAbits.URXDA)
        ;

    UART1_ReadBuffer((uint8_t *)&bufferRx, bufLen);
}

int main(void) {
    T1CON = 0x8030;
    int i = 0;
    SYSTEM_Initialize();
    __delay_ms(200);

    for (i = 0; i < 2; i++){
        putU1((uint8_t *) char_array[i]);
        __delay_ms(500);
    }

    return (EXIT_SUCCESS);
}

 
 
Actually it is now sending some random characters before the actual data. Also the time between transmissions isn't uniform (1st LED blink, delay, blink blink) (Tx LED) and I can't see why it loops forever?
The serial port reader image wont upload so I will try to upload in a reply.
 
P.S. If you see this, DarioG you have helped incredibly without knowing it. I am very grateful for your contribution to these forums!
 
post edited by northernLad - 2018/08/09 04:53:38
#1
DarioG
Allmächtig.
  • Total Posts : 54079
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 04:55:02 (permalink)
0
thanks northernLad Smile
unfortunately I can't find anyone to help me, facing "bad" people...

GENOVA :D :D ! GODO
#2
DarioG
Allmächtig.
  • Total Posts : 54079
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 04:59:40 (permalink)
0
Back to code:
what happens if buflen (available in queue) is > the length of string you're passing to "write" function?
shouldn't you check that?
 
 
 

GENOVA :D :D ! GODO
#3
northernLad
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2018/07/17 01:43:27
  • Location: 0
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 08:06:37 (permalink)
0
I'm not fully sure where you mean to check it? I have tried to make it so that the buffer can't be longer than the string to be sent but it hasn't had any affect.

 
void putU1(const uint8_t *buf, int i){
    unsigned int bufLen = UART1_TransmitBufferSizeGet();
    while (U1STAbits.UTXBF == 1)
        ; // wait while Tx buffer full
    if (bufLen > sizeof(char_array[i]))                 <---
        bufLen = sizeof(char_array[i]);                 <---
    UART1_WriteBuffer(buf, bufLen);
}    
 

 
I have changed so that there are now 3 strings of 8 chars sent in a row, and the output looks like this. (i clicked the \n button after each string to show their order)
When captured to a txt file, there are 3 spaces before example1
[code]
ø
 
   example1
eightbit
maywork?
 
 
 
 
post edited by northernLad - 2018/08/09 08:24:51
#4
DarioG
Allmächtig.
  • Total Posts : 54079
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 08:19:54 (permalink)
0
Hmm, no, sizeof returns the "static, overall" size of the array.
Maybe more something like
    UART1_WriteBuffer(buf, strlen(buf));
or also
     UART1_WriteBuffer(buf, min(bufLen,strlen(buf)));

GENOVA :D :D ! GODO
#5
northernLad
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2018/07/17 01:43:27
  • Location: 0
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 09:03:13 (permalink)
0
I have tried both of those and they don't prevent the extra bits still
#6
johnszy
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2015/09/29 15:33:45
  • Location: 0
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 09:14:18 (permalink)
3 (1)
Put one character at a time in the TX register and the chip will handle putting it on the wire, this works for 16F1619, then buffer outside of this code:
 
 
void USART_putc(unsigned char c)
{
while(!TXSTAbits.TRMT);
TX1REG=c;
}
void USART_puts(unsigned char *s)
{

while(*s)
{
USART_putc(*s);
s++;
}
}
 
 
#7
DarioG
Allmächtig.
  • Total Posts : 54079
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 09:22:36 (permalink)
0
Yep, John, but those things don't use a queue or FIFO.
I suppose the issue lies in FIFO...

GENOVA :D :D ! GODO
#8
johnszy
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2015/09/29 15:33:45
  • Location: 0
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 09:47:17 (permalink)
4 (1)
Ok, yes, agree, it is in the FIFO, i would run the FIFO code in a gcc and debug the buffer there...
 
Just wondering - have you looked at this line of code?:
 
if (uart1_obj.txTail == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH))

Maybe your tail gets too long - so subtract 1 from the right side

if (uart1_obj.txTail == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH - 1 ))

That would be too easy...
grin: grin
but I'm with DarioG, its buffer overrun in your FIFO
#9
davekw7x
Entropy++
  • Total Posts : 1455
  • Reward points : 0
  • Joined: 2012/01/16 12:01:07
  • Location: Left Coast, USA
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/09 14:54:45 (permalink)
4.5 (2)
Most of your uart stuff (other than putU1) is from MCC, right?
 
Well...
It is set up for a Tx buffer size of 8.  The program puts stuff in the buffer by calling UART1_WriteBuffer() and the MCC interrupt routine (not shown) sucks them out of the buffer one at a time to send to the UART.
 
One problem with MCC is that it allows users with little knowledge or interest in learning I/O specifics, or even C language details, to create a framework of I/O functions, but, unlike the late, great MLA (Microchop Libraries for Applications), MCC doesn't give usage examples. 
 
Note to anyone and everyone reading this:
I do NOT include you in this unenlightened group; that is a general statement, the point of which is that the very people who need to understand how to use MCC are often the ones least able to dig to the bottom of things.
 
So, here's the deal:
 
If you call UART1_WriteBuffer() with a "string" of more than eight bytes, it will send eight bytes and then quit. 
 
If you want to transmit more than eight bytes, you must send the message in chunks of eight bytes.  Of course you could increase the size of the buffer when you set up the UART in mcc, but then the question is, "How big should it be so that it never truncates any message that I will ever want to send?"  Not one that I would like to try to answer.  No matter how big I make it, I'm thinking that someone will want a longer message.  I don't want to reconfigure and recompile the MCC stuff for different maximum message lengths.
 
Well, regardless of the size of the MCC buffer...
A clue to usefulness is given in the comments preceding the UART1_WriteBuffer function prototype in uart1.h.
That particular example is silly (assumes the message occupies exactly the number of bytes in the user's buffer), but it does give a clue on a way to do the deed.
 
Here's my main.c, showing an enhanced implementation of your putU1.  I left the other UART functions (initialization and WriteBuffer) unaltered from the way there were generated by MCC.

// Curiosity 24FJ256GA7 board:
//
//  UART connections on mikroBUS 2:
//    U1Tx on RB7
//    U1Rx on RB8 (Not used in this test)
//  LEDS:
//    LED1 on RA8
//    LED2 on RA9 (Not used in this test)


#include "mcc_generated_files/mcc.h"
#include <stdio.h>   // For sprintf() among other things
#include <string.h>  // For strlen() among other things

// __XTAL_FREQ is defined by MCC in mcc.h
// Rounded unsigned integer division: Add half the denominator
// to the numerator before dividing.  You must define FCY
 
// before including <libpic30.h>
#define FCY ((_XTAL_FREQ + 1) / 2)
#include <libpic30.h>    // For __delay_ms()
void daves_putU1(const char *buf);

int main(void)
{
    char tx_buffer[80];
    // initialize the device
    SYSTEM_Initialize();
    __delay_ms(100); // Give things a little time to settle down

    snprintf(tx_buffer, sizeof(tx_buffer),
            "\r\nCompiled on %s at %s PDT by XC16 version %d\r\n",
            __DATE__, __TIME__, __XC16_VERSION);
    daves_putU1(tx_buffer);
   
    uint32_t counter = 0;
    
    while (1)
    {
        snprintf(tx_buffer, sizeof(tx_buffer), "%10lu\r\n", counter);
        daves_putU1(tx_buffer);
        ++counter;
        LED1_Toggle();
        __delay_ms(1000);
    } // End of main loop
    // Never gets here
} // End of main()

// The sequence in putU1 is taken from comments in MCC-generated uart1.h
//
void daves_putU1(const char *buf)
{
    unsigned int num_to_transmit = strlen(buf);
    UART1_TRANSFER_STATUS status;
    unsigned int numBytes = 0;
    while (numBytes < num_to_transmit) {
        status = UART1_TransferStatusGet();
        if (status & UART1_TRANSFER_STATUS_TX_EMPTY) {
            numBytes += UART1_WriteBuffer((uint8_t *)(buf + numBytes), num_to_transmit - numBytes);
            if (numBytes < num_to_transmit) {
                continue;
            } else {
                break;
            }
        } else {
            continue;
        }
    }

} // End of daves_putU1

Output:
Compiled on Aug  9 2018 at 14:28:07 PDT by XC16 version 1035
         0
         1
         2
         3
         4
         .
         .
         .
Bottom line: The MCC functions can work, but you gotta figure out how to use them
 
Regards,

Dave
 
 Footnote
"Men are born ignorant, not stupid.
Education is what makes them stupid."
---Bertrand Russell
 
post edited by davekw7x - 2018/08/09 16:00:11

Sometimes I just can't help myself...
#10
DarioG
Allmächtig.
  • Total Posts : 54079
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/10 02:41:47 (permalink)
0
good Smile

GENOVA :D :D ! GODO
#11
northernLad
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2018/07/17 01:43:27
  • Location: 0
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/10 03:12:47 (permalink)
0
I am trying to use your code, word for word. But nothing is transmitting at all 
post edited by northernLad - 2018/08/10 03:42:07
#12
davekw7x
Entropy++
  • Total Posts : 1455
  • Reward points : 0
  • Joined: 2012/01/16 12:01:07
  • Location: Left Coast, USA
  • Status: offline
Re: UART sending unknown data on PIC24F 2018/08/10 06:58:15 (permalink)
0
northernLad
I am trying to use your code, word for word. But nothing is transmitting at all 

Actually, it's not "my" code.  I just wanted to illustrate how to use the information in the MCC-generated header file, and my output seems to indicate that it works for me.  "My" code would implement the same chunk-at-a-time functionality without the baroque, twisted logic inside the loop.  See Footnote.
 
Anyhow...
Since I only showed main() and the UART put function, even if you use that "word for word," we have no way of knowing everything else in your project, including your MCC setup.
 
Suggestion: Use the MPLABX "package" function to create a zip file for your project and post it.
Maybe someone can help you get to the bottom of things.
 
Regards,
 
Dave
 
Footnote:
"If it ain't baroque, don't fix it!"
---davekw7x
post edited by davekw7x - 2018/08/10 07:43:47

Sometimes I just can't help myself...
#13
Jump to:
© 2018 APG vNext Trial Version 4.5