Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Parallel Communication problem

Status
Not open for further replies.

haxan

New Member
Hi, i am trying to make a parallel communication protocol which uses 10 pins from one controller and 10 from the other one. 8 pins are to transfer a byte of data and 2 pins for data control. I have successfully made one way communication from Master to Slave. however i am getting problems when sending data back to the Master. The master sends a command to the slave and the slave from the frame knows how many bytes to send back to the master. So basically master sends a command and then waits for the slave to send a certain number of bytes for which the master is waiting.

The problem occurs when i try to make the slave port for output (which is previously in input mode to read data bytes coming from master)

My frame structure is:
[START BITS][ADDRESS][COMMAND][(n) number of bytes to receive][(m) number of bytes to transmit][(n) bytes][(m) bytes][STOP BITS]

P_OM = means the slave data control pin.
P_SM = means the master data control pin.

I am using PIC24FJ128GA010 for MASTER
and
PIC18F4520 for SLAVE.

Please kindly help me. I have been stuck with this for two days now :(

I have tried giving delays etc but doesn't work.

(Note: I get logic contention error in simulation, which actually means that at some point, both the pins have different voltages and both are set to output, which should not happen as i tend to make one port into input first and then try to read byte)

Master Code:
Code:
#include "TCPIP Stack/TCPIP.h"
#include "P_Communication.h"

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------- [ PARALLEL COMMUNICATION LAYER ] -----------------------
~~~~ [ BEGIN ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

/*
Conventions:
	-- P_ means Parallel Communication (Function, Variable, Definition)
	-- SM (connected with ethernet)
	-- OM (connected with RS-485 Data Bus)
*/

/*---- [ Parallel Communication Variables ] -----------------*/
BYTE P_ADDRESS;
BYTE P_COMMAND;
BYTE P_Rec_nbytes;
BYTE P_Trans_mbytes;
BYTE P_RecData[100];
BYTE P_TransData[100];
BYTE *P_RecPtr 		= &P_RecData[0];
BYTE *P_TransPtr 	= &P_TransData[0];
BYTE P_PORT_VAL 	= 0x00;
unsigned long P_timeout 		= 0; 			// Timeout Counter
unsigned char P_timedout 		= 0;			// Timed out Flag
char COMM_P						= 0;


char P_SM_Communication(
		BYTE address,
		BYTE command,
		BYTE n_Transmit,
		BYTE m_Receive,
		BYTE *n_Bytes,
		BYTE *m_Bytes
		)
{
	/* FRAME STRUCTURE
	[STARTBITS]	[ADDRESS] [COMMAND] [N-Bytes to Transmit] [M-Bytes to Receive] [N-BYTES] [M-BYTES] [STOPBITS]
	*/
	BYTE i = 0;
	P_Init();
	if(P_OM == 0)	// OM can take request
	{
		P_timedout = 0;
		COMM_P = P_SendByte(P_START_BITS);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}

		COMM_P = P_SendByte(address);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		COMM_P = P_SendByte(command);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		COMM_P = P_SendByte(n_Transmit);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		COMM_P = P_SendByte(m_Receive);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}

		for(i = 0; i < n_Transmit; i++)
		{
			COMM_P = P_SendByte(n_Bytes[i]);
			if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		}

		for(i = 0; i < m_Receive; i++)
		{
			COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{m_Bytes[i] = COMM_P;}
		}

		COMM_P = P_SendByte(P_STOP_BITS);
		if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		else if(COMM_P == P_SUCCESSFUL){return P_SUCCESSFUL;}
		else{return P_UNSUCCESSFUL;}
	}
	return P_NOTHING;

}

