USART Receive Problems

Thread Starter

crazyengineer

Joined Dec 29, 2010
156
Hello everyone. I'm having difficulty trying to get the PIC18F2420 to receive the messages that I send it using the Arduino terminal. I can get the PIC to send messages to the terminal fine, but it seems like it cannot receive anything.

Rich (BB code):
/*	Includes */
#include <p18F2420.h>
#include <delays.h>
#include <portb.h>
#include <usart.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*	PIC Configuratings */
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF 
#pragma config PWRT = ON 
#pragma config DEBUG= OFF
//#pragma config BOREN = OFF
char data;
char message[100];



void main(void)
{
	OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 10);
	while(1)
	{
		
		if(DataRdyUSART())
		{
			data=ReadUSART();
			sprintf(message,"Hello %c \r\n",data);
			putsUSART(message);
			while(BusyUSART());
		}

	}
	CloseUSART();
}
The above code should just print hello and the character you type in the display. However, whenever I type the message, I don't even see the message.
 

tshuck

Joined Oct 18, 2012
3,534
try commenting out the sprintf and see it you can use the UART functions... this may not be printing to the proper output stream...
 

spinnaker

Joined Oct 29, 2009
7,830
Are you certain data is indeed being sent to the Audrino? Do you have a scope that you can put on your input pin?

Have you tried debugging your code? Is it going past DataRdyUSART()
 

Thread Starter

crazyengineer

Joined Dec 29, 2010
156
IDK why, but it seems like it's working now. However,I'm really doing this for a research. I'm trying to write a pic code which outputs the encoder velocity, acceleration, and position a certain number of times.Bassically, if I send "c100", it should print the velocity, acceleration, and position 100 times. However, it seems like the code works, when I comment out the timer configuration code

Rich (BB code):
#include <p18F2420.h>
#include <delays.h>
#include <portb.h>
#include <usart.h>
#include <stdio.h>
#include <stdlib.h>

/*	PIC Configuratings */
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF 
#pragma config PWRT = ON 
#pragma config DEBUG= OFF
//#pragma config BOREN = OFF


/*	Global Variables Encoder*/
int encoder_previous_pos=0;
int encoder_previous_state=0;
int encoder_current_state=0;
int encoder_state_ticks=0;
int encoder_ticks=0;
int encoder_previous_ticks=0;
int encoder_current_velocity=0;
int encoder_pos=0;
int encoder_previous_velocity=0;
int timer_counts=0;
int acceleration=0;
int time_stamp=0;
/*	Global Variables for USART */
char message[100];
char command[4];
char test[3];
int v=0;
int index=0;

void GET_ENCODER_TICKS(void);
void GET_ENCODER_DATA(void);
void PIC_CONFIG(void);
void PIC_EXT_CONFIG(void);
void PIC_TIMER_CONFIG(void);

#pragma interrupt ISR
void ISR (void)
{ 
	if(INTCONbits.INT0IF==1 || INTCON3bits.INT1IF==1)
	{
		GET_ENCODER_TICKS();
	}
	if(INTCONbits.TMR0IF==1)
	{
		if(timer_counts==40)						//	Checks to see if .02 seconds passed
		{
			timer_counts=0;							//	Resets timer counts
			GET_ENCODER_DATA();						//  Retrieve encoder velocity
			time_stamp+=5;
		}
		else
		{
			timer_counts+=1;
		}
		INTCONbits.TMR0IF=0;
	}

}
#pragma code InterruptVectorHigh = 0x08				//	This function simply jumps to the ISR code shown above.
void InterruptVectorHigh (void)
{
	_asm
	goto ISR //jump to interrupt routine
	_endasm
}
#pragma code

void main(void)
{
//	PIC_CONFIG();
	OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 10);
	while(1)
	{	
		
		if(DataRdyUSART())
		{
			getsUSART(command,4);
			if(command[0]=='c')
			{
				sprintf(test,"%c%c%c",command[1],command[2],command[3]);
				v=atoi(&test);
				for(index;index<v;index++)
				{
					sprintf(message,"Hello World \r\n",v);
					putsUSART(message);
					while(BusyUSART());
				}
				index=0;
			}
		}
					
			
			
	}

	CloseUSART();
}

