Pause in UART Transmitted Values

Thread Starter

Harnee15

Joined Sep 14, 2015
24
Hi,
I am working with dspic33fj128mc804. UART used to send values from the PCB to the computer., transmits all the values but there is a tiny pause between the readings. I am sampling data at 8KHz . As the data is time critical I dont want to loose any values.
Could anyone please suggest something for this problem?

Many Thanks!!
 

Thread Starter

Harnee15

Joined Sep 14, 2015
24
Thank you very much! Below is my code.

C:
#define FIFO_SIZE 656
#define FIFO_MASK (FIFO_SIZE-1)
#define  MAX_CHNUM                7        // Highest Analog input number in Channel Scan
#define  SAMP_BUFF_SIZE            8        // Size of the input buffer per analog input
#define  NUM_CHS2SCAN            8        // Number of channels enabled for channel scan


unsigned int BufferA[8]__attribute__((space(dma)));
unsigned int BufferB[8]__attribute__((space(dma)));

/*=======================================================================
Used to set operating speed and default port directions along with setting
remappable peripherals
========================================================================= */

void setupPIC(void)
    {
        AD1PCFGL = 0xff00;
        CLKDIV=0;                    //reset DOZE
        //Setup for 7.37MIPS operation (internal FRC is 7.37MHz). To get mips, we need to x2 the OSC frequency
        PLLFBD=30;                    //32*(7.37/2)=117.92MHz
        CLKDIVbits.PLLPOST = 3;        //M=16, N1=2, N2=8
        CLKDIVbits.PLLPRE=0;        //Fosc = 7.37M*32/(2*8)=14.74MHz
        OSCTUN = 0;
        RCONbits.SWDTEN = 0;        //Disable watchdog timer
        __builtin_write_OSCCONH(0x01);        //Initiate Clock Switch
        __builtin_write_OSCCONL(0x01);        //Start Clock Switch
        while(OSCCONbits.COSC != 0b001);    //Wait for clock switching
        while (OSCCONbits.LOCK != 1);        //Wait for PLL to lock
        //Port mappings
        __builtin_write_OSCCONL(OSCCON & ~(1<<6));
        //inputs
        RPINR18bits.U1RXR = 20;    //txdto Pin RP19
        //outputs
        RPOR9bits.RP19R = 3;   // TXD of pic to RXD of UART(RP19)
        RPOR4bits.RP9R = 0x8;   //SCK to Pin RP9
        RPOR11bits.RP22R= 0x7; // SDO to Pin R22
        __builtin_write_OSCCONL(OSCCON | (1<<6));
        //Setup port directions
        LATA = 0x0000; TRISA = 0x0003;
        LATB = 0x2860; TRISB = 0x006f;
        LATC = 0x0100; TRISC = 0x0013;
        // Writing 0 means line On is pulled to ground
        B1L1=0; B1L2=0;
        B2L1=0; B2L2=0;
        B3L1=0; B3L2=0;
        B4L1=0; B4L2=0;
        //initializing resistance values
        res1=0x000;
        res2=0x000;
        res3=0x000;
        res4=0x000;
          // For random number generation
        max= 30;
        min= 10;
        range= max-min+1;
        // Set up Timer for Temperature Sensor. Prescaler 1:256; PR4 Preload = 57580; 2 sec
          PR4    = 57580;
        T4CON    = 0x8030;
        TMR4 = PR4>>1;
        _T4IE    = 0;
        _T4IF    = 0;
        // Set up Timer for schedule. Prescaler 1:256; PR3 Preload = 28790 for 1 sec;
        TMR2 = 0x0000;
        PR2    = 4999;
        T2CON    = 0x8000;
        _T2IE    = 0;
        _T2IF    = 0;

        //Timer 3 for ADC trigger
        TMR3 = 0x0000;
        T3CON    = 0x8000;
        PR3 = 4999; // Trigger ADC1 every  for 800Hz
        IFS0bits.T3IF = 0; // Clear Timer 3 interrupt
        IEC0bits.T3IE = 0; // Disable Timer 3 interrupt
        T3CONbits.TON = 1; //Start Timer 3

    }

/*=======================================================================
Initialize ADC
========================================================================= */

