Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Feeding data from PC to on-chip DAC through UART

Not open for further replies.


Member level 1
Sep 8, 2009
Reaction score
Trophy points
Activity points
Hi everyone,

I want to send a file from my laptop to PIC33FJ128GP802 through UART and then pass the data to on chip DAC. The file contains samples of a sinusoidal signal, which was sampled at 8038Hz. I managed to write the code, which as i thought should do the job, but when I sensed the output with the oscilloscope , I got a blinking sinusoid with a line at 0 volts across it. The line at 0 volts is probably the default output value of the DAC, which means that data isn't transferred fast enough for the DAC to reproduce the actual signal. Uart is configured as follows:
Baud rate: 19200
8, N, 1.
Rx generates interrupt after 2 chars are received.

To the best of my knowledge baud rate of 19200 should be enough, however there is one thing I'm not sure of: when I send the file from PC (via RealTerm), CPS (chars per second) is approximately 1700 when baud rate is set to 9600 and approximately 3500 when baud rate is 19200. I thought that baud rate of 9600 means that data is sent at 9600 chars per second, but what i see in real term proves me wrong.

PS, is there a way to plot a wave from the data file containing samples of the signal., some software or something? I just want to be sure that the file contains the right data.

The baud rate is the number of signal transitions per second, which is related to the bit rate.
With 8 data bits and one stop bit, at 19200 baud you could only expect to get ~2150 chars per second!

You could use this free program from Microchip to plot your data:
dsPICworks; Signal Analysis and Visual DSP Design Software

Available here:
**broken link removed**

You could try just sending one cycle of the sine wave, and the micro could just repeat it until you change the data?


    Points: 2
    Helpful Answer Positive Rating
thanks for prompt reply, the software you advised me was really helpful. Now I know for sure, that the part of the code that converts analogue signal and sends the data to PC works fine. However the problem with the DAC is still unsolved. Am I right saying that in order to transmit an 8KHz sampled signal (each sample is 2 byte long) through UART, the minimum baud rate should be 128KBaud?

I think you are going to have to set the baud rate as high as possible and see what results you get?


    Points: 2
    Helpful Answer Positive Rating
I have noticed a very strange thing about my program, when it transmits data files to microcontroller and receives data from ADC at the same time, the Tx pin of the uart stops working at baud rates above 57600. I have also tested a sample program from microchip, called UART loopback with DMA, and encountered the same problem again.
After some time after the file transfer is initiated, Tx pin of the uC stops sending data to PC, however, at baud rates 19200 and below everything works fine. Does anyone know what could be the cause of the problem?
I am using 16 bit 28 pin starter board with ICD3 in debug mode. To the best of my knowledge, the board has a PIC18 which is used for uart to usb communication. Could it be that Pic 18 is too slow for baud rates of 57600 and above?

Added after 2 hours 50 minutes:

here is the source code for data transfer from PC to DAC:

#include "p33fxxxx.h"
#include "dsp.h"
//#include "C:\Users\fed5552\Desktop\DACUART\h\adcdacDrv.h"
#include "p33FJ128GP802.h"
#define Fosc 79227500
#define Fcy (Fosc/2)
#define Fs 8038//103160 //8038 //44211 //25000 // //Hz
#define NUMSAMP 32
#define FCY 40000000
#define BAUDRATE 115200
#define BRGVAL ((FCY/BAUDRATE)/16)-1
fractional BufferA[NUMSAMP] __attribute__((space(dma))); // Ping-pong buffer A
fractional BufferB[NUMSAMP] __attribute__((space(dma))); // Ping-pong buffer B
//Configure DAC module
void initDac(void)
/* Initiate DAC Clock */
ACLKCONbits.SELACLK = 0; // FRC w/ Pll as Clock Source
ACLKCONbits.AOSCMD = 0; // Auxiliary Oscillator Disabled
ACLKCONbits.ASRCSEL = 0; // Auxiliary Oscillator is the Clock Source
ACLKCONbits.APSTSCLR = 7; // FRC divide by 1
DAC1STATbits.ROEN = 1; // Right Channel DAC Output Enabled
DAC1DFLT = 0x8000; // DAC Default value is the midpoint
DAC1CONbits.DACFDIV = 76; // Divide High Speed Clock by DACFDIV+1
DAC1CONbits.FORM = 1; // Data Format is signed integer
DAC1CONbits.AMPON = 0; // Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode
DAC1CONbits.DACEN = 1; // DAC1 Module Enabled