void PIC_CONFIG(void)
{
	/*	Setting	PIC to use interrupts	*/
	RCONbits.IPEN=1;					//	Enable interrupt priority
	INTCONbits.GIE=1;					//	Enable global interrupts
	
	//	Call the external interrupt configuration function
	PIC_EXT_CONFIG();
	
	//	Call the timer interrupt configuration function
	PIC_TIMER_CONFIG();
	
	//	USART Configuration
	TRISC=0x00;
}

void PIC_EXT_CONFIG(void)
{
		/*	External Interrupt configuration for INT0 */
	INTCONbits.INT0IE=1;				//	Enables INT0
	INTCONbits.INT0IF=0;				//	Clears the flag
	INTCON2bits.INTEDG0=1;				//	Activates on rising edge
	
	/*	External Interrupt configuration for INT1 */
	INTCON3bits.INT1IE=1;				//	Enables INT1
	INTCON3bits.INT1IF=0;				//	Clears the flag
	INTCON2bits.INTEDG1=1;				//	Activates on rising edge
	
	//	External Interrupts final configurations
	INTCON2bits.RBPU=1;					// Disable Pull up
	TRISB=0x03;							//	Sets RB0 and RB1 as inputs
	PORTB=0x03;							// Enable high on inputs
}

void PIC_TIMER_CONFIG(void)
{
	//	Setup Timer 0 for interrupts
	INTCONbits.TMR0IE=1;
	INTCON2bits.TMR0IP=1;
	INTCONbits.TMR0IF=0;
	T0CONbits.T08BIT=1;
	T0CONbits.T0CS=0;
	T0CONbits.PSA=1;
	TMR0L=0;
	T0CONbits.TMR0ON=1;
}



void GET_ENCODER_TICKS(void)
{
	//	Checks to see if INT0 has been activated
		if(INTCONbits.INT0IF==1)
		{
		
			INTCON2bits.INTEDG0=~(INTCON2bits.INTEDG0);			//	Inverts the INTEDG0 bit
			INTCONbits.INT0IF=0;								//	Clears interrupt flag
		}
		
		//	Checks to see if INT1 has been activiated
		if(INTCON3bits.INT1IF==1)
		{
			
			INTCON2bits.INTEDG1=~(INTCON2bits.INTEDG1);				//	Inverts the INTEDG1 bit
			INTCON3bits.INT1IF=0;									//	Clears the flag
		}
		
		if(PORTBbits.RB0==1)
		{
			encoder_current_state+=1;
		}
		if(PORTBbits.RB1==1)
		{
			encoder_current_state+=2;
		}
		
		//	Checks to see if a new state has occured
		if(encoder_previous_state != encoder_current_state)
		{
			//	Checks the different states
			switch(encoder_current_state)
			{
				case 0:
					//	Checks to see if the previous state is equal to 2). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==2)
					{
						encoder_state_ticks+=1;	
					}
					else 
					{
						encoder_state_ticks-=1;
					}
					break;
				case 1:
					//	Checks to see if the previous state is equal to 0). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==0)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				case 3:
					//	Checks to see if the previous state is equal to 1). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==1)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				case 2:
					//	Checks to see if the previous state is equal to 3). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==3)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				//	This will do nothing
				default:
					break;
			}
			
			//	Checks to see if the encoder ticks is greater than or equal to 4 
			if(encoder_state_ticks>=4)
			{
				encoder_ticks+=1;		//	Increase the encoder pos
				encoder_state_ticks=0;
			}
			//	Checks to see if the encoder ticks is less than or equal to -4
			if(encoder_state_ticks<=-4)
			{
				encoder_ticks-=1;		//	Decrease the encoder pos
				encoder_state_ticks=0;
			}
			
			//	Sets the current state as the new previous state.
			encoder_previous_state=encoder_current_state;
			encoder_current_state=0;
		}
}

void GET_ENCODER_DATA(void)
{
	encoder_current_velocity=(encoder_ticks-encoder_previous_ticks)*500;
	acceleration=(encoder_current_velocity-encoder_previous_velocity)*500;
	encoder_pos=encoder_ticks/2;
	encoder_previous_ticks=encoder_ticks;
	encoder_previous_velocity=encoder_current_velocity;

}
 

spinnaker