void initadc(void)
{

    AD1CON1bits.FORM = 0;        // Data Output Format: Integer
    AD1CON1bits.SSRC = 2;    //  GP Timer3 starts conversion
    AD1CON1bits.ASAM = 1;        // ADC Sample Control: Sampling begins immediately after conversion
    AD1CON1bits.AD12B = 1;        // SHEN : 12-bit ADC operation
    AD1CON2bits.CSCNA = 1;        // Scan Input Selections for CH0+ during Sample A bit
    AD1CON2bits.CHPS  = 0;        // Converts CH0
    AD1CON3bits.ADRC = 0;        // ADC Clock is derived from Systems Clock
    AD1CON3bits.ADCS = 65;        // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/7.37M)*64 = 1.6us (625Khz).
    AD1CON1bits.ADDMABM = 1;     // 1= Conversion order mode and 0 is DMA buffers are built in scatter/gather mode
    AD1CON2bits.SMPI    = (NUM_CHS2SCAN-1);    // 8 ADC Channels are scanned
    AD1CON4bits.DMABL   = 0;    //shen : Each buffer contains 1 word
    AD1CSSLbits.CSS0=1;         
    AD1CSSLbits.CSS1=1;         
    AD1CSSLbits.CSS2=1;         
    AD1CSSLbits.CSS3=1;         
    AD1CSSLbits.CSS4=1;
    AD1CSSLbits.CSS5=1;
    AD1CSSLbits.CSS6=1;
    AD1CSSLbits.CSS7=1;
    AD1CHS0=0;
    IFS0bits.AD1IF   = 0;        // Clear the A/D interrupt flag bit
    IEC0bits.AD1IE   = 0;        // Do Not Enable A/D interrupt
    AD1CON1bits.ADON = 1;        // Turn on the A/D converter
}

/*=======================================================================
Initialize DMA
========================================================================= */

void initDma0(void)
{
    DMA0CONbits.AMODE = 0;            // Configure DMA for Register Indirect Mode
    DMA0CONbits.MODE  = 0;            // Configure DMA for Continuous Ping-Pong mode disabled
    DMA0PAD=0x0300 ;                //shen : Point DMA to ADC1BUF0
    DMA0CNT = (SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;
    DMA0REQ = 13;                    // Select ADC1 as DMA Request source
    DMA0STA = __builtin_dmaoffset(&BufferA);
    DMA0STA = __builtin_dmaoffset(&BufferB);
    IFS0bits.DMA0IF = 0;            //Clear the DMA interrupt flag bit
    IEC0bits.DMA0IE = 1;            //Set the DMA interrupt enable bit

    DMA0CONbits.CHEN=1;                // Enable DMA

}

unsigned int DmaBuffer = 0;

/*=============================================================================
_DMA0Interrupt()
=============================================================================*/

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
    if(DmaBuffer == 0)
    {
     
ProcessADCSamples(BufferA[0]);
        ProcessADCSamples(BufferA[1]);
        ProcessADCSamples(BufferA[2]);
        ProcessADCSamples(BufferA[3]);
        ProcessADCSamples(BufferA[4]);
        ProcessADCSamples(BufferA[5]);
        ProcessADCSamples(BufferA[6]);
        ProcessADCSamples(BufferA[7]);
    }
    else
{
        ProcessADCSamples(BufferB[0]);
        ProcessADCSamples(BufferB[1]);
        ProcessADCSamples(BufferB[2]);
        ProcessADCSamples(BufferB[3]);
        ProcessADCSamples(BufferB[4]);
        ProcessADCSamples(BufferB[5]);
        ProcessADCSamples(BufferB[6]);
        ProcessADCSamples(BufferB[7]);


}

    DmaBuffer ^= 1;
    IFS0bits.DMA0IF = 0;        // Clear the DMA0 Interrupt Flag
}

void ProcessADCSamples(unsigned int AdcBuffer)
{
    //check=1;
    adResults[adChannelCounter]= AdcBuffer;
    adChannelCounter++;
//    adChannelCounter&=0x7;                     //Allows 0-7
    AD1CHS0=adChannelMap[adChannelCounter];    //set the channel
    if (adChannelCounter==7)        //rolled over, to have 8 samples
    {
    shouldWriteResults = 1;        //set flag.
adChannelCounter=0; 
}
//check=1;
}

/*=======================================================================
Turns a numeric 0-F to ASCII 0-9 and A-F
========================================================================= */

unsigned int nibbleToHex(int v)
    {
        v&=0xf;
        if (v>9) return (v+'A'-10); else return v+'0';
    }

/*=======================================================================
Convert ascii hex 0-F to int 0-F. Returns -1 if conversion not possible
========================================================================= */

int hexToNibble(char v)
    {
        if (v>47 && v<58)  return (v-48); else
        if (v>64 && v<71)  return (v-55); else
        if (v>96 && v<103) return (v-87); else return -1;
    }


/*=======================================================================
UART Set UP
========================================================================= */

void initUART()
    {
        txFIFOtail = txFIFOhead = 0;

    U1MODE=0;
//    U1MODEbits.BRGH = 1;
    U1BRG=3;            //Baud Rate 1574400
    U1MODE = 0x8800;    //EN, no flow control, no BRGH
    U1STA = 0x0400;        //only TXEN
    }

/*=======================================================================
Process UART FIFOs
========================================================================= */

void processUART()
    {
        char dummy=0;
        U1STA&=0xFFFD; //lear the OERR bit
        if (_U1RXIF)
            {
                dummy = U1RXREG;
                _U1RXIF = 0;
        //echo back //uartWriteByte(dummy);
                if (dummy!=0x0d) //% 0xd 0xa  is the ending of the line
                    {
                        if (uartCMDpos<16)
                            {
                                uartCMD[uartCMDpos++]=dummy;
                            } else
                                processUARTcmd();
                    } else
                        {
                            processUARTcmd();
                        }
          }

     if (!U1STAbits.UTXBF)
          {
                if (txFIFOtail != txFIFOhead)
                    {
                        U1TXREG = txFIFO[txFIFOtail];
                        txFIFOtail = (txFIFOtail + 1) & FIFO_MASK;
                    }
            }
    }



