??? 08/27/11 12:00 Read: times |
#183501 - Multiprocessor Communication 8052 |
Hi
we are using Philips P89C52X2 in our project with 1 master controller and 12 slave controllers. Information to be sent to slaves is differentiated as Command Byte / Data Byte by making use of TB8. We implemented the Multiprocessor Communication procedure provided by Philips (P89C51X2/52X2/54X2/58X2 datasheet --- FULL-DUPLEX ENHANCED UART - Multiprocessor Communications topic - page 21) The operations of the code are: Serial Communication Mode 3 with variable baud rate = 7812, XTAL = 12 Mhz. All slaves are recognized by their unique 4-bit hardware ID(0x00 ~ 0x0B), calculated as per the physical placement of the slave in the hardware slot. The TxD pins of the slaves are hardwired to the RxD pin of master, and RxD pins of the slaves are hardwired to the TxD pin of master. As the no. of slave cards increases, the speed of operations decreases. At system startup, the master starts addressing each slave by its hardware ID, and treats that the slave is present if it responds back / acknowledges. The master can send data bytes to a slave instantaneously. When the master wants to send a data protocol to a particular slave, it first addresses the slave, and if it responds back, it sends the protocol in the following pattern: Master Protocol Start Byte -> Protocol Type Identification Byte -> Data Byte -> . . . . . -> Data Byte -> Master Protocol End Byte. The master gets data from slaves by addressing each slave in the superloop in a round robin sequence. The addressed slave will be prepared for re-transmitting pending data bytes (if any) to the master, followed by End Of Comm Byte. The master waits for this byte before proceeding to next slave. Infinite waiting loops are broken using countdown flags in communication failure cases. The addressed slave sends the protocol in the following pattern: Slave Protocol Start Byte -> Protocol Type Identification Byte -> Data Byte -> . . . . . -> Data Byte -> Slave Protocol End Byte. All data bytes sent / received require self acknowledges to confirm that the data byte is communicated properly. Master Card code: /*****************************************************************************/ // ************* MASTER CARD CODE ************* /*****************************************************************************/ #define MP_START_BIT 0XCF /* Master Protocol Start */ #define SP_START_BIT 0xCE /* Slave Protocol Start */ #define MP_END_BIT 0xCD /* Master Protocol End */ #define SP_END_BIT 0xCC /* Slave Protocol End */ #define ACKNOWLEDGE 0xCA /* Acknowledge From Slave Card */ #define DATA_ACK 0xC8 /* Data Acknowledge */ #define MAX_TASKS 96 unsigned char buf; /* Data Received Buffer */ unsigned char end_of_comm; unsigned char synch_flag; /* Infinite Loops Breaking Countdown Variable, Decrememted In TISR */ unsigned char slave_card_id; bit acknowledge; /* Acknowledge To Master Flag */ bit give_data_ack; /* Data Acknowledge To Master Flag */ bit data_ack; /* Data Acknowledge To Slave Flag */ bit transmit_ready; /* Transmitter Ready Flag */ void SerialISR_Master(void) interrupt 4 using 3 { /* Data Reception */ if(RI) { /* If A Character Is Received */ buf = SBUF; /* Store The Character Sent From Slave In Buffer */ if((buf == ACKNOWLEDGE)) { /* If Data Received Is Acknowledge */ 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 Whether The End Of Comm Byte Is Received From The Proper Slave Or Not */ end_of_comm = 0XCC; /* Set The End Of Comm Byte Received Flag */ } else if(buf == SP_END_BIT) { /* If Data Received Is Slave Portocol End Byte */ /* Process The Received Data Operations */ } else if(buf == SP_START_BIT) { /* If Data Received Is Slave Protocol Start Byte */ /* Prepare To Receive The Data Bytes From The Next Reception */ } else { /* If Data Bytes Are Being Received...*/ /* Load The Data Bytes Into The Buffers */ } transmit_ready = 0; /* Block The Transmitter Ready Flag */ TB8 = 0; /* Clear Bit 8 Of Comm */ SBUF = DATA_ACK; /* Send The Data Acknowledge to Slave */ RI = 0; /* Clear RI To Wait For Next Character */ buf = 0; /* Clear The Received Byte Storing Buffer */ } /*Data Transmission*/ else if(TI) { TB8 = 0;/* Clear Bit 8 For General Data Transmission */ TI = 0; transmit_ready = 1; /* Release The Transmitter Ready Token After Transmission Completed */ } } void getDataFromSlaves(void) { slave_card_id++; if(end_of_comm == 0X55) { // If Comm Port Is Free... end_of_comm = 0XAA;//MAKE IT BUSY /* Address A Slave By Sending (slave_card_id | 0x20) As A General Command. If The Addressed Slave Responded For Re-Transmitting Its Data Bytes...*/ 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 Pending Data Or Synch Count Comes To Zero thro Timer 0 ISR */ if(end_of_comm == 0XAA) { /* If The Slave Card Lost The Communication, store the Error Log and send reset signal to restart the system */ } end_of_comm = 0x55;// Make Comm Port Free... } } void main(void) { unsigned char i; /* Initialisations Go Here */ while(1) { for(i=0; i<MAX_TASKS ; i++) { // ITERATIONS FOR ALL TASKS if(i%8 == 0) { // FOR EVERY 8 SERVES getDataFromSlaves(); } } /* Remaining Code Goes Here */ } } Slave Card Code: /*****************************************************************************/ // ************* SLAVE CARD CODE ************* /*****************************************************************************/ #define MP_START_BIT 0XCF /* Master Protocol Start */ #define SP_START_BIT 0xCE /* Slave Protocol Start */ #define MP_END_BIT 0xCD /* Master Protocol End */ #define SP_END_BIT 0xCC /* Slave Protocol End */ #define ACKNOWLEDGE 0xCA /* Acknowledge From Slave Card */ #define DATA_ACK 0xC8 /* Data Acknowledge */ #define OH_START_BIT 0xB1 /* Onhook / Offhook On Extensions */ unsigned char code END_OF_COMM_ARR[12]=/*Used for identifying unique End Of Comms at Master End*/ {0XA0,0XA1,0XA2,0XA3,0XA4,0XA5,0XA6,0XA7,0XA8,0XA9,0XAA,0XAB}; bit give_ack; /* Send Acknowledge To Master */ bit give_data_ack; /* Send Data Acknowledge To Master */ bit transmit_enable;/* Slave Is Data Receiver Or Re-Transmitter */ bit trans_r; /* Transmitter Ready Flag */ bit data_ack; /* Data Acknowledge Received Flag */ bit data_ready; /* Data Ready To Be Sent To Master Flag */ unsigned char hardware_id; /* 0x00 ~ 0x0B */ unsigned char rec_data; /* Data Received Buffer */ unsigned char off_hook; /* Status Buffer */ 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( ( (rec_data & 0xf0) == 0x20) || ( (rec_data & 0xf0) == 0x10) ) { // IF THE MODE IS RECEIVER / RE-TRANSMITTER if(hardware_id == (rec_data & 0x0F)) { /* If Received Correct Address */ transmit_enable = (rec_data & 0x20); //UPDATE THE RECEIVER / RE-TRANSMITTER FLAG SM2 = 0;/* Prepare To Receive The Data Bytes That Will Be Coming */ give_ack = 1; /* Send Ack Signal To Master */ } else {SM2 = 1;}/* Make This Slave As Not Being Addressed */ } else { /* If The Addressed Slave Is Not This...*/ SM2 = 1;/* Make This Slave As Not Being Addressed */ } 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 Master Portocol End Byte */ /* Update The Protocol Data */ } else if(rec_data == MP_START_BIT) { /* If Data Received Is Master Protocol Start Byte */ /* Prepare To Receive The Data Bytes From The Next Reception */ } else { /* If Data Bytes Are Being Received...*/ /* Load The Data Bytes Into The Buffers */ } give_data_ack = 1;/* Send Data Acknowledge To Master */ } RI = 0; /* Clear RI To Wait For Next Character */ rec_data = 0; /* Clear The Received Byte Storing Buffer */ } // TRANSMITTER SECTION if(TI) { TI = 0; trans_r =0; } } void send_data(unsigned char i) { /* Send The Data Byte To The Master */ trans_r = 1; SBUF = i; while(trans_r); } void send_data_w_ack(unsigned char i) { data_ack = 0; SBUF = i; while(!data_ack);/* Wait Till Master Acknowledge Received In SISR */ } void sendProtocolToMaster(void) { /* Updates The All The Current Onhook/Offhook Status Of The Slave */ if(data_ready) { send_data_w_ack(SP_START_BIT); /* Send Slave Protocol Start Byte */ send_data_w_ack(OH_START_BIT); /* Send 'Protocol Type' Identification Byte */ send_data_w_ack(off_hook); /* Send The Data Byte */ send_data_w_ack(SP_END_BIT); /* Send Slave Protocol End Byte */ data_ready = 0; } send_data(END_OF_COMM_ARR[hardware_id]);/* Send The End Of Comm Byte */ transmit_enable = 0; SM2 = 1; } void main (void) { /* Initialisation Code Here */ /* Card hardware ID Calculation Code Here */ while(1) { /* Loop Forever */ 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 Data Ack */ give_data_ack = 0;/* Clear The Request */ send_data(DATA_ACK); } if(transmit_enable)//If The Slave Is Enabled In Re-Transmiting Mode, sendProtocolToMaster();// Send Pending Data To The Master. } } } Now, we are trying to implement a modification to the above scenario as : The data bytes being sent from master to slaves will not be instantaneous. Instead, a fixed serial array for each slave will be created. Whatever data bytes need to be sent will be pushed into the array. The data bytes frame is in the following format, which will have a byte counter that goes on incrementing when data is being pushed: Master Protocol Start Byte -> Protocol Type Identification Byte -> Data Byte -> . . . . . -> Data Byte -> Master Protocol End Byte. In The superloop, a loop for the individual slaves will be running, and these serial arrays will be sent to the serial buffer SBUF. We found this type of implementation in some similar system, found stable too. and the operations of the system found stable. Whether you install 1 slave card or all 12 slave cards together, the speed of operations is the same. Q. In the above two methods, which one is the best stable method as far as Master-slave communication upto 14 slaves is concerned? Thanks in advance. |
Topic | Author | Date |
Multiprocessor Communication 8052 | 01/01/70 00:00 | |
where is bottleneck? | 01/01/70 00:00 | |
That's the usual approach | 01/01/70 00:00 | |
one comment | 01/01/70 00:00 | |
9th Bit - How ? | 01/01/70 00:00 | |
how to use bit 9 for data bytes? | 01/01/70 00:00 | |
one form of 9th bit use | 01/01/70 00:00 | |
One byte | 01/01/70 00:00 | |
One Byte !!! | 01/01/70 00:00 | |
re: 1 byte - MDB | 01/01/70 00:00 | |
Strong work | 01/01/70 00:00 | |
Just as there is a timeout | 01/01/70 00:00 | |
my reason | 01/01/70 00:00 | |
Protocol should preferably support dry-counting for EOP pos | 01/01/70 00:00 | |
Methods in brief | 01/01/70 00:00 | |
At least 1 packet less (sic) | 01/01/70 00:00 | |
Neither! | 01/01/70 00:00 |