PIC24F UART - Page 1
Forum section: electronics / general

author: netwinder
author_rank: Regular Contributor
timestamp: July 08, 2016, 06:13:54 pm
content: Hello again,I'm trying to use UART on my PIC24FJ32MC101, and i'm trying to just send on UART. I followed this tutorial:http://www.engscope.com/pic24-tutorial/9-2-uart-usage/however I ran into a few issues with remapable pins:This line presented in the tutorial RPOR1bits.RP3R = 3; I couldnt implement because my PIC doesn't have them (see page 135 of the datasheet, link below, on the table with RPOR1 there's a note stating that they aren't available on my device) I also noticed that this line that sets the input, RPINR18bits.U1RXR = 2; , it confuses me. RPINR18, which in my mind translates to "Remappable Pin INput Register 18", ooes each remappable pin register come with each set of peripherals?Even then, if I can set Rx via this method: RPINR18bits.U1RXR = 2; and this sets it to remappable pin 2, however to set the output (transmit) in the tutorial they use RPOR1bits.RP3R = 3; but shouldnt the syntax be RPOR1bits.U1TXR = 3; ?As you can tell i'm confused as to a few things, however I do have some code for everybody to criticize.Code:// 'C' source line config statements#pragma config OSCIOFNC = OFF // CLKO Enable Configuration bit (CLKO output signal is active on the OSCO pin)#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#define USE_AND_OR /* To enable AND_OR mask setting */#include <xc.h>#include <libpic30.h>#include "headers.h"// libpic30 delays#define __delay_ms(d) \{ __delay32( (unsigned long) (((unsigned long long) d)*(FCY)/1000ULL)); }#define __delay_us(d) \{ __delay32( (unsigned long) (((unsigned long long) d)*(FCY)/1000000ULL)); }#define FP 40000000#define BAUDRATE 9600#define BRGVAL ((FP/BAUDRATE)/16)-1#define DELAY_105uS asm volatile ("REPEAT, #4201"); Nop(); // 105uS delay bits#define FCY 7370000/2 // All dsPIC33s, a few PIC24sunsigned int i;int main(void){//Set up I/O PortAD1PCFGL=0xFFFF;//set to all digital I/OTRISBbits.TRISB15 = 0; // LED pin is an outputRPINR18bits.U1RXR=2;//UART1 receive set to RP2RPOR0bits.RP0R = 3; // Uart Transmit ???LATBbits.LATB15=0; // Turn LED on to show that its not brokeninitUART(23); // See formula on datasheet__delay_ms(5000);while(1){UART1PutChar('t');UART1PutChar('e');UART1PutChar('s');UART1PutChar('t');UART1PutChar(' ');}return 0;}/*** Initialize the UART module* @param baud baud rate as calculated by formula in data sheet*/void initUART(int baud){U1BRG = baud; //9600 baudU1MODE = 0x8000; // Enable moduleU1STA = 0x8400; // Set interruptsIFS0bits.U1RXIF = 0; // Reset RX interrupt flag}/*** --- UART TRANSMIT FUNCTION ---* Transmits a char if the TX buffer is empty* @param ch char to transmit*/void UART1PutChar(char ch){while(U1STAbits.UTXBF){U1TXREG = ch;}}/*** --- UART RECIEVE FUNCTION ---* While there is content in the RX buffer, copy the char and reset RX register* @return a char from the RX register*/char UART1GetChar(){char buffer = ' '; // Initialize variablewhile(IFS0bits.U1RXIF == 0){buffer = U1RXREG;IFS0bits.U1RXIF = 0;}return buffer;}I do hope me making multiple posts isn't a issue - I just want to learn, I don't mean to come off as a help vampireThank you everybody for the help, I do enjoy programming for the PIC microcontrollerEDIT: Silly me i forgot to say how my code is broken. It does compile yes, however when running there is no activity on the remappable pins. On some remappable pins theres a square wave, but nothing else.Datasheet:http://ww1.microchip.com/downloads/en/DeviceDoc/30009997e.pdf#G11.1048847

