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.

communicating between microcontrollers using usart

Status
Not open for further replies.

shaneelal

Member level 1
Joined
Nov 16, 2004
Messages
38
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
553
openusart

Hi,I'm using two PIC 18F452 microcontrollers in two devices that I'm building. One microcontroller has to transmit a reading to the second microcontroller. I'm using USART implementing rs-232. The first device transmits well,I checked the output using the hyperterminal of the pc.
I can't read the string that I sent to the second microcontroller. The second PIC just keeps waiting and waiting for data to be recieved.
I'm using the mcc18 compiler. Is it all possible to communicate between PICs using the USART in asynchronous mode?
these are excerpts from my code


configuration of usart of the device transmitting
Code:
OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF &
           USART_ASYNCH_MODE & USART_EIGHT_BIT &
	USART_BRGH_HIGH &
           USART_CONT_RX,25);

code that transmits:
Code:
speed=(distance/ReadTimer0());

	ultoa(speed,str); 
	while(BusyXLCD());
	SetDDRamAddr(0x14);
	while(BusyXLCD());
	putsXLCD(clear);	
	while(BusyXLCD());
	SetDDRamAddr(0x14);
	while(BusyXLCD());
	putsXLCD(str);
	while(BusyXLCD());
	SetDDRamAddr(0x1C);
	while(BusyXLCD());
	putsXLCD(units);

	while (BusyUSART());
	putsUSART(str); //string located in data memory
	while (BusyUSART());

str is declared as
Code:
char str[7];

The transmitter works.



configuration of usart of the receiving device:
Code:
OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF &
           USART_ASYNCH_MODE & USART_EIGHT_BIT &
		   USART_BRGH_HIGH &
           USART_CONT_RX,25);

code to recieve(on the other PIC)
Code:
	SetChanADC(ADC_CH0); //select voltage channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	voltage_adc=ReadADC();
	voltage = (voltage_adc * convFactor  *100.0);
	SetChanADC( ADC_CH1 );//select current channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	current_adc=ReadADC();
	current = (current_adc *1.2* convFactor  *600.0);
	while(!DataRdyUSART());
	getsUSART(speed , 7);//obtain speed
	while (BusyUSART());


speed is declared as:
Code:
char speed[7];
 

usart_cont_rx

Try using an interrupt based routine to see if the interrupt is firing. You haven't even listed the code for your most important routine, the USART ones.
 

openusart

I got it to work. I will show both sets of my working code. I still need help with something.

code of the transmitting device
Code:
#include <p18f452.h>
#include <timers.h>
#include <xlcd.h>
#include <delays.h>
#include <stdlib.h>
#include <usart.h>
#include <string.h>