Joined Oct 29, 2009
7,830
Because your ISR is huge. Just have the ISR clear the interrupt flag and have it set your own flag, process it in your main loop when the flag is set.
 

Thread Starter

crazyengineer

Joined Dec 29, 2010
156
Because your ISR is huge. Just have the ISR clear the interrupt flag and have it set your own flag, process it in your main loop when the flag is set.
Okay. So I edited the code so that the main function updates the encoder data. So when I tried to have the usart transmit the data whenever it detects c in the string I send it, it will output the encoder data. However, when I ran it in terminal, it just outputs the encoder data without waiting for the string first.


Rich (BB code):
/* Includes */
#include <p18F2420.h>
#include <delays.h>
#include <portb.h>
#include <usart.h>
#include <stdio.h>
#include <stdlib.h>

/*	PIC Configuratings */
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF 
#pragma config PWRT = ON 
#pragma config DEBUG= OFF
//#pragma config BOREN = OFF

/*	Global Variables Encoder*/
int encoder_previous_pos=0;
int encoder_previous_state=0;
int encoder_current_state=0;
int encoder_state_ticks=0;
int encoder_ticks=0;
int encoder_previous_ticks=0;
int encoder_current_velocity=0;
int encoder_pos=0;
int encoder_previous_velocity=0;
int timer_counts=0;
int acceleration=0;
int time_stamp=0;

/*	Global Variables for USART */
char message[100];
char command[4];
int index=0;

/* Interrupt Handling */
unsigned int timer_goal=0;

void GET_ENCODER_TICKS(void);
void GET_ENCODER_DATA(void);
void PIC_CONFIG(void);
void PIC_EXT_CONFIG(void);
void PIC_TIMER_CONFIG(void);

#pragma interrupt ISR
void ISR (void)
{ 
	if(INTCONbits.INT0IF==1 || INTCON3bits.INT1IF==1)
	{
		GET_ENCODER_TICKS();
	}
	if(INTCONbits.TMR0IF==1)
	{
		if(timer_counts==40)						//	Checks to see if .02 seconds passed
		{
			timer_counts=0;							//	Resets timer counts
			timer_goal=1;						//  Retrieve encoder velocity
			time_stamp+=5;
		}
		else
		{
			timer_counts+=1;
		}
		INTCONbits.TMR0IF=0;
	}

}
#pragma code InterruptVectorHigh = 0x08				//	This function simply jumps to the ISR code shown above.
void InterruptVectorHigh (void)
{
	_asm
	goto ISR //jump to interrupt routine
	_endasm
}
#pragma code

void main(void)
{
	/* Configure the PIC microcontroller */
	PIC_CONFIG();
	while(1)
	{	
		/* Check to see if it's time to get new encoder data */
		if(timer_goal==1)
		{
			GET_ENCODER_DATA();
			timer_goal=0;
		}
		//	Checks to see if the USART is ready to recieve data
		if(DataRdyUSART())
		{
			command[index]=ReadUSART();
			index+=1;
			
		}
		if(index==4)
		{
			index=0;
		}
		if(command[0]=='c')
			{
				sprintf(message,"%d %d %d \r\n",encoder_pos,encoder_current_velocity,acceleration);
				putsUSART(message);
			}
		
	}
	CloseUSART();
}

void PIC_CONFIG(void)
{
	/*	Setting	PIC to use interrupts	*/
	RCONbits.IPEN=1;					//	Enable interrupt priority
	INTCONbits.GIE=1;					//	Enable global interrupts
	
	//	Call the external interrupt configuration function
	PIC_EXT_CONFIG();
	
	//	Call the timer interrupt configuration function
	PIC_TIMER_CONFIG();
	
	//	USART Configuration
	TRISC=0x00;
	OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 10);

}


void PIC_EXT_CONFIG(void)
{
		/*	External Interrupt configuration for INT0 */
	INTCONbits.INT0IE=1;				//	Enables INT0
	INTCONbits.INT0IF=0;				//	Clears the flag
	INTCON2bits.INTEDG0=1;				//	Activates on rising edge
	
	/*	External Interrupt configuration for INT1 */
	INTCON3bits.INT1IE=1;				//	Enables INT1
	INTCON3bits.INT1IF=0;				//	Clears the flag
	INTCON2bits.INTEDG1=1;				//	Activates on rising edge
	
	//	External Interrupts final configurations
	INTCON2bits.RBPU=1;					// Disable Pull up
	TRISB=0x03;							//	Sets RB0 and RB1 as inputs
	PORTB=0x03;							// Enable high on inputs
}




