Printing text from the dsPIC30F4011 to a PC via UART

This is a simple example of sending text from a dsPIC30F4011 microcontroller to a PC via the UART. This program toggles an LED on RD0 once every second. Each time the LED is switched on or off, the word “Hello” is transmitted via the UART using the printf function.

Here’s the code:

//
// dsPIC30F4011 UART Example
// Written by Ted Burke
// Last updated 27-8-2012
//

#include <xc.h>
#include <stdio.h>
#include <libpic30.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

int main()
{
	TRISD = 0; // Set all port D pins as outputs

	// Setup UART - most default options are fine
	U1BRG = 48;            // 38400 baud @ 30 MIPS
	U1MODEbits.UARTEN = 1; // Enable UART

	while(1)
	{
		printf("Hello\r\n"); // Send text via UART
		_LATD0 = 1 - _LATD0; // Toggle LED on RD0
		__delay32(30000000); // 1 second delay
	}

	return 0;
}

The PICkit2 helper application provides a UART tool that’s probably the easiest way of viewing the text printed by the dsPIC. This tool can be found in the “Tools” menu of the PICkit2 application. Once the UART tool window opens, set the baudrate t0 38400 using the drop down box in the top left corner of the window. Ensure that the VDD check box is ticked so that power is supplied to the circuit. Finally, click the “Connect” button and you should see the trasmitted text appearing in the text window, as shown below:

This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

