Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com 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.

[SOLVED] dsPIC30F6014A - Problem with UART Receive, using MPLAB C30 Compiler

Status
Not open for further replies.

miskol

Member level 4
Joined
Nov 6, 2008
Messages
75
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,288
Activity points
1,814
Hi guys,

i have tried programming the dsPIC30F6014A to make the UART1 and UART2 to function properly for days now.
1) i started with using CCS C Compiler, successfully able to send and receive from both UARTs. the problem is however:
- UART calls (e.g getc(), puts()) cannot be placed in a function, it works only in main().
- main problem is however, after calling few puts(), the mC freeze. after removing a single puts(), everything works again.
- suspecting the Compiler itself is buggy, i change my coding to MPLAB C30 Compiler.

2) using C30 Compiler is really hard, having to set manually configuration at low-level programming unlike CCS C Compiler. however i finally able to get the UARTs working, only 1 problem halting my progress:
- not able to check if data is available in receive buffer thus i also cannot check if i can receive from the UARTs with my coding.
- URXDA is always high.

Please help, most importantly on the case of using C30 Compiler. if anyone can share a working dsPIC30F6014A UART code that would be helpful. i have tried many Microchip given examples and they dont work out-of-the-box. my code is based on template given for 30F6014A. as shown is my coding using MPLAB C30 Compiler.

Please help, thank you.

Code:
#define FCY 20000000UL
#include <p30f6014A.h>
#include <libpic30.h>
#include <stdio.h>			   
#include <delay.h>
#include <uart.h>

//Configuration bits
_FWDT(WDT_OFF);
_FOSC(CSW_FSCM_OFF & HS);
_FBORPOR(PBOR_ON & BORV_27 & MCLR_EN);
_FGS(CODE_PROT_OFF);


/* Define constants		                            */

#define LED1 LATCbits.LATC13
#define LED2 LATCbits.LATC14

#define U1TXIF IFS0bits.U1TXIF
#define U1RXIF IFS0bits.U1RXIF
#define U1TXBF U1STAbits.UTXBF
#define U1TRMT U1STAbits.TRMT
#define U1RXDA U1STAbits.URXDA	//The URXDA status bit will be set whenever data is available in the buffer.

#define U2TXIF IFS1bits.U2TXIF
#define U2RXIF IFS1bits.U2RXIF
#define U2TXBF U2STAbits.UTXBF
#define U2TRMT U2STAbits.TRMT
#define U2RXDA U2STAbits.URXDA	//The URXDA status bit will be set whenever data is available in the buffer.

/************* START OF GLOBAL DEFINITIONS **********/
/* Define global variables without attributes */

int variable3;
char Buf[80];
char * Receiveddata = Buf;


/************** END OF GLOBAL DEFINITIONS ***********/

void ConfigIntUART1(unsigned int config);
void ConfigIntUART2(unsigned int config);
void OpenUART1(unsigned int config1,unsigned int config2, unsigned int ubrg);
void OpenUART2(unsigned int config1,unsigned int config2, unsigned int ubrg);
void WriteUART1(unsigned int data);
void WriteUART2(unsigned int data);
char DataRdyUART1(void);
char DataRdyUART2(void);
unsigned int ReadUART1(void);
unsigned int ReadUART2(void);

void mCputc(const char *str, int stream);
unsigned char mCgetc(int stream);
void mCnewLine(int stream);

/************* START OF MAIN FUNCTION ***************/