// dma0 Configuration
void DacDma0init(void)
DMA0CONbits.AMODE = 0; /* Register Indirect with Post Increment */
DMA0CONbits.MODE = 1; /* one shot mode Enabled */
DMA0CONbits.DIR = 1; /* Ram-to-Peripheral Data Transfer */
DMA0PAD = (volatile unsigned int)&DAC1RDAT; /* Point DMA to DAC1RDAT */
DMA0CNT = NUMSAMP-1; /* 32 DMA Request */
DMA0REQ = 78; /* Select DAC1RDAT as DMA Request Source */
DMA0STA = __builtin_dmaoffset(BufferA);
DMA0STB = __builtin_dmaoffset(BufferB);
IFS0bits.DMA0IF = 0; /* Clear DMA Interrupt Flag */
IEC0bits.DMA0IE = 1; /* Set DMA Interrupt Enable Bit */
DMA0CONbits.CHEN = 1; /* Enable DMA Channel 0 */
void cfgUart2(void)
U1MODEbits.STSEL = 0; // 1-stop bit
U1MODEbits.PDSEL = 0; // No Parity, 8-data bits
U1MODEbits.ABAUD = 0; // Autobaud Disabled
U1BRG = BRGVAL; // BAUD Rate Setting for 9600
RPINR18 = 9; // Make Pin RP9 U1RX
RPOR4bits.RP8R = 3; // Make Pin RP8 U1TX
AD1PCFGL = 0x03C0; // Make analog pins digital
U1STAbits.URXISEL = 0; // Interrupt after one RX character is received
U1MODEbits.UARTEN = 1; // Enable UART
IEC4bits.U1EIE = 0;

// DMA3 configuration
void cfgDMA3UartRx(void)
DMA3REQ = 0x000B; // Select UART2 Receiver
DMA3PAD = (volatile unsigned int) &U1RXREG;
DMA3CONbits.AMODE = 0;
DMA3CONbits.MODE = 2;
DMA3CONbits.DIR = 0;
DMA3CONbits.SIZE = 1;
DMA3CNT = NUMSAMP*2-1; // 8 DMA requests
DMA3STA = __builtin_dmaoffset(BufferA);
DMA3STB = __builtin_dmaoffset(BufferB);
IFS2bits.DMA3IF = 0; // Clear DMA interrupt
IEC2bits.DMA3IE = 1; // Enable DMA interrupt
DMA3CONbits.CHEN = 1; // Enable DMA Channel

unsigned int DmaBuffer = 0;
int flag = 0;

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag;

void __attribute__((interrupt, no_auto_psv)) _DMA3Interrupt(void)
static unsigned int BufferCount = 0; // Keep record of which buffer contains Rx Data

if(BufferCount == 0)
DMA0STA = __builtin_dmaoffset(BufferA); // Point DMA 0 to data to be transmitted
DMA0STA = __builtin_dmaoffset(BufferB); // Point DMA 0 to data to be transmitted

DMA0CONbits.CHEN = 1; // Re-enable DMA0 Channel
DMA0REQbits.FORCE = 1; // Manual mode: Kick-start the first transfer

BufferCount ^= 1;
IFS2bits.DMA3IF = 0; // Clear the DMA3 Interrupt Flag

void __attribute__ ((interrupt, no_auto_psv)) _U1ErrInterrupt(void)
IFS4bits.U1EIF = 0; // Clear the UART2 Error Interrupt Flag

Can't figure out what is wrong with it.

Added after 6 minutes:

It is also strange that sending a 80Kb file to microcontroller from PC at 115200 baud rate takes approximately 42 seconds.

Added after 4 minutes:

Main looks like that:

#include <p33FJ128GP802.h>
#include "dsp.h"
//#include "C:\Users\fed5552\Desktop\DACUART\h\adcdacDrv.h"
#if defined(__dsPIC33F__)
#include "p33Fxxxx.h"
#elif defined(__PIC24H__)
#include "p24Hxxxx.h"

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software
// (LPRC can be disabled by clearing SWDTEN bit in RCON register

int main(void)
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
PLLFBD=41; // M=43
CLKDIVbits.PLLPOST=0; // N1=2
CLKDIVbits.PLLPRE=0; // N2=2
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to Primary
// Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01); // Start clock switching
while(OSCCONbits.LOCK!=1) {}; // Wait for PLL to lock
RPINR18 = 9; // Make Pin RP9 U1RX
RPOR4bits.RP8R = 3; // Make Pin RP8 U1TX
while (1); // Loop Endlessly - Execution is interrupt driven

Can someone please help to find the problem, I am out of ideas.

Not open for further replies.

Part and Inventory Search

Welcome to