Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
Praveen Kumar
08/17/10 01:57
Modified:
  08/17/10 01:58

Read: 1132 times
Hyderabad
India


 
#178052 - Multiprocessor Communication 8052
I am using P89C52X2 controllers in our project, and the hardware is designed to support master-slave communication. There are 13 slave cards, which are identified by their addresses 0000b~1100b. The RxD's of all slaves are hardwired to TxD of master, and the TxD's are hardwired to the RxD of master.

Crystal in master is 12Mhz, and of slaves are 6Mhz.
We are using serial communication Mode 3 with variable Baud rate of 31,250.
We are using Timer 0 with 20 milliseconds interrupt.


	/* Initialize 8052 UART for multi-processor comms */
	/* Mode 3: 9-bit uart, VARIABLE 31250 baud rate */

	PCON =  0X80;	        
	SCON = 	0xD0;	  /* Setup serial port control register */	
	TH1  =  0xFE;
	SM2  =  0;
	TB8  =  1;
	REN  =  1;
	RB8  =  0;
 


Information to be sent to slaves is differentiated as Command Byte / Data Byte by making use of TB8. We tried to implement the Serial Communication procedure provided by Philips (P89C51X2/52X2/54X2/58X2 datasheet --- FULL-DUPLEX ENHANCED UART - Multiprocessor Communications topic - page 21)

After the initial detection of the active slave cards, the master card starts accessing each slave in a sequence in the main superloop, so that the addressed slave sends its data bytes to the master and the master waits till the end of data. So, data sending from slave to master is done in a sequence, once for each slave in the superloop.

Data sending from master to slave is done whenever required.

All data bytes sent / received require acknowledges reception / transmission to confirm that the data is communicated properly.



/*****************************************************************************/
//			************* MASTER CARD CODE *************
/*****************************************************************************/

#define SP_START_BIT	0xCE
#define SP_END_BIT		0xCC
#define END_OF_COMM		0xCB
#define ACKNOWLEDGE		0xCA
#define DATA_ACK		0xC8

unsigned char buf;
unsigned char end_of_comm;
unsigned char synch_flag;

bit acknowledge;
bit data_ack;
bit transmit_ready;

void SerialISR_Master(void) interrupt 4 using 3
{	/*Data Reception*/  
	if(RI)					
	{	// RI = 1, means data received from addressed slave
		buf = SBUF; // Store The Character Sent From Slave In Buffer

		if((buf ==  ACKNOWLEDGE))
		{	//If Data Received Is Acknowledge Type...
			acknowledge = 1;// Set Acknowledge Received Flag
		}
		else if(buf == DATA_ACK)//If Data Received Is 'Data Acknowledge'...
			data_ack = 1;// Set Data Acknowledged Flag

		else if((buf & 0XF0) == 0XA0)  
		{	// Cross Check The End Of Comm Signal Is Received From The Proper Slave Or Not
			end_of_comm = 0XCC;   // Set The End Of Communication Flag
		}
		else if(buf == SP_END_BIT)  
		{	//If Data Received Is Slave Portocol End Flag...	
			
			/*Process the received data operations*/

			transmit_ready = 0;		//	Block The Transmitter Ready Token
			TB8 = 0;				//	Clear Bit 8 Of Comm               
			SBUF = DATA_ACK;        //	Send The Data Acknowledge to Slave         	
        }
		else if(buf == SP_START_BIT) 
		{	//If Data Received Is Slave Protocol Start Byte	

			/*Prepare to receive the Data bytes from the next reception*/

			transmit_ready = 0;		//	Block The Transmitter Ready Token
			TB8 = 0;				//	Clear Bit 8 Of Comm               
			SBUF = DATA_ACK;        //	Send The Data Acknowledge to Slave                 
		}
	    else
		{	//If Data Bytes Are Being Received...
			
			/*Load the data bytes into the buffers*/

			transmit_ready = 0; //	Block The Transmitter Ready Token   
			TB8 = 0;			//	Clear Bit 8 Of Comm                      
			SBUF = DATA_ACK;    //  Send The Data Ack On Every Data Received 
		}	
		RI = 0;		//	Clear Ri To Wait For Next Character   
		buf = 0;	//	Clear The Received Byte Storing Buffer
	}
	/*Data Transmission*/
	else if(TI) 
	{	// TI = 1, means ready to load new character in SBUF
		TB8 = 0;// clear bit 8, for general data transmission
		TI = 0;	// clear TI flag since we are going to transmit again
		transmit_ready = 1;	// release the transmitter ready token after transmission completed
	}
}

bit enableSlaveToTx(unsigned char sid)
{
	transmit_ready = 0;		// take transmitter ready token in order to transmit
	acknowledge    = 0;
	TB8 = 1;				// set bit 8, for address transmission
	SBUF = sid;				/* General Broadcast address - all slaves receive this */
	synch_flag = 75;		// Load The Synchronisation Flag Count, which counts down in TISR every 20 ms
	while( (!acknowledge) && synch_flag){;}
	if(!acknowledge)
	{	
		return 0;
	}
	acknowledge = 0;     // If It Responds Go Further
 	return 1;
}	