unsigned int portValues[5];

void processUARTcmd()
    {
        int i, dummy, wasError;
        //    unsigned int newOutput;
        if (uartCMDpos==5)
            {
                //    uartWriteString("!OK - applying values\r\n");
                wasError=0;
                //take each letter from uartCMDpos, must be 0-9, A-F. if okay, apply to relevant output. if not okay, break out and say so
                for (i=0; i<5; i++)
                    {
                        dummy = hexToNibble(uartCMD[I]);
                        if (dummy!=-1) portValues[I]=dummy; else { wasError=i+1; break; }
                    }
                if (wasError)
                    {
                        uartWriteString("!ERROR - expected 5 HEX values\r\n");
                    }
                else
                    {
                        LATB&=0x0FFF; LATB|=(portValues[4]<<12);
                    }
            } else uartWriteString("!ERROR - must be 5 letters followed by \\r\\n\r\n");

    uartCMDpos=0;
    uartCMD[0]='\0';
    }
/*=======================================================================
Writing to UART
========================================================================= */


/*=======================================================================
Sending a Byte
========================================================================= */
void uartWriteByte(unsigned int v)
    {
        txFIFO[txFIFOhead] = v & 0xFF;
        txFIFOhead = (txFIFOhead+1) & FIFO_MASK;
    }

/*=======================================================================
Send an Int, LSB first
========================================================================= */

void uartWriteInt(unsigned int v)
    {
        uartWriteByte(nibbleToHex(v>>4));
        uartWriteByte(nibbleToHex(v));
        uartWriteByte(nibbleToHex(v>>12));
        uartWriteByte(nibbleToHex(v>>8));
    }

/*=======================================================================
Send a word, LSB first
========================================================================= */

void uartWriteShort(unsigned char v)
    {
        uartWriteByte(nibbleToHex(v>>4));
        uartWriteByte(nibbleToHex(v));
    }

/*=======================================================================
Send a Decimal, LSB first
========================================================================= */
void uartWriteDecimal(unsigned int v)
    {
        unsigned int a=v/10000; char lead=0;
        if (a)       { uartWriteByte('0'+a); lead=1;  v-=a*10000; }
        a=v/1000;
        if (a||lead) { uartWriteByte('0'+a); lead=1;  v-=a*1000; }
        a=v/100;
        if (a||lead) { uartWriteByte('0'+a); lead=1;  v-=a*100; }
        a=v/10;
        if (a||lead) { uartWriteByte('0'+a); lead=1;  v-=a*10; }
        uartWriteByte('0'+v);
    }
/*=======================================================================
Write New Line 0x0d 0x0a values
========================================================================= */

void uartWriteNL(void)
    {
        //uartWriteByte(0x0d);
        uartWriteByte(0x0a);
    }
/*=======================================================================
Writes a string into the txFIFO_USB
========================================================================= */

void uartWriteString(const char* v)
    {
        while (*v) uartWriteByte(*v++);
    }



/*=======================================================================
Initialize DAC
========================================================================= */

void initDACs(void)
    {
        TRISB&=~0x4010;
        DAC1CS=DAC2CS=1;
        _SPI1IF = 0; // Clear the interrupt flag
        _SPI1IE = 0; // Disable the interrupt
        //Initialize SPI
        SPI1CON1=0x073e; //16bit, master, prescale 4, CKP0 CKE1 SMP 1
        SPI1STAT=0x8000; //enable SPI
        DAC1CS=0;DAC2CS=0;
        SPI1BUF = 0x3000;    //Set output of A to 0V
        while(!_SPI1IF); //wait until SPI has finished
        _SPI1IF = 0;
        DAC1CS=DAC2CS=1;
        SPI1STAT &=~0x40;
        DAC1CS=0;
        DAC2CS=0;
        SPI1BUF = 0xb000; // Set output of B to 0V
        while(!_SPI1IF); //wait until SPI has finished..****
        _SPI1IF = 0;
        DAC1CS=DAC2CS=1;
        SPI1STAT &=~0x40;
  }

/*=======================================================================
Function to set values on the DAC
========================================================================= */

void channelSetDACtwo(int v, int ch)
    {
        unsigned int sendData;
        if(ch>3) return;//wrong values
        if(ch &1)
            {
                sendData= 0x3000 | (v & 0xfff);
            }
        else
            {
                sendData= 0xb000 | (v & 0xfff);
            }

        if (ch <2) DAC1CS=0; else DAC2CS=0;
        SPI1BUF=sendData;
        while(!_SPI1IF); //wait until SPI has finished
        _SPI1IF = 0;
        DAC1CS=DAC2CS=1;
        SPI1STAT &=~0x40;//same like in init.... ****
        spiReady=1;
    }
Moderators note: Please use code tags for pieces of code
 
Last edited by a moderator:
Top