/* Set configuration bits for use with ICD2 / PICDEM2 PLUS Demo Board:
* - set XT oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_XT_1H,
_CONFIG2L_DEFAULT,
_CONFIG2H_DEFAULT & _WDT_OFF_2H,
_CONFIG3H_DEFAULT,
_CONFIG4L_DEFAULT & _LVP_OFF_4L,
_CONFIG5L_DEFAULT,
_CONFIG5H_DEFAULT,
_CONFIG6L_DEFAULT,
_CONFIG6H_DEFAULT,
_CONFIG7L_DEFAULT,
_CONFIG7H_DEFAULT);
#pragma romdata

void DelayFor18TCY( void )
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}

void DelayPORXLCD( void )
{
Delay1KTCYx(60); //Delay of 15ms
	return;
}

void DelayXLCD( void )
{
	Delay1KTCYx(20); //Delay of 5ms 
	return;
}

void main( void )
{	
	unsigned int time100;
    unsigned int count;
	unsigned int distance= 110;
	unsigned int speed;
	char str[8];
	char units[10] = "mm persec";
	char clear[20] = "                   ";
	int  lenght = 0;
	int  cnt = 0;

                                                                                                             
// configure external LCD
	OpenXLCD( FOUR_BIT & LINES_5X7 );//four bit mode,multiple line display 




	// configure timer0,used for timing
	OpenTimer0( TIMER_INT_OFF & //interrupt off
			T0_16BIT &      //16bit mode
            T0_SOURCE_INT & //internal clock source
            T0_PS_1_256 );  //1:256 prescale

	// configure timer1,used for counting pulses
	OpenTimer1( TIMER_INT_OFF & //interrupt off
			T1_16BIT_RW &   //16 bit mode
			T1_SOURCE_EXT & //external clock source,that is the input pulses
			T1_PS_1_1 &     //1:1 prescale
			T1_OSC1EN_OFF & //disable Timer1 oscillator
			T1_SYNC_EXT_OFF);
	speed = 0;
	while (1)
	{
		
		time100=0;
		count=0;

	
		WriteTimer1(0);	//restart timer1
		WriteTimer0(0);	//restart timer0

		while(ReadTimer1()<100)
			{
			
			}
		speed = ReadTimer0();
	
		speed = distance / (speed/ 65536.0 * 16.777);


		ultoa(speed,str); //convert speed to string (usart can only accept string)
					//convert a 16-bit signed integer to a string
		lenght = strlen(str);
		for(cnt = lenght; cnt < 7; ++cnt)
		{
			str[cnt] = ' ';
		}
		str[7] = '\0';
		while(BusyXLCD());
		SetDDRamAddr(0x14);
		while(BusyXLCD());
		putsXLCD(clear);	
		while(BusyXLCD());
		SetDDRamAddr(0x14);
		while(BusyXLCD());
		putsXLCD(str);
		while(BusyXLCD());
		SetDDRamAddr(0x1C);
		while(BusyXLCD());
		putsXLCD(units);

		OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF &
	           USART_ASYNCH_MODE & USART_EIGHT_BIT &
			   USART_BRGH_HIGH &
	           USART_CONT_RX,25);
		while (BusyUSART());
		
		putsUSART(str); //string located in data memory
		CloseUSART();
	
	
	}

}



Code for recieving device

Code:
#include <p18f452.h>
#include <xlcd.h>
#include <delays.h>
#include <stdlib.h>
#include <usart.h>
#include <portb.h>
#include <adc.h>
#include <string.h>
#include <timers.h>


/* Set configuration bits for use with ICD2 / PICDEM2 PLUS Demo Board:
* - set XT oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_XT_1H,
_CONFIG2L_DEFAULT,
_CONFIG2H_DEFAULT & _WDT_OFF_2H,
_CONFIG3H_DEFAULT,
_CONFIG4L_DEFAULT & _LVP_OFF_4L,
_CONFIG5L_DEFAULT,
_CONFIG5H_DEFAULT,
_CONFIG6L_DEFAULT,
_CONFIG6H_DEFAULT,
_CONFIG7L_DEFAULT,
_CONFIG7H_DEFAULT);
#pragma romdata



void DelayFor18TCY( void )
{
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
}

void DelayPORXLCD( void )
{
	Delay1KTCYx(60); //Delay of 15ms
	return;
}

void DelayXLCD( void )
{
	Delay1KTCYx(20); //Delay of 5ms
	return;
}

rom char sp_units[10] = "mm persec"; //The rom qualifier denotes that the object is
									//located in program memory
rom char vol_units[10] = "Volts"; 
rom	char cur_units[10] = "Amps";
rom	char welcome[20] = "Welding Monitor";
rom	char cursorL1[5] = "{A17" ;
rom	char cursorL2[7] = "{C0202"	;
rom	char cursorL5[7] = "{C0204";
rom	char cursorL7[7] = "{C0206";
rom	char cursorL9[9] = "{C0209";
rom	double convFactor = 1024.00;
rom char clear[20] = "                  ";



void main(void)
{


	int current_adc;
	int voltage_adc;
    	int voltage;
	int current;
	char speed[8];
	char voltage_str[7];
	char current_str[7];
	int curret_fs = 600.0;
	int voltage_fs = 100.0;
	
                                                                                                              
// configure external LCD
OpenXLCD( FOUR_BIT & LINES_5X7 );//four bit mode,multiple line display 
	while(BusyXLCD());
	WriteCmdXLCD(DOFF);
	while(BusyXLCD());
	WriteCmdXLCD(DON);
	while(BusyXLCD());
	WriteCmdXLCD(BLINK_OFF);
	while(BusyXLCD());
	WriteCmdXLCD(CURSOR_OFF);



OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST &
		ADC_8ANA_0REF,ADC_CH0 & 
		ADC_INT_OFF);


OpenTimer0( TIMER_INT_ON & //interrupt on
			T0_16BIT &      //16bit mode
            T0_SOURCE_INT & //internal clock source
            T0_PS_1_32 );  //1:32 prescale







	//PIR1bits.RCIF=0;
	//INTCONbits.GIE=1;
	//INTCONbits.PEIE=1;
	INTCONbits.GIE = 1;//do I have to put,yes from pg58
	while (1)
	{
		while (1)
		{
		if (INTCONbits.TMR0IF == 1)
			break;
			
		}

	SetChanADC(ADC_CH0); //select voltage channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	voltage_adc=ReadADC();
	voltage = ((voltage_adc /convFactor)  * voltage_fs);
	ultoa(voltage,voltage_str);
	SetChanADC( ADC_CH1 );//select current channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	current_adc=ReadADC();
	current = ((current_adc/convFactor) *1.2 *curret_fs);
	ultoa(current,current_str);
	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON&
           	  USART_ASYNCH_MODE & USART_EIGHT_BIT &
		    USART_BRGH_HIGH & USART_CONT_RX,25);
	while (BusyUSART());
		getsUSART(speed , 7);//obtain speed	
		CloseUSART();
		speed[7] = '\0';



/***************write to LCD*******************/
	
	while(BusyXLCD());
	SetDDRamAddr(0x00);
	putrsXLCD( clear );
	while(BusyXLCD());
	SetDDRamAddr(0x40);
	putrsXLCD( clear );			
	while(BusyXLCD());
	SetDDRamAddr(0x10);
	putrsXLCD( clear );
	while(BusyXLCD());
	SetDDRamAddr(0x1C);
	while(BusyXLCD());
	putrsXLCD( sp_units );
	while(BusyXLCD());
	SetDDRamAddr(0x14);
	while(BusyXLCD());
	putsXLCD(speed);
	while(BusyXLCD());
	SetDDRamAddr(0x48);
	while(BusyXLCD());
	putrsXLCD( cur_units );
	while(BusyXLCD());
	SetDDRamAddr(0x40);
	while(BusyXLCD());
	putsXLCD(current_str);
	while(BusyXLCD());
	SetDDRamAddr(0x08);
	while(BusyXLCD());
	putrsXLCD( vol_units );
	while(BusyXLCD());
	SetDDRamAddr(0x00);
	while(BusyXLCD());
	putsXLCD(voltage_str);
	while ( BusyXLCD() );
	WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
		//CloseUSART();