12 Responses to Printing text from the dsPIC30F4011 to a PC via UART

  1. Pingback: Simple UART (Universal Asynchronous Receiver/Transmitter) “Soft Loop” using the dsPIC30F4011 & Python Terminal Program « COG Projects

  2. nerd says:

    Hi Ted, how do you configure the same dsPic30F4011 to a baud rate of 115200 to be able to use Bluetooth RN 42. I have been struggling.

    • batchloaf says:

      Hi Nerd,

      Assuming you’re running the dsPIC30F4011 at 30MIPS (as is the case in my example above), then you can set the baudrate to 115200 as follows:

      // Setup UART - most default options are fine
      U1BRG = 15; // approximately 115200 baud @ 30 MIPS
      U1MODEbits.UARTEN = 1; // Enable UART
      

      Note that the baudrate will not be exactly 115200. By setting U1BRG = 15, you’re actually setting the baud rate to 117187.5, but that’s probably close enough. Unless you’re using a crystal to set the clock speed of the chip, the baud rate you get is always going to be quite approximate.

      You can read more about U1BRG and how the baud rate is generated in section 18.8 of the dsPIC30F4011 datasheet.

      Does that answer your question?

      Ted

      • Here is my code:
        //Y-hust
        #include
        #include
        #include
        _FOSC(CSW_FSCM_OFF &FRC_PLL16 )//& FRC_PLL16); // Fosc=4*7.37Mhz,fcy=fosc/4=30mhz
        _FWDT(WDT_OFF);

        #define ledx TRISDbits.TRISD3
        #define led LATDbits.LATD3

        void delay(unsigned long int t) {
        while (t–);
        }

        void Timer4()
        { IFS1bits.T4IF=0;
        IEC1bits.T4IE = 1; // allow interrupt timer 3
        IPC5bits.T4IP = 0b011; // priority :3
        T4CONbits.TCKPS = 0b11; // prescale =1/1
        PR4 = 10000;
        led=0;
        T4CONbits.TON = 1; // on
        }
        void __attribute__((interrupt, auto_psv)) _T4Interrupt(void) // T4
        {
        led=~led;
        IFS1bits.T4IF = 0;
        }
        ////////********************************* UART**************************////////////////////////////////////////////////
        void OpenUART1(void)
        {
        U1MODEbits.STSEL = 0; /* 1 Stop bit */
        U1MODEbits.PDSEL = 0; /* No Parity, 8 data bits */
        U1MODEbits.ABAUD = 0; /* Auto-Baud Disabled */
        //U1MODEbits.BRGH = 1; /* High Speed mode */
        U1BRG = 48; /* BAUD Rate Setting for: */ //
        U1MODEbits.UARTEN = 1; /* Enable UART */
        U1STAbits.UTXEN = 1; /* Enable UART TX1 */
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////
        char BusyUART1(void)
        {
        /* flag for transission */
        if (!IFS0bits.U1TXIF)
        return 1;
        else
        {
        IFS0bits.U1TXIF = 0; /* clear flag */
        return 0;
        }

        }
        void WriteCharToUART1(unsigned char Data)
        {
        U1TXREG = Data;
        while (BusyUART1());
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////
        void PrintStringUART1(unsigned char *String)
        {
        while (*String)
        {
        WriteCharToUART1(*String++);
        }
        }
        /////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////
        void sendBits(unsigned int x) {
        while(U1STAbits.UTXBF);
        U1TXREG = x & 0xff;
        while(U1STAbits.UTXBF);
        U1TXREG = x ;
        }
        ////////////////////***********main here********////////////////////
        int main()
        {
        // TRISFbits.TRISF3=0; // UART Tx
        // TRISFbits.TRISF2=1; //Rx

        TRISDbits.TRISD2=0;
        LATDbits.LATD2=0;
        ledx=0;
        char buf[80];
        unsigned char F[] = “Frequency:”;
        unsigned char Hz[] = “Hz”;
        double f;
        OpenUART1();
        PrintStringUART1(F);
        WriteCharToUART1(10); // mandatory
        Timer4();

        while(1)
        {
        f=50;
        WriteCharToUART1(13);
        delay(300);
        sprintf(buf,”f=%3.1f “,f); //
        PrintStringUART1((unsigned char*)buf);
        PrintStringUART1(Hz);
        __delay32(28000000); // 1 second delay

        }
        return 0;
        }
        and here was i recevied : “‘;’&%$&” i dont know exactly how to describe them :(.
        Help me.

  3. My band rate at 38400,using Timer4() to show my board is ok.thanks

  4. Kwetso says:

    hi am trying to send the values of the samples from my ADC to my terminal using the UART please help 😦

    • batchloaf says:

      Try this 🙂

      //
      // sampler.c - print analog samples via UART
      // Written by Ted Burke - 25-8-2017
      //
      // To build as a hex file (sampler.hex):
      //
      //   xc16-gcc sampler.c -o sampler.out -mcpu=30F4011 -Wl,--script=p30F4011.gld
      //   xc16-bin2hex sampler.out
      //
      
      #include <xc.h>
      #include <stdio.h>
      #include <libpic30.h>
      
      // Configuration settings
      _FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
      _FWDT(WDT_OFF);                  // Watchdog timer off
      _FBORPOR(MCLR_DIS);              // Disable reset pin
      
      // Function prototypes
      void configure_pins();
      unsigned int read_analog_channel(int n);
      
      void main()
      {
          // Configure AN0-AN8 as analog inputs
          ADCON3bits.ADCS = 15;  // Tad = 266ns, conversion time is 12*Tad
          ADCON1bits.ADON = 1;   // Turn ADC ON
      
          // Setup UART
          U1BRG = 48;            // 38400 baud @ 30 MIPS
          U1MODEbits.UARTEN = 1; // Enable UART
      
          int v; // variable to store sample value
      
          while(1)
          {
              v = read_analog_channel(0); // Read sample
              printf("%d\n", v);          // Print sample
              __delay32(30000000);        // 1 second delay
          }
      }
      
      // This function reads a single sample from the specified
      // analog input. It should take less than 2.5us if the chip
      // is running at about 30 MIPS.
      unsigned int read_analog_channel(int channel)
      {
          ADCHS = channel;          // Select the requested channel
          ADCON1bits.SAMP = 1;      // start sampling
          __delay32(30);            // 1us delay @ 30 MIPS
          ADCON1bits.SAMP = 0;      // start Converting
          while (!ADCON1bits.DONE); // Should take 12 * Tad = 1.2us
          return ADCBUF0;
      }
      
    • batchloaf says:

      PS I wrote a handy little program for displaying incoming UART text in a terminal:

      https://batchloaf.wordpress.com/comprinter/

      It’s free and very easy to use.

  5. Hey I want to print something not using printf when a push button is pressed. Can you guys help?

    • batchloaf says:

      Why don’t you want to use printf?! You don’t need to, but it’s the easiest way to do it on the dsPIC30F. If you really don’t want to use printf, I suppose you can feed characters into the UARTs output buffer one by one. I’ve never bothered doing that on the dsPIC though!

      Ted

  6. Sumitabha Banerjee says:

    Hi. Can you please tell me whether the printf function automatically connects to the uart, or do I have to do anything extra? I am working with dsPIC30f4011, and the demo program provided by microchip seems quite confusing. My application is basically trying to log speed data from a rotary encoder every 0.03 sec using a timer. However I am not getting any output on my serial terminal. Please help

    • batchloaf says:

      Hi Sumitabha,

      Sorry for the delay replying. I can’t keep up with my comments!

      Basically, yes, printf will automatically print to the default UART. You do need to enable the UART and set the baud rate, which I do in the example above with these lines:

      // Setup UART - most default options are fine
      U1BRG = 48; // 38400 baud @ 30 MIPS
      U1MODEbits.UARTEN = 1; // Enable UART
      

      …but that’s it. There is a way that you can redirect printf to the second UART, but I can’t remember the exact code off the top of my head. Anyway, assuming you’re using the default UART you don’t need to worry about that.

      Ted

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s