author: JPortici
author_rank: Super Contributor
timestamp: July 08, 2016, 06:28:52 pm
content: you'd better read the datasheet AND the family reference manual for your pic.on the product page on the microchip website, at the end of the page you'll find everything.(fort the PPS, short version: RPRINxx is a register for the peripheral. the remappable peripheral input is connected to the RPyy/RPINyy pin, yy is the value you write in the RPRINxx register. this means that you can use the same pin for different peripheral inputs in case you were wondering, however for the output there is a register associated to the RPxx pin, the value in this register tell which peripheral is connected to that pin)

author: 22swg
author_rank: Frequent Contributor
timestamp: July 08, 2016, 07:00:07 pm
content: Hi vampire ... One thing I did come to understand about PIC24 UART is you have to use interrupts on the RX and read in to FIFO. will look out my also crap code and post ... ( some one bound to disagree)

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: July 08, 2016, 07:24:09 pm
content: Quote from: 22swg on July 08, 2016, 07:00:07 pmNot necessarily you just need to read data out fast enough to not make the fifo overrun. Interrupts are often the easiest/best way to achieve this but not always necessary.

author: Howardlong
author_rank: Super Contributor
timestamp: July 08, 2016, 08:40:31 pm
content: I've cut it down to a bare minimum to avoid too much confusion from irrelevant stuff!1) To allow changes to the PPS you need to explicitly allow this either in runtime with a special unlock sequence, or just by turning off the IOL1WAY config bit. You can look at the PPS registers in the debugger to make sure they're changed.2) The RP pins you chose either don't exist on your device or were used by one of the debug/programmer pins (RP0 is PGED1, RP2 doesn't exist). I switched them to RP14 (RXD) and RP13 (TXD).Code:#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2 pin has clock out function)#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)#pragma config IOL1WAY = OFF // IOLOCK Protection (Allow Multiple Re-configurations)#include <xc.h>#define FCY 7370000/2 // All dsPIC33s, a few PIC24s#include <libpic30.h>#define BAUDRATE 9600#define BRGVAL ((FCY/BAUDRATE)/16)-1void initUART(int baud){U1BRG = baud; //9600 baudU1MODEbits.UARTEN=1;U1STAbits.UTXEN=1; // Enable the tx}void UART1PutChar(char ch){while(!U1STAbits.TRMT){Nop(); // I like multiple Nops in case the hardware debugger skids on breakpointsNop();Nop();}U1TXREG = ch;LATBbits.LATB15=1; // Debug this pin with your scopeLATBbits.LATB15=0;}int main(void){//Set up I/O PortAD1PCFGL=0xFFFF;//set to all digital I/OTRISBbits.TRISB15 = 0; // LED pin is an output// RPINR18bits.U1RXR=2;//UART1 receive set to RP2 // There is no RP2 on this chipRPINR18bits.U1RXR=14;//UART1 receive set to RP14 (not used in this example))// RPOR0bits.RP0R = 3; // Uart Transmit ??? // RP0 is used by programming pin PGED1RPOR6bits.RP13R = 3; // Uart Transmit on RP13LATBbits.LATB15=0; // Turn LED on to show that its not brokeninitUART(BRGVAL); // See formula on datasheet__delay_ms(500);while(1){UART1PutChar('t');UART1PutChar('e');UART1PutChar('s');UART1PutChar('t');UART1PutChar(' ');}return 0;}

author: netwinder
author_rank: Regular Contributor
timestamp: July 08, 2016, 09:14:27 pm
content: Quote from: mikeselectricstuff on July 08, 2016, 07:24:09 pmInterrupts are probably the next step after this, however for now I'm trying basic implementations to understand how things tick. I'm learning trust meQuote from: Howardlong on July 08, 2016, 08:40:31 pmThank you very much! I was sticking the tutorial i was reading too close, I thought that my chip had those pins (rp2) however I do thank you alot for fixing my implementation.As a token of my appreciation, I've attached a thank you (as printed by my microcontroller)