/************write to tv screen*************************/
	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF &
           USART_ASYNCH_MODE & USART_EIGHT_BIT &
		   USART_BRGH_HIGH & USART_CONT_RX,25);
	while (BusyUSART());
	putrsUSART(cursorL1 ); //clear screen
	while (BusyUSART());
	putrsUSART( cursorL2 );
	while (BusyUSART());
	putrsUSART( welcome );
	while (BusyUSART());
	putrsUSART( cursorL5 );
	while (BusyUSART());
	putsUSART( speed );
	while (BusyUSART());
	putrsUSART( sp_units );
	putrsUSART( cursorL7 );
	while (BusyUSART());
	putsUSART( current_str );
	while (BusyUSART());
	putrsUSART( cur_units );
	while (BusyUSART());
	putrsUSART( cursorL9 );
	while (BusyUSART());
	putsUSART( voltage_str );
	while (BusyUSART());
	putrsUSART( vol_units );
	while (BusyUSART());
	CloseUSART();
	INTCONbits.TMR0IF = 0;
	}
}

The above code works well. I'm building two deivces. One transmits a 'wirespeed' after a shaft encoder makes one revolution(100pulses). As soon as speed is determined it is transmitted. Another device determines current and voltage every 2 seconds,it used the overflow of timer0. The above code waits for the wirespeed to be transmitted before it goes on to other code. I was thinking of using interrupts on recieve,I was having some trouble with that.
Below is the code I wrote to obtain the interrupt once recieved and also obtain the wirespeed. Please help me correct it.

Code:
#include <p18f452.h>
#include <xlcd.h>
#include <delays.h>
#include <stdlib.h>
#include <usart.h>
#include <portb.h>
#include <adc.h>
#include <string.h>
#include <timers.h>