int main ( void )
{
	unsigned int baudvalue;
	unsigned int UMODEvalue;
	unsigned int UXSTAvalue;
	unsigned int RX1_data;
	unsigned int RX2_data;

	LATC = 0x0000; //Initialize LED pin data to off state
	TRISC = 0x0000; //Set LED pins (PORTC) as outputs
	LED1 = 0; LED2 = 0;
	U1RXIF = 0; U2RXIF = 0;
	U1RXDA = 0;

	/* Turn off UART1module */
	CloseUART1(); CloseUART2();

	/* Configure uart1 & uart2 receive and transmit interrupt */
	ConfigIntUART1(UART_RX_INT_EN & UART_RX_INT_PR1 & UART_TX_INT_DIS & UART_TX_INT_PR2);
	ConfigIntUART2(UART_RX_INT_EN & UART_RX_INT_PR1 & UART_TX_INT_DIS & UART_TX_INT_PR2);

	/* Configure UART1 module to transmit 8 bit data with one stopbit. */
	baudvalue = 32;
	UMODEvalue = UART_EN & UART_IDLE_CON &
		UART_DIS_WAKE & UART_NO_PAR_8BIT & 
		UART_1STOPBIT;
	UXSTAvalue = UART_INT_TX_BUF_EMPTY &
		UART_TX_PIN_NORMAL &
		UART_TX_ENABLE &
		UART_INT_RX_3_4_FUL &
		UART_ADR_DETECT_DIS &
		UART_RX_OVERRUN_CLEAR;

	OpenUART1(UMODEvalue, UXSTAvalue, baudvalue);
	OpenUART2(UMODEvalue, UXSTAvalue, baudvalue);

	while(1)
	{
		LED1 = 1; __delay_ms(10);
		LED1 = 0; __delay_ms(10);

		mCputc("UART1 Send!", 1); __delay_ms(1); mCnewLine(1);
		mCputc("UART2 Send!", 2); __delay_ms(1); mCnewLine(2);		
		if(U1RXDA==1) // check if data is ready in UART1 
                //** problem is here, the mC always comes in here even though no input to UART1 is given.
		{ 
			LED2 = 1; __delay_ms(10);
			RX1_data = ReadUART1();
			LED2 = 0; __delay_ms(10);
		}
	}
}


void mCputc(const char *str, int stream)
{
	if (stream == 1)
	{
		while((*str) != 0)
		{		
			while(U1TXIF && U1TXBF);	//Wait for TXREG Buffer to become available and TX Buffer is empty		
			U1TXREG = (*str);			//Write data
			str++;						//Next goto char
		}
	}
	if (stream == 2)
	{
		while((*str) != 0)
		{		
			while(U2TXIF && U2TXBF);	//Wait for TXREG Buffer to become available and TX Buffer is empty		
			U2TXREG = (*str);			//Write data
			str++;						//Next goto char
		}
	}
}

unsigned char mCgetc(int stream)
{
	char RX_BUF;
	if (stream == 1)
	{
		while(!U1RXIF);	//Wait for a byte
		U1RXIF = 0;
		RX_BUF = U1RXREG;
	}
	if (stream == 2)
	{
		while(!U2RXIF);	//Wait for a byte
		U2RXIF = 0;
		RX_BUF = U1RXREG;	
	}
	return (RX_BUF);
}

void mCnewLine(int stream)
{
	if (stream == 1)
	{
		while(U1TXIF && U1TXBF); WriteUART1(10); 
		while(U1TXIF && U1TXBF); WriteUART1(13);
	}
	if (stream == 2)
	{
		while(U2TXIF && U2TXBF); WriteUART2(10); 
		while(U2TXIF && U2TXBF); WriteUART2(13);
	}
}


/****** START OF INTERRUPT SERVICE ROUTINES *********/
/* This is UART1 transmit ISR */
void __attribute__((interrupt, auto_psv)) _U1TXInterrupt(void)
{
	U1TXIF = 0;
}

/* This is UART1 receive ISR */
void __attribute__((interrupt, auto_psv)) _U1RXInterrupt(void)
{
	U1RXIF = 0;
	/* Read the receive buffer till atleast one or more character can be
	read */
	while(DataRdyUART1())
	{
		( *( Receiveddata)++) = ReadUART1();
	}
}

/* This is UART2 transmit ISR */
void __attribute__((interrupt, auto_psv)) _U2TXInterrupt(void)
{
	U2TXIF = 0;
}

