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

Back to Subject List

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

Read: times


 
#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            01/01/70 00:00      
   missing info            01/01/70 00:00      
      Hardware and slaves placement            01/01/70 00:00      
         How to TriState???            01/01/70 00:00      
            Using Tristate IC in Slave Card            01/01/70 00:00      
               at the receive ...            01/01/70 00:00      
               RE: I think that this IC handles the Tristate situation            01/01/70 00:00      
               then you need to read            01/01/70 00:00      
                  At the Master end            01/01/70 00:00      
                     again, you need a schmitt            01/01/70 00:00      
                        Hysterese            01/01/70 00:00      
                        Re: Thanks...Info about hardware we are using            01/01/70 00:00      
                           how do you know?            01/01/70 00:00      
                              Lowering baud rate            01/01/70 00:00      
                           Really            01/01/70 00:00      
                              Modified the code in Master and Slave            01/01/70 00:00      
                                 Haven't seen full code - slave protocol state fully cleared?            01/01/70 00:00      
                                    Slave protocol code            01/01/70 00:00      
                                       Slave send code fails to synchronize            01/01/70 00:00      
                                          breaking infinite waits in slave acknowledge wait            01/01/70 00:00      
                                       Stop fooling yourself            01/01/70 00:00      
                                          why didn't you before posting updated code            01/01/70 00:00      
                                          How to reset?            01/01/70 00:00      
                                             Hard reset by doing a hard reset.            01/01/70 00:00      
                                          Errors gone            01/01/70 00:00      
                                             But slave still doesn't synchronize with a resend request            01/01/70 00:00      
                                                that is not the way to do it            01/01/70 00:00      
                                                   too late for an edit            01/01/70 00:00      
      Reduced Baud Rate            01/01/70 00:00      
         not surprised            01/01/70 00:00      
            Never reboot for a transfer error            01/01/70 00:00      
               never be an afterthought            01/01/70 00:00      
                  Transfer validation before implementing command processing            01/01/70 00:00      
                     a trick            01/01/70 00:00      
                        address coding example required            01/01/70 00:00      
                           example            01/01/70 00:00      
                        Added "No message" byte            01/01/70 00:00      
                  never be an afterthought: Amen            01/01/70 00:00      
               Slave Recovery in Error            01/01/70 00:00      
                  Find out Why            01/01/70 00:00      
                     absolutely            01/01/70 00:00      
                        worse in the real world            01/01/70 00:00      
                  in addition: rise baudrate            01/01/70 00:00      
               Slaves follow Synchronization            01/01/70 00:00      
   + Error Checking?            01/01/70 00:00      
      It would be smart to assume that a percentage of messages...            01/01/70 00:00      

Back to Subject List