author: netwinder
author_rank: Regular Contributor
timestamp: July 09, 2016, 12:52:36 am
content: Hello Again!Its been a few hours and i'm stuck, again. This time i'm trying to receive data, and if the data is a 'p', return "p is for pineapple" (just for testing, in the actual device im designing this will use PWM to drive a motor based on something received, however it needs to send data back as well).I am primarily a Java programmer (that's where I started) so I do have a few questions about RX with PIC.I keep hearing the term "interrupts" thrown around, is this similar to event-driven programming?Are interrupts required for all TX and RX operations? At the moment I have my configuration set to have interrupts on RX (IEC0bits.U1RXIE = 1) and no interrupts on TX (IEC0bits.U1TXIE = 0) is this ok?Is my understanding correct: an interrupt will stop other program operation and allow for the interrupt code to runHere's my RX method.Code:char UART1GetChar(){char temp;while(IFS0bits.U1RXIF == 0); //wait for the buffer to fill uptemp = U1RXREG; //copy charIFS0bits.U1RXIF = 0; //reset interruptreturn temp; //return received char}I have changed it a bit, but it doesn't seem to work :/Also, I'm just wondering but can you have persistent storage on PIC?

author: hans
author_rank: Super Contributor
timestamp: July 09, 2016, 08:08:43 am
content: Want to add something to your remappable pin woes.If you look at chip diagram at the begin of the datasheet, almost every pin will have RP added with a number. You can route most peripheral functions through to any peripheral pin on this PIC24.For a given remappable output you need to select what peripheral output source you want to use, in this case UART TX pin (source 3).For a peripheral input source you need to choose which remappable input to listen to.Regarding uart TX/RX interrupt:1) Hmm, yeah, similar.. but not quite. Interrupts are generated by hardware and tied to the interrupt controller of the CPU. If a hardware interrupt fires, the CPU will look in the interrupt vector table which interrupt handler to execute. That function will be called (similar to an event), regardless of what your main application is doing (one exception: you disabled interrupts in software). The functions called through the main tree are paused.Interrupts are high priority pieces of code and need to be short. A conventional technique is not to call any functions in an interrupt or have any long polling actions taken place. This makes sure that the interrupt is a short piece of code, thus quick. Remember; it "steals" CPU time from the main() code that can happen at any time. There are some caveats you may need to look out for, like the proper use of "volatile" and atomic read/write. These are necessary because the C compiler is not perfect, and may not be able to see any modifiers to a variable and thus assume it's constant.2) No strictly not. Remember that most microcontroller peripherals are prettydumbsimple and rely on the software driver to tie them together. Also, some peripherals have some limitations. UART is a good example of that; you can receive a new character at any time, and waiting for a second character to be received or transmitted can take centuries in MCU land. E.g. at 9600Baud a single character will almost take 1ms to transmit. In addition, the UART can only hold a few characters at a time. In your microcontroller, there is a FIFO that hold up to 4 characters. If the FIFO overflows bytes are lost, so you need to read the data in time. A 4-byte FIFO is already quite luxurious; most 8-bit MCU's (and even some ARM micro's) don't have a FIFO and can only hold 1 character at a time.Because of this you will see most people at least putting RX in an interrupt. That way you can have your main() code do whatever it needs to do, and once in a while come back to a buffer (that's filled by the RX interrupt) and serve the characters.However, a scenario may happen that you need to transmit lots of TX data as well; and each byte will take 1ms to transmit. If you that messes with other main() code, you could serve interrupts for TX as well.From what I can see your interrupt bits are correct.3) Yes, that's correct. I'm sorry but I don't have any working code right at hand now, but an interrupt may look something like tihs:Code:circularbuffer uart_receive_buffer;circularbuffer uart_transmit_buffer;void U1_interrupt_handler(void) // this is not the actual ISR function name{if (IFS0bits.U1RXIF) { // RX-not-empty interrupt fireduint8_t data = U1RXREG; // read registerCircularBufferWrite data into uart_receive_buffer ; // store data in circular buffer; the main() code can read bytes from this bufferIFS0bits.U1RXIF = 0;}if (IFS0bits.U1TXIF) { // TX-empty interrupt firedif (CircularBufferEmpty uart_transmit_buffer){U1STA = disable TX;}else{U1TXREG = CircularBufferRead from uart_transmit_buffer;}IFS0bits.U1TXIF = 0;}}For persistent storage I would look at using the internal microcontroller FLASH (although you can't erase & write FLASH 1 byte at a time); or an external EEPROM chip connected via I2C or SPI.

author: 22swg
author_rank: Frequent Contributor
timestamp: July 09, 2016, 08:39:12 am
content: Hi Vampire … Firstly let me say I am no programmer, not even close, mostly my C comes from data sheets, tutorials, forums etc.... second , you are so right about PIC24 being “fun” . I started with PIC16 and assembler way back ( after fun with mpu s) , I have built several “dev” boards for PIC24 F-H-E up to 100pin TQFP, eventually they all worked ! Your RX problem … I don't know why but polling either the buffer full flag or the interrupt flag fails to find the byte in the RX register ?I code a high priority ISR that reads the RX register, and puts byte in a FIFO array and sets an “input” flag, poll that flag...This is for an PIC24EP128MC202 , chatting with a HC-12 transceiver so uart / IFS names / bits may be different …Code:int SBR,SBW,SBC; // HC12 buffer pointers//buffer Read ,Write,Currentint SerialBuf_size = 20 ;char RX_FIFO ; // U2 RX character FIFO bufferchar HC12_input ; // poll this flagchar Serial_input ;void __attribute__((__interrupt__, auto_psv))_U2RXInterrupt(void){while(U2STAbits.URXDA){RX_FIFO = U2RXREG ;if ((SBW+1)% SerialBuf_size != SBR){SBW++;SBW %= SerialBuf_size;}}IFS1bits.U2RXIF = 0;HC12_input = 1; // flag SERIAL DATA IN}char pro_buf() // process the RX buffer{char serial_in;serial_in = RX_FIFO;SBC++;SBR++;SBR %= SerialBuf_size;SBC %= SerialBuf_size;HC12_input = 0;return serial_in ;}You need to do this when your ready to RXIFS1bits.U2RXIF = 0; // clear flag.IEC1bits.U2RXIE = 1; // Enable U2RX INTERRUPT.

author: netwinder
author_rank: Regular Contributor
timestamp: July 09, 2016, 05:56:14 pm
content: Quote from: 22swg on July 09, 2016, 08:39:12 amI tried this solution, i had to change the UART to refer to the 1st UART module because my pic does not have 2 UART modules. Either way I couldn't get it to work.Quote from: hans on July 09, 2016, 08:08:43 amHm, I do like your solution, so I combined it with 22swg's. I made a FIFO structure, and re-implemented.Still does not work. For now I'm just trying to make a serial repeater.My main.cCode:#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2 pin has clock out function)#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)#pragma config IOL1WAY = OFF // IOLOCK Protection (Allow Multiple Re-configurations)#include <xc.h>#define FCY 7370000/2 // All dsPIC33s, a few PIC24s#include <libpic30.h>#include "FIFOheader.h"#define BAUDRATE 9600#define BRGVAL ((FCY/BAUDRATE)/16)-1// Function prototypesextern void initUART(int baud);extern void UART1PutChar(char Ch);char getRXBuff();int main(void) {//Set up I/O PortAD1PCFGL = 0xFFFF; //set to all digital I/OTRISBbits.TRISB15 = 0; // LED pin is an outputRPINR18bits.U1RXR = 14; //UART1 receive set to RP14RPOR6bits.RP13R = 3; // Uart Transmit on RP13initUART(BRGVAL); // See formula on datasheetwhile (1) {UART1PutChar(getRXBuff());}return 0;}void initUART(int baud) {/*Enable Interrupts*/IEC0bits.U1RXIE = 1; // Interrupt on RX allowedIEC0bits.U1TXIE = 0; // No interrupts on TX/*Initialize UART1*/U1BRG = baud; //9600 baudU1MODEbits.UARTEN = 1;U1STAbits.UTXEN = 1; // Enable the TX}void UART1PutChar(char ch) {while (!U1STAbits.TRMT) {Nop();Nop();Nop();}U1TXREG = ch;LATBbits.LATB15 = 1; // Debug this pin with your scopeLATBbits.LATB15 = 0;}void __attribute__((__interrupt__)) _U1RXInterrupt(void); // Declarationvoid __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {if (IFS0bits.U1RXIF) { // RX-not-empty interrupt firedchar data = U1RXREG; // read register// store data in circular buffer; the main() code can read bytes from this bufferadd(data);IFS0bits.U1RXIF = 0; // reset interrupt}}char getRXBuff() // process the RX buffer{if(isEmpty() == 1) {return 0;} else {return get();}}My FIFO.cCode:/** File: FIFO.c* Author: netwinder** Created on July 9, 2016, 12:25 PM*/#include "FIFOheader.h"char FIFOArray;int tail = 0;// TOHEADERvoid add(char data) {addLast(data);}void addLast(char data) {if (tail == 32) {tail = 0;}FIFOArray = data;tail++;}char get() {if(isEmpty() == 1) {return 0;} else {return getFirst();}}char getFirst() {char temp = FIFOArray;FIFOArray = 0; // I would use null but i can'ttail--;return temp;}int isEmpty() {if(tail == 0) {return 1;} else {return 0;}}The FIFO.c header fileCode:/* Microchip Technology Inc. and its subsidiaries. You may use this software* and any derivatives exclusively with Microchip products.** THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A* PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION* WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.** IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS* IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF* ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.** MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE* TERMS.*//** File:* Author:* Comments:* Revision history:*/// This is a guard condition so that contents of this file are not included// more than once.#ifndef XC_HEADER_TEMPLATE_H#defineXC_HEADER_TEMPLATE_H#include <xc.h> // include processor files - each processor file is guarded.// TODO Insert appropriate #include <>// TODO Insert C++ class definitions if appropriate// TODO Insert declarations// Comment a function and leverage automatic documentation with slash star star/**<p><b>Function prototype:</b></p><p><b>Summary:</b></p><p><b>Description:</b></p><p><b>Precondition:</b></p><p><b>Parameters:</b></p><p><b>Returns:</b></p><p><b>Example:</b></p><code></code><p><b>Remarks:</b></p>*/// TODO Insert declarations or function prototypes (right here) to leverage// live documentationvoid add(char data);void addLast(char data);int isEmpty();char get();char getFirst();#ifdef__cplusplusextern "C" {#endif /* __cplusplus */// TODO If C++ is being used, regular C code needs function names to have C// linkage so the functions can be used by the c code.#ifdef__cplusplus}#endif /* __cplusplus */#endif/* XC_HEADER_TEMPLATE_H */Sorry for the raw code dump - i've been working at this structure for a few hours and I've been trying to debug the RX side of things to no avail.

author: Howardlong
author_rank: Super Contributor
timestamp: July 09, 2016, 07:08:14 pm
content: I've debugged the code.First, the code is continually writing to the UART, whether there's a character or not. I am not sure if this is what you want, but right now it's just sending nuls ('\0').Second, the ISR is being fired, and the character is read correctly from the RP14 pin.The buffer stuff isn't right though. you need a tail and a head, there's only a tail implemented.I'd get your buffer stuff working in a test harness first, maybe just on a PC in portable code, then port it.One further thing, it's fairly common nowadays to #include <stdint.h> so you can use the standard int8_t, uint8_t etc. This will help in portability.Whether you use a ciruclar buffer or a queue is up to you: I tend to use boilerplate queues for UART stuff.Also be careful of how much stuff you do in your ISR. Generally calling nested functions, or calling functions at all, is avoided, but this is a rule of thumb. Of course we all like modular code, but there is a balance between academically pleasing niceties and the reality of generating tight code that works well. In this case it's not a big deal, but when you start running at higher speed interrupts, it's worth bearing in mind, as you run the risk that your main() superloop is rarely getting any attention.

author: netwinder
author_rank: Regular Contributor
timestamp: July 09, 2016, 08:41:25 pm
content: Hello!I got it working, thank you howardlong for pointing me in the right direction. I can now successfuly receive some text and send it back.Kind of.Code:#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2 pin has clock out function)#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)#pragma config IOL1WAY = OFF // IOLOCK Protection (Allow Multiple Re-configurations)#include <xc.h>#define FCY 7370000/2 // All dsPIC33s, a few PIC24s#include <libpic30.h>#include <stdio.h>#include <stdlib.h>#include <limits.h>#define BAUDRATE 9600#define BRGVAL ((FCY/BAUDRATE)/16)-1#define QUEUESIZE 64// Function prototypesextern void initUART(int baud);extern void UART1PutChar(char Ch);char getRXBuff();struct Queue* createQueue(unsigned capacity);int isFull(struct Queue* queue);int isEmpty(struct Queue* queue);void enqueue(struct Queue* queue, int item);int dequeue(struct Queue* queue);int front(struct Queue* queue);int rear(struct Queue* queue);struct Queue* queue;int main(void) {//Set up I/O PortAD1PCFGL = 0xFFFF; //set to all digital I/OTRISBbits.TRISB15 = 0; // LED pin is an outputRPINR18bits.U1RXR = 14; //UART1 receive set to RP14RPOR6bits.RP13R = 3; // Uart Transmit on RP13initUART(BRGVAL); // See formula on datasheetwhile (1) {// Silly routine just to occupy the cpuprintf("TX\n");__delay_ms(1000);}return 0;}void initUART(int baud) {queue = createQueue(QUEUESIZE);/*Enable Interrupts*/IEC0bits.U1RXIE = 1; // Interrupt on RX allowedIEC0bits.U1TXIE = 0; // No interrupts on TX/*Initialize UART1*/U1BRG = baud; //9600 baudU1MODEbits.UARTEN = 1;U1STAbits.UTXEN = 1;}void UART1PutChar(char ch) {while (!U1STAbits.TRMT) {Nop();Nop();Nop();}U1TXREG = ch;}void __attribute__((__interrupt__)) _U1RXInterrupt(void); // Declarationvoid __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {if (IFS0bits.U1RXIF) { // RX-not-empty interrupt firedchar data = U1RXREG; // read register// store data in circular buffer; the main() code can read bytes from this bufferenqueue(queue, data);char c = (char)dequeue(queue) + 0;UART1PutChar(c);printf("\n");IFS0bits.U1RXIF = 0; // reset interrupt}}char getRXBuff() // process the RX buffer{if(isEmpty(queue) == 1) {return 0;} else {return dequeue(queue);}}/* --- QUEUE IMPLEMENTATION --- */// A structure to represent a queuestruct Queue{int front, rear, size;unsigned capacity;char* array;};// function to create a queue of given capacity. It initializes size of// queue as 0struct Queue* createQueue(unsigned capacity){struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));queue->capacity = capacity;queue->front = queue->size = 0;queue->rear = capacity - 1; // This is important, see the enqueuequeue->array = (int*) malloc(queue->capacity * sizeof(int));return queue;}// Queue is full when size becomes equal to the capacityint isFull(struct Queue* queue){ return (queue->size == queue->capacity); }// Queue is empty when size is 0int isEmpty(struct Queue* queue){ return (queue->size == 0); }// Function to add an item to the queue. It changes rear and sizevoid enqueue(struct Queue* queue, int item){if (isFull(queue))return;queue->rear = (queue->rear + 1)%queue->capacity;queue->array[queue->rear] = item;queue->size = queue->size + 1;}// Function to remove an item from queue. It changes front and sizeint dequeue(struct Queue* queue){if (isEmpty(queue)){return INT_MIN;}int item = queue->array[queue->front];queue->front = (queue->front + 1)%queue->capacity;queue->size = queue->size - 1;return item;}// Function to get front of queueint front(struct Queue* queue){if (isEmpty(queue))return INT_MIN;return queue->array[queue->front];}// Function to get rear of queueint rear(struct Queue* queue){if (isEmpty(queue))return INT_MIN;return queue->array[queue->rear];}Here's the output of me sending the text "hi" through a serial console$$TXTXetc. Should I change the queue to store the data as a char instead of an int? Because casting the int to char isn't working.

author: netwinder
author_rank: Regular Contributor
timestamp: July 09, 2016, 09:01:37 pm
content: Making progress...I probed the TX of the chip then sent a load of data to the RX, and it returned the same amount of bits... Just they were all null, I'll review my queue implementation.

author: 22swg
author_rank: Frequent Contributor
timestamp: July 09, 2016, 09:19:29 pm
content: Quote from: netwinder on July 09, 2016, 08:41:25 pmMy stab would be that there's too much going on in here .... Just save the byte , set a flag , reset the RX IF , and get outAdditional , as soon as you enable the RX interrupt you can get an RX interrupt immediately ! , clear the IF first.

author: netwinder
author_rank: Regular Contributor
timestamp: July 09, 2016, 11:51:13 pm
content: Hello,Its fixed. I can now send and recieve, here is the code completed with a new queue data structure (i figured the old one with pointers was too compilicated) so it got replaced with arrays.Code:#pragma config OSCIOFNC = OFF // Primary Oscillator Output Function (OSC2 pin has clock out function)#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)#pragma config IOL1WAY = OFF // IOLOCK Protection (Allow Multiple Re-configurations)#include <xc.h>#define FCY 7370000/2 // All dsPIC33s, a few PIC24s#include <libpic30.h>#include <stdio.h>#include <stdlib.h>#include <limits.h>#define BAUDRATE 9600#define BRGVAL ((FCY/BAUDRATE)/16)-1#define QUEUESIZE 64// Function prototypesextern void initUART(int baud);extern void UART1PutChar(char Ch);char getRXBuff();int isEmpty();void enqueue(char item);char dequeue();int main(void) {//Set up I/O PortAD1PCFGL = 0xFFFF; //set to all digital I/OTRISBbits.TRISB15 = 0; // LED pin is an outputRPINR18bits.U1RXR = 14; //UART1 receive set to RP14RPOR6bits.RP13R = 3; // Uart Transmit on RP13initUART(BRGVAL); // See formula on datasheetwhile (1) {if (isEmpty() == 1) {__delay_ms(1);} else {if(getRXBuff() == 'p'){printf("p is for pineapple\n");}}}return 0;}void initUART(int baud) {/*Enable Interrupts*/IEC0bits.U1RXIE = 1; // Interrupt on RX allowedIEC0bits.U1TXIE = 0; // No interrupts on TX/*Initialize UART1*/U1BRG = baud; //9600 baudU1MODEbits.UARTEN = 1;U1STAbits.UTXEN = 1;}void UART1PutChar(char ch) {while (!U1STAbits.TRMT) {Nop();Nop();Nop();}U1TXREG = ch;}void __attribute__((__interrupt__)) _U1RXInterrupt(void); // Declarationvoid __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {if (IFS0bits.U1RXIF) { // RX-not-empty interrupt firedchar data = U1RXREG; // read register// store data in circular buffer; the main() code can read bytes from this bufferenqueue(data);IFS0bits.U1RXIF = 0; // reset interrupt}}char getRXBuff() // process the RX buffer{if (isEmpty() == 1) {return 0;} else {return dequeue();}}/* --- QUEUE IMPLEMENTATION --- */// A structure to represent a queuechar queueData;int head = 0;int tail = 0;int refactoredSize = 0;// Queue is empty when size is 0int isEmpty() {if (refactoredSize == 0) {return 1;} else {return 0;}}void enqueue(char item) {if (refactoredSize == sizeof (queueData)) {return;} else {queueData = item;tail = (tail + 1) % sizeof (queueData);refactoredSize++;}}char dequeue() {if (isEmpty == 1) {return 0;} else {char temp = queueData;queueData = 0;head = (head + 1) % sizeof (queueData);refactoredSize--;return temp;}}There is one issue - in this code when 'p' is sent it responds p is for pineapple. If i probe the TX from the chip and decode it with my scope, it reads correctly. However In the serial console, its gibberish.I'll resolve this - but for now the problems are solved.Thanks everybody for the insight