void getDataFromSlaves(void)
{
	unsigned char slave_card_id;

	for(slave_card_id=0;slave_card_id<13;slave_card_id++)
	{
		if(end_of_comm == 0X55)						
		{	// If Comm Port Is Free...
			end_of_comm = 0XAA;//MAKE IT BUSY
			if(enableSlaveToTx(slave_card_id))
			{	// If The Addressed Slave Is Enabled For Transmitting Mode...
				synch_flag = 75;	// Load The Synchronisation Flag Count, which counts down in TISR every 20 ms
				while( (end_of_comm == 0XAA) && synch_flag){;}
				// Wait Until The Slave Transmits The Total Data Or Synch Count Comes To Zero thro Timer 0 ISR
				if(end_of_comm == 0XAA)			
				{	// If The Slave Card Lost The Communication

					/*Error Log storing code goes here*/
				}
				end_of_comm = 0x55;// Make Comm Port Free...
			}
			else									
			{	// If The Addressed Slave Does Not Respond At All...
				/*We give 5 turns for the slave to respond. If it fails, we
				  store the Error Log and send reset signal to restart the system.
				  else,
				*/
				end_of_comm = 0x55;// Make Comm Port Free...
			}
		}
	}
}
void main(void)
{

	/*Initialisations go here*/
	while(1)
	{
		getDataFromSlaves();
		/*Remaining code goes here*/
	}
}

/*****************************************************************************/
//			************* SLAVE CARD CODE *************
/*****************************************************************************/

#define MP_START_BIT      		0XCF 
#define MP_END_BIT       		0xCD
#define ACKNOWLEDGE		   		0xCA
#define DATA_ACK           		0xC8
#define RESET_SLAVE_SIGN		0XC7

unsigned char code END_OF_COMM_ARR[13]=/*Used for identifying unique End Of Comms at Master End*/
		{0XA0,0XA1,0XA2,0XA3,0XA4,0XA5,0XA6,0XA7,0XA8,0XA9,0XAA,0XAB};

bit restart;
bit give_ack;
bit give_data_ack;
bit transmit_enable;
bit trans_r;
bit restart;

unsigned char hardware_id;/*0000 ~ 1100 */
unsigned char rec_data;

void send_data(unsigned char i) 
{
	trans_r = 1;
	SBUF = i;                      // SEND THE DATA TO THE MASTER 
	while(trans_r);	
}

void sendProtocolToMaster(void)
{
	/*
	Data bytes sending code goes here.
	Each byte requires acknowledge from master (DATA_ACK)
	*/
	send_data(END_OF_COMM_ARR[hardware_id]);
	transmit_enable = 0; 
	SM2 = 1;             
}

void main (void)
{
	/*Initialisation code here*/
	/*Card hardware ID generation code here*/

	if(!SM2)                     //CHECKING WHETHER THE SLAVE IS PERMITED TO SEND THE DATA OR NOT
	{
		if(give_ack)               //IF THERE IS A REQUEST FOR ACK  
		{
			give_ack = 0;           //CLEAR THE REQUEST 
			send_data(ACKNOWLEDGE);
		}
		if(give_data_ack)               //IF THERE IS A REQUEST FOR ACK  
		{
			give_data_ack = 0;           //CLEAR THE REQUEST 
			send_data(DATA_ACK);
		}
		if(transmit_enable)
			sendProtocolToMaster();//IF THE SLAVE IS ENABLED IN TRANSMITING MODE SEND ALL PROTOCOLS PENDING TO THE MASTER
	}	
	if(restart)
	{
		EA = 0;
		((void(code*)(void))0x0000)();//Go to location 00 of code
	}
}

void SerialISR_Slave(void) interrupt 4 using 3	
{					
	// RECEIVER SECTION
	if(RI)					
	{	// if a character is received				
		rec_data = SBUF;// read data character sent from master and store it in rec buf
		if(RB8)	// if received general broadcast address,
		{	// Global Message Reception	
			if(hardware_id == rec_data) 		
			{	// if received correct address,
				transmit_enable = 1;
				SM2 = 0;	// prepare to read data
				give_ack = 1; // SEND ACK SIGNAL TO MASTER
			}
			else 
				SM2 = 1;// reset serial port for address reception mode			
			// This message is not acknowledged back to the Master
			// since all the slaves would be replying it at the same time
			// and the data would therefore be corrupted.
		    else if(rec_data == RESET_SLAVE_SIGN)/*To restart the slave*/
				restart = 1;

			else
			{// if the addressed slave is not this...
			    SM2 = 1;		// reset serial port for address reception mode
			}
			RB8 = 0;
		}
		else if(!SM2) // IF SLAVE IS IN RECEIVING MODE
		{	//Private Message data Reception
			if(rec_data == DATA_ACK)//If Data Received Is 'Data Acknowledge'...
				data_ack = 1;// Set Data Acknowledged Flag

			else if(rec_data == MP_END_BIT)  
			{	//If Data Received Is Slave Portocol End Flag...	
				
				/*Process the received data operations*/

				give_data_ack = 1;       	
			}
			else if(rec_data == MP_START_BIT) 
			{	//If Data Received Is Slave Protocol Start Byte	

				/*Prepare to receive the Data bytes from the next reception*/

				give_data_ack = 1;            
			}
			else
			{	//If Data Bytes Are Being Received...
				
				/*Load the data bytes into the buffers*/

				give_data_ack = 1;
			}	
		}		
		RI = 0;
		rec_data = 0;
	}
	// TRANSMITTER SECTION
	if(TI)					
	{				// TI = 1, means ready to load new character in SBUF					
		TI = 0;		// clear TI flag since we are goling to transmit again
		trans_r =0;
	}
}


 