/* Set configuration bits for use with ICD2 / PICDEM2 PLUS Demo Board:
* - set XT oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_XT_1H,
_CONFIG2L_DEFAULT,
_CONFIG2H_DEFAULT & _WDT_OFF_2H,
_CONFIG3H_DEFAULT,
_CONFIG4L_DEFAULT & _LVP_OFF_4L,
_CONFIG5L_DEFAULT,
_CONFIG5H_DEFAULT,
_CONFIG6L_DEFAULT,
_CONFIG6H_DEFAULT,
_CONFIG7L_DEFAULT,
_CONFIG7H_DEFAULT);
#pragma romdata



void DelayFor18TCY( void )
{
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
	Nop();
}

void DelayPORXLCD( void )
{
	Delay1KTCYx(60); //Delay of 15ms
	return;
}

void DelayXLCD( void )
{
	Delay1KTCYx(20); //Delay of 5ms
	return;
}
volatile char speed[8];
rom char sp_units[10] = "mm persec"; //The rom qualifier denotes that the object is
									//located in program memory
rom char vol_units[10] = "Volts"; 
rom	char cur_units[10] = "Amps";
rom	char welcome[20] = "Welding Monitor";
rom	char cursorL1[5] = "{A17" ;
rom	char cursorL2[7] = "{C0202"	;
rom	char cursorL5[7] = "{C0204";
rom	char cursorL7[7] = "{C0206";
rom	char cursorL9[9] = "{C0209";
rom	double convFactor = 1024.00;
rom char clear[20] = "                  ";



void getspeed();
void main(void)
{


	int current_adc;
	int voltage_adc;
    	int voltage;
	int current;
	char voltage_str[7];
	char current_str[7];
	int curret_fs = 600.0;
	int voltage_fs = 100.0;
	
                                                                                                               
// configure external LCD
OpenXLCD( FOUR_BIT & LINES_5X7 );//four bit mode,multiple line display 
	while(BusyXLCD());
	WriteCmdXLCD(DOFF);
	while(BusyXLCD());
	WriteCmdXLCD(DON);
	while(BusyXLCD());
	WriteCmdXLCD(BLINK_OFF);
	while(BusyXLCD());
	WriteCmdXLCD(CURSOR_OFF);



OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST &
		ADC_8ANA_0REF,ADC_CH0 & 
		ADC_INT_OFF);

OpenTimer0( TIMER_INT_ON & //interrupt on
			T0_16BIT &      //16bit mode
            T0_SOURCE_INT & //internal clock source
            T0_PS_1_32 );  //1:32 prescale







	PIR1bits.RCIF=0;
	INTCONbits.GIE=1;
	//INTCONbits.PEIE=1;
	INTCONbits.GIE = 1;//do I have to put,yes from pg58
	while (1)
	{
		while (1)
		{
		if (INTCONbits.TMR0IF == 1)
			break;
	
		}


	SetChanADC(ADC_CH0); //select voltage channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	voltage_adc=ReadADC();
	voltage = ((voltage_adc /convFactor)  * voltage_fs);
	ultoa(voltage,voltage_str);
	SetChanADC( ADC_CH1 );//select current channel
	Delay10TCYx(3);
	ConvertADC();
	while( BusyADC());
	current_adc=ReadADC();
	current = ((current_adc/convFactor) *1.2 *curret_fs);
	ultoa(current,current_str);

	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON &
           USART_ASYNCH_MODE & USART_EIGHT_BIT &
		   USART_BRGH_HIGH &
           USART_CONT_RX,25);
	Delay10TCYx(3);
	Delay10TCYx(3);

/***************write to LCD*******************/
	
	while(BusyXLCD());
	SetDDRamAddr(0x00);
	putrsXLCD( clear );
	while(BusyXLCD());
	SetDDRamAddr(0x40);
	putrsXLCD( clear );			
	while(BusyXLCD());
	SetDDRamAddr(0x10);
	putrsXLCD( clear );
	while(BusyXLCD());
	SetDDRamAddr(0x1C);
	while(BusyXLCD());
	putrsXLCD( sp_units );
	while(BusyXLCD());
	SetDDRamAddr(0x14);
	while(BusyXLCD());
	putsXLCD(speed);
	while(BusyXLCD());
	SetDDRamAddr(0x48);
	while(BusyXLCD());
	putrsXLCD( cur_units );
	while(BusyXLCD());
	SetDDRamAddr(0x40);
	while(BusyXLCD());
	putsXLCD(current_str);
	while(BusyXLCD());
	SetDDRamAddr(0x08);
	while(BusyXLCD());
	putrsXLCD( vol_units );
	while(BusyXLCD());
	SetDDRamAddr(0x00);
	while(BusyXLCD());
	putsXLCD(voltage_str);
	while ( BusyXLCD() );
	WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
		//CloseUSART();
/************write to tv screen*************************/
	OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF &
           USART_ASYNCH_MODE & USART_EIGHT_BIT &
		   USART_BRGH_HIGH &
           USART_CONT_RX,25);
	while (BusyUSART());
	putrsUSART(cursorL1 ); //clear screen
	while (BusyUSART());
	putrsUSART( cursorL2 );
	while (BusyUSART());
	putrsUSART( welcome );
	while (BusyUSART());
	putrsUSART( cursorL5 );
	while (BusyUSART());
	putsUSART( speed );
	while (BusyUSART());
	putrsUSART( sp_units );
	putrsUSART( cursorL7 );
	while (BusyUSART());
	putsUSART( current_str );
	while (BusyUSART());
	putrsUSART( cur_units );
	while (BusyUSART());
	putrsUSART( cursorL9 );
	while (BusyUSART());
	putsUSART( voltage_str );
	while (BusyUSART());
	putrsUSART( vol_units );
	while (BusyUSART());
	CloseUSART();
	INTCONbits.TMR0IF = 0;
	}
}


 #pragma code high_vector=0x08
 static void prvLowInterrupt( void )
 {

	if(PIR1bits.RCIF==1)
	{		
		_asm
			goto getspeed
		_endasm
	}

 }
 #pragma code

 #pragma interrupt getspeed
 void getspeed()
 {
	while (BusyUSART());
		getsUSART(speed , 7);//obtain speed
	CloseUSART();
	speed[7] = '\0';
	PIR1bits.RCIF=0;
  }
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top