/* This is UART1 receive ISR */
void __attribute__((interrupt, auto_psv)) _U2RXInterrupt(void)
{
	U2RXIF = 0;
	/* Read the receive buffer till atleast one or more character can be
	read */
	while(DataRdyUART2())
	{
		( *( Receiveddata)++) = ReadUART2();
	}
}


/********* END OF INTERRUPT SERVICE ROUTINES ********/
 

Hi,

for updates, i have been able to use both dsPIC30F6014A's UART1 and UART2.

below is the functions that can be used for Transmit, Receive, and Send String:

Examples of use:

for Transmit
// character 'a' will be sent through UART1
mCputc('a', 1);

// character 'a' will be sent through UART2
mCputc('a', 2);


for Receive
char status;
// variable status will receive a character from UART1
status = mCgetc(1);

// variable status will receive a character from UART2
status = mCgetc(2);


for String
// send a string through UART1
mCputs("Initialization Complete...\r\n", 1);

// send a string through UART2
mCputs("Initialization Complete...\r\n", 2);

Code:
    /*******************************************************************************
    * PUBLIC FUNCTION: mCputc
    *
    * PARAMETERS:
    * ~ uc_data        - The data that we want to transmit.
    * ~ stream        - '1' to select UART module for UART1 and '2' for UART2.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * This function will transmit one byte of data using UART1 or UART2. This is a blocking
    * function, if the transmit buffer is full, we will wait until the
    * data in the buffer has been sent out before we move in the new data.
    *
    *******************************************************************************/
    void mCputc(unsigned char uc_data, int stream)
    {
        switch (stream)
        {
            case 1:   
                // Wait until the transmit buffer is ready for new data.
                while (U1STAbits.UTXBF == 1);
                // Transmit the data.
                U1TXREG = uc_data;
                break;
            case 2:
                // Wait until the transmit buffer is ready for new data.
                while (U2STAbits.UTXBF == 1);
                // Transmit the data.
                U2TXREG = uc_data;
                break;
        }
    }


    /*******************************************************************************
    * PUBLIC FUNCTION: mCgetc
    *
    * PARAMETERS:
    * ~ stream        - '1' to select UART module for UART1 and '2' for UART2.
    *
    * RETURN:
    * ~ The data received from the UART1 or UART2.
    *
    * DESCRIPTIONS:
    * This function will receive one byte of data using UART1 or UART2. This is a blocking
    * function because if the receive buffer is empty, we will wait until the
    * data is received.
    *
    *******************************************************************************/
    unsigned char mCgetc(int stream)
    {
        unsigned char receive;
        switch (stream)
        {
            case 1:   
                // Wait until there is data available in the receive buffer.
                while (U1STAbits.URXDA == 0);           
                // Clear the overflow bit and return the received data.
                U1STAbits.OERR = 0;
                receive = U1RXREG;
                break;
            case 2:
                // Wait until there is data available in the receive buffer.
                while (U2STAbits.URXDA == 0);   
                // Clear the overflow bit and return the received data.
                U2STAbits.OERR = 0;
                receive = U2RXREG;   
                break;
        }
        return receive;
    }


    /*******************************************************************************
    * PUBLIC FUNCTION: mCputs
    *
    * PARAMETERS:
    * ~ csz_string    - The null terminated string to transmit.
    * ~ stream        - '1' to select UART module for UART1 and '2' for UART2.
    *
    * RETURN:
    * ~ void
    *
    * DESCRIPTIONS:
    * Transmit a string using UART1 and UART2.
    *
    *******************************************************************************/
    void mCputs(const char* csz_string, int stream)
    {
        switch (stream)
        {
            case 1:
                // Loop until the end of string.
                while (*csz_string != '\0')
                {
                    uart1_transmit(*csz_string);    //Write data  
                    csz_string++;                    // Point to next character.
                }
                break;
            case 2:
                // Loop until the end of string.
                while (*csz_string != '\0')
                {
                    uart2_transmit(*csz_string);    //Write data  
                    csz_string++;                    // Point to next character.
                }
                break;
        }
    }
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top