[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

Cookies are required to use this site. You must accept them to continue using the site. Learn more…