void PIC_TIMER_CONFIG(void)
{
	//	Setup Timer 0 for interrupts
	INTCONbits.TMR0IE=1;
	INTCON2bits.TMR0IP=1;
	INTCONbits.TMR0IF=0;
	T0CONbits.T08BIT=1;
	T0CONbits.T0CS=0;
	T0CONbits.PSA=1;
	TMR0L=0;
	T0CONbits.TMR0ON=1;
}



void GET_ENCODER_TICKS(void)
{
	//	Checks to see if INT0 has been activated
		if(INTCONbits.INT0IF==1)
		{
		
			INTCON2bits.INTEDG0=~(INTCON2bits.INTEDG0);			//	Inverts the INTEDG0 bit
			INTCONbits.INT0IF=0;								//	Clears interrupt flag
		}
		
		//	Checks to see if INT1 has been activiated
		if(INTCON3bits.INT1IF==1)
		{
			
			INTCON2bits.INTEDG1=~(INTCON2bits.INTEDG1);				//	Inverts the INTEDG1 bit
			INTCON3bits.INT1IF=0;									//	Clears the flag
		}
		
		if(PORTBbits.RB0==1)
		{
			encoder_current_state+=1;
		}
		if(PORTBbits.RB1==1)
		{
			encoder_current_state+=2;
		}
		
		//	Checks to see if a new state has occured
		if(encoder_previous_state != encoder_current_state)
		{
			//	Checks the different states
			switch(encoder_current_state)
			{
				case 0:
					//	Checks to see if the previous state is equal to 2). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==2)
					{
						encoder_state_ticks+=1;	
					}
					else 
					{
						encoder_state_ticks-=1;
					}
					break;
				case 1:
					//	Checks to see if the previous state is equal to 0). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==0)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				case 3:
					//	Checks to see if the previous state is equal to 1). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==1)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				case 2:
					//	Checks to see if the previous state is equal to 3). If it did, then increase ticks, otherwise it'll be decreased
					if(encoder_previous_state==3)
					{
						encoder_state_ticks+=1;	
					}
					else
					{
						encoder_state_ticks-=1;
					}
					break;
				//	This will do nothing
				default:
					break;
			}
			
			//	Checks to see if the encoder ticks is greater than or equal to 4 
			if(encoder_state_ticks>=4)
			{
				encoder_ticks+=1;		//	Increase the encoder pos
				encoder_state_ticks=0;
			}
			//	Checks to see if the encoder ticks is less than or equal to -4
			if(encoder_state_ticks<=-4)
			{
				encoder_ticks-=1;		//	Decrease the encoder pos
				encoder_state_ticks=0;
			}
			
			//	Sets the current state as the new previous state.
			encoder_previous_state=encoder_current_state;
			encoder_current_state=0;
		}
}

void GET_ENCODER_DATA(void)
{
	encoder_current_velocity=(encoder_ticks-encoder_previous_ticks)*500;
	acceleration=(encoder_current_velocity-encoder_previous_velocity)*500;
	encoder_pos=encoder_ticks/2;
	encoder_previous_ticks=encoder_ticks;
	encoder_previous_velocity=encoder_current_velocity;
}
 

t06afre

Joined May 11, 2009
5,934
What have you done to debug this. As I remember you have a PICKIT 2 or 3. And both of those support in circuit debugging for your chip. You can not work with embedded systems. And at the same time be allergic to all kind of debugging
 

spinnaker

Joined Oct 29, 2009
7,830
What have you done to debug this. As I remember you have a PICKIT 2 or 3. And both of those support in circuit debugging for your chip. You can not work with embedded systems. And at the same time be allergic to all kind of debugging
What I said. :) But more concise. :)
 

Thread Starter

crazyengineer

Joined Dec 29, 2010
156
I've used the PICKit3 as my debugger. When I debugged it, it works fine reading a single character, but when I used a getsUSART command, it will not print the message.
 
Last edited:
Top