Q1: Is it a better way to use 31250 baud for serial communication?

While the system is running, once in a while, one of the slaves is not responding when it is being addressed. We are trying to trace it with the help of error log at the instance of card response failure. Once this happens, we are sending reset command to restart the whole system, as the system is not running properly, it happens 2-3 times in 24 hrs.

Q2: What issues affect a slave from not responding to command Byte? what needs to be done to refresh the communication?

Q3. Are we using the correct way to communicate in Master Slave Application (as described in Philips datasheet) or better options are available to implement?




List of 46 messages in thread
TopicAuthorDate
Multiprocessor Communication 8052      Praveen Kumar      08/17/10 01:57      
   missing info      Erik Malund      08/17/10 06:25      
      Hardware and slaves placement      Praveen Kumar      08/17/10 23:38      
         How to TriState???      Michael Karas      08/18/10 01:58      
            Using Tristate IC in Slave Card      Praveen Kumar      08/19/10 00:16      
               at the receive ...      Erik Malund      08/19/10 06:57      
               RE: I think that this IC handles the Tristate situation      Andy Neil      08/19/10 07:06      
               then you need to read      Erik Malund      08/19/10 07:32      
                  At the Master end      Praveen Kumar      08/20/10 00:50      
                     again, you need a schmitt      Erik Malund      08/20/10 05:23      
                        Hysterese      Per Westermark      08/20/10 06:13      
                        Re: Thanks...Info about hardware we are using      Praveen Kumar      08/20/10 08:25      
                           how do you know?      Erik Malund      08/20/10 09:03      
                              Lowering baud rate      Praveen Kumar      08/21/10 01:00      
                           Really      Neil Kurzman      08/20/10 17:55      
                              Modified the code in Master and Slave      Praveen Kumar      08/21/10 01:12      
                                 Haven't seen full code - slave protocol state fully cleared?      Per Westermark      08/21/10 02:21      
                                    Slave protocol code      Praveen Kumar      08/21/10 03:23      
                                       Slave send code fails to synchronize      Per Westermark      08/21/10 03:46      
                                          breaking infinite waits in slave acknowledge wait      Praveen Kumar      08/21/10 05:17      
                                       Stop fooling yourself        Per Westermark      08/21/10 06:31      
                                          why didn't you before posting updated code      Erik Malund      08/21/10 08:47      
                                          How to reset?      Praveen Kumar      08/22/10 23:54      
                                             Hard reset by doing a hard reset.      Per Westermark      08/23/10 00:08      
                                          Errors gone      Praveen Kumar      08/26/10 01:00      
                                             But slave still doesn't synchronize with a resend request      Per Westermark      08/26/10 05:57      
                                                that is not the way to do it      Erik Malund      08/26/10 06:27      
                                                   too late for an edit      Erik Malund      08/26/10 14:16      
      Reduced Baud Rate      Praveen Kumar      08/18/10 06:25      
         not surprised      Erik Malund      08/18/10 06:31      
            Never reboot for a transfer error        Per Westermark      08/18/10 07:28      
               never be an afterthought        Erik Malund      08/18/10 08:06      
                  Transfer validation before implementing command processing      Per Westermark      08/18/10 10:08      
                     a trick      Erik Malund      08/18/10 10:16      
                        address coding example required      Praveen Kumar      08/19/10 00:27      
                           example      Erik Malund      08/19/10 06:55      
                        Added "No message" byte      Praveen Kumar      08/19/10 08:18      
                  never be an afterthought: Amen      Kalpak Dabir      08/19/10 00:15      
               Slave Recovery in Error      Praveen Kumar      08/19/10 00:36      
                  Find out Why        Michael Karas      08/19/10 01:59      
                     absolutely      Erik Malund      08/19/10 09:06      
                        worse in the real world      Andy Neil      08/19/10 09:46      
                  in addition: rise baudrate      Stefan KAnev      08/19/10 07:27      
               Slaves follow Synchronization      Praveen Kumar      08/20/10 00:56      
   + Error Checking?        Marty McLeod      08/17/10 16:21      
      It would be smart to assume that a percentage of messages...      Andy Neil      08/18/10 02:58      

Back to Subject List