char P_SendByte(BYTE data)
{
	P_timeout = 0;
	while(P_OM != 0){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_PORT_VAL = data;
	P_PORT(0);
	P_SM = 1;
	P_timeout = 0;
	while(P_OM != 1){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_SM = 0;
	return P_SUCCESSFUL;
}

BYTE P_ReadByte(void)
{
	P_PORT(1);
	P_SM = 0;
	P_timeout = 0;
	while(P_OM != 1){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_PORT_VAL = P_PORT(1);
	P_SM = 1;
	P_timeout = 0;
	while(P_OM != 0){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_SM = 0;
	return P_PORT_VAL;
}

void P_Init(void)
{
	P_PORT(1);
	P_TRIS_SM = 0;
	P_TRIS_OM = 1;
	P_SM = 0;
	P_timeout = 0;
}

BYTE P_PORT(unsigned char dir)
{
	if(dir == 0)
	{
		P_TRIS0 = 0;
		P_TRIS1 = 0;
		P_TRIS2 = 0;
		P_TRIS3 = 0;
		P_TRIS4 = 0;
		P_TRIS5 = 0;
		P_TRIS6 = 0;
		P_TRIS7 = 0;
		P_PORT0 = ((P_PORT_VAL & 0b00000001) > 0)? 1 : 0;
		P_PORT1 = ((P_PORT_VAL & 0b00000010) > 0)? 1 : 0;
		P_PORT2 = ((P_PORT_VAL & 0b00000100) > 0)? 1 : 0;
		P_PORT3 = ((P_PORT_VAL & 0b00001000) > 0)? 1 : 0;
		P_PORT4 = ((P_PORT_VAL & 0b00010000) > 0)? 1 : 0;
		P_PORT5 = ((P_PORT_VAL & 0b00100000) > 0)? 1 : 0;
		P_PORT6 = ((P_PORT_VAL & 0b01000000) > 0)? 1 : 0;
		P_PORT7 = ((P_PORT_VAL & 0b10000000) > 0)? 1 : 0;
	}
	else if(dir == 1)
	{
		P_TRIS0 = 1;
		P_TRIS1 = 1;
		P_TRIS2 = 1;
		P_TRIS3 = 1;
		P_TRIS4 = 1;
		P_TRIS5 = 1;
		P_TRIS6 = 1;
		P_TRIS7 = 1;
		P_PORT_VAL = (0x00 | (P_PORT0 | P_PORT1 << 1 | P_PORT2 << 2 | P_PORT3 << 3 | P_PORT4 << 4 | P_PORT5 << 5 | P_PORT6 << 6 | P_PORT7 << 7));
	}
	return P_PORT_VAL;
}

char P_CheckTimeout(void)
{
	if(P_timeout > 200000){P_timedout = 1;P_Init();return 1;}
	P_timeout++;
	return 0;
}


/*
~~~~ [ END ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------- [ PARALLEL COMMUNICATION LAYER ] -----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/


SLAVE CODE:
Code:
#include <p18cxxx.h>
#include <delays.h>
#include "RS_comm.h"
#include "P_Communication.h"
#include "../Commands.def"

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------- [ PARALLEL COMMUNICATION LAYER ] -----------------------
~~~~ [ BEGIN ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

/*
Conventions:
	-- P_ means Parallel Communication (Function, Variable, Definition)
	-- SM (connected with ethernet)
	-- OM (connected with RS-485 Data Bus)
*/


/*---- [ Parallel Communication Variables ] -----------------*/
BYTE P_ADDRESS;
BYTE P_COMMAND;
BYTE P_Rec_nbytes;
BYTE P_Trans_mbytes;
BYTE P_RecData[100];
BYTE P_TransData[100];
BYTE *P_RecPtr 		= &P_RecData[0];
BYTE *P_TransPtr 	= &P_TransData[0];
BYTE P_PORT_VAL 	= 0x00;
unsigned long P_timeout 		= 0; 			// Timeout Counter
unsigned char P_timedout 		= 0;			// Timed out Flag
char COMM_P			= 0;

char COMM_R;

char P_OM_Communication(
		BYTE *n_Bytes,		// Ptr to Receive n Bytes and store them
		BYTE *m_Bytes		// Ptr to Transmit m Bytes back
		)
{
	/* FRAME STRUCTURE
	[STARTBITS]	[ADDRESS] [COMMAND] [N-Bytes to Receive] [M-Bytes to Transmit] [N-BYTES] [M-BYTES] [STOPBITS]
	*/
	BYTE i = 0;
	P_Init();
	if(P_SM == 1)	// SM wants to communicate
	{
		P_timedout = 0;
		COMM_P = P_ReadByte();
		if(COMM_P != P_START_BITS)
		{
			return P_NOTHING;
		}

		COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{P_ADDRESS = COMM_P;}
		COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{P_COMMAND = COMM_P;}
		COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{P_Rec_nbytes = COMM_P;}
		COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{P_Trans_mbytes = COMM_P;}
		

		for(i = 0; i < P_Rec_nbytes; i++)
		{
			COMM_P = P_ReadByte();if(COMM_P == P_TIMED_OUT && P_timedout == 1){return P_TIMED_OUT;}else{n_Bytes[i] = COMM_P;}
		}

		COMM_R = RS_M_Communication(P_ADDRESS,P_COMMAND,P_Rec_nbytes,P_Trans_mbytes,n_Bytes,m_Bytes);
		if(COMM_R == RS_SUCCESSFUL)
		{
			for(i = 0; i < P_Trans_mbytes; i++)
			{
				COMM_P = P_SendByte(m_Bytes[i]);if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
			}
			PORTGbits.RG0 ^= 1;
		}
		else if(COMM_R == RS_COMMAND_INVALID){return P_COMMAND_INVALID;}
		else if(COMM_R == RS_TIMED_OUT){return P_TIMED_OUT;}

		COMM_P = P_ReadByte();
		PORTF = COMM_P;
		if(COMM_P == P_STOP_BITS){return P_SUCCESSFUL;}
		else if(COMM_P == P_TIMED_OUT){return P_TIMED_OUT;}
		else{return P_UNSUCCESSFUL;}
	}
	else return P_NOTHING;

}

char P_SendByte(BYTE data)
{
	P_OM = 0;	// NEW EDITION
	P_timeout = 0;
	while(P_SM != 0){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_PORT_VAL = data;
	Delay10KTCYx(1);
	P_PORT(0);
	Delay10KTCYx(1);
	P_OM = 1;
	P_timeout = 0;
	while(P_SM != 1){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_OM = 0;
	return P_SUCCESSFUL;
}

BYTE P_ReadByte(void)
{
	P_OM = 0;
	P_timeout = 0;
	while(P_SM != 1){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_PORT_VAL = P_PORT(1);
	P_OM = 1;
	P_timeout = 0;
	while(P_SM != 0){if(P_CheckTimeout() == 1){return P_TIMED_OUT;}}
	P_OM = 0;
	return P_PORT_VAL;
}

void P_Init(void)
{
	P_PORT(1);
	P_TRIS_SM = 1;
	P_TRIS_OM = 0;
	P_OM = 0;
	P_timeout = 0;
}

BYTE P_PORT(unsigned char dir)
{
	if(dir == 0)
	{
		P_TRIS0 = 0;
		P_TRIS1 = 0;
		P_TRIS2 = 0;
		P_TRIS3 = 0;
		P_TRIS4 = 0;
		P_TRIS5 = 0;
		P_TRIS6 = 0;
		P_TRIS7 = 0;
		P_PORT0 = ((P_PORT_VAL & 0b00000001) > 0)? 1 : 0;
		P_PORT1 = ((P_PORT_VAL & 0b00000010) > 0)? 1 : 0;
		P_PORT2 = ((P_PORT_VAL & 0b00000100) > 0)? 1 : 0;
		P_PORT3 = ((P_PORT_VAL & 0b00001000) > 0)? 1 : 0;
		P_PORT4 = ((P_PORT_VAL & 0b00010000) > 0)? 1 : 0;
		P_PORT5 = ((P_PORT_VAL & 0b00100000) > 0)? 1 : 0;
		P_PORT6 = ((P_PORT_VAL & 0b01000000) > 0)? 1 : 0;
		P_PORT7 = ((P_PORT_VAL & 0b10000000) > 0)? 1 : 0;
	}
	else if(dir == 1)
	{
		P_TRIS0 = 1;
		P_TRIS1 = 1;
		P_TRIS2 = 1;
		P_TRIS3 = 1;
		P_TRIS4 = 1;
		P_TRIS5 = 1;
		P_TRIS6 = 1;
		P_TRIS7 = 1;
		P_PORT_VAL = (0x00 | (P_PORT0 | P_PORT1 << 1 | P_PORT2 << 2 | P_PORT3 << 3 | P_PORT4 << 4 | P_PORT5 << 5 | P_PORT6 << 6 | P_PORT7 << 7));
	}
	return P_PORT_VAL;
}

char P_CheckTimeout(void)
{
	if(P_timeout > 2000000){P_timedout = 1;P_Init();return 1;}
	P_timeout++;
	return 0;
}


/*
~~~~ [ END ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------- [ COMMUNICATION LAYER ] ---------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
 
Last edited:
Also i would like to add, Data sent from MASTER to SLAVE goes fine if no bytes are to be read back from SLAVE. This would mean that most probability of error in functions would be in MASTER's P_ReadByte() function and maybe in SLAVE's P_SendByte().
 
One more thing to add, If i don't send the STOP BITS from MASTER and do not receive them from SLAVE, the communication goes on successfully. However i want to send STOP BITS over :(

This means that conversion of Master going into Read mode and then again Write mode or maybe making SLAVE going from writing mode to reading mode makes logic contention.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top