⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
		}
		if (index == SIZE_UART_OUT_ARRAY)		// If we go past the end ...
		{
			index = 0;							// ... start over at the beginning
		}
	}

	if(returnValue != 0)
	{
		// Do something...
	}

	return (returnValue);
}


//==========================================================================================
// Function:		WriteUARTString()
//
// Description: 	This function is used to interface between the code and the function
//					which sends data to the UART (SendUART()).
//
//					This routine accepts a count, and a pointer to the start of data.  It
//					then inserts an entry into the array UARTDataOut which TaskWriteUART
//					uses to send out data.
//					Note that it will store the count and pointer, not buffer the actual
//					data, so the calling function must keep the variable around (static or
//					global), or else use the function WriteUARTValue().
//
// Input:			s16		count;		Number of words to transfer.
//					u16*	dataPtr;	Pointer to start of data.
//
// Return:  		SUCCESS  		Added to list. (not necesarily sent yet)
//					ERR_LIST_FULL   No buffer space.
//
// Revision History:
//==========================================================================================
s16 WriteUARTString(u16* msgString)
{
	#define	UART_OUT_BUFF_SIZE	256
	static u16		UARTOutBuff[UART_OUT_BUFF_SIZE];
	static s16		indexS = 0;		// Index into UARTOutBuff
	s16				returnValue;	// Function return value
	s16				msgLen=-1;		// Length of message string
	u16				uLengthFound=0;	// Flag used to find string length.
	u16				i;				// Loop index

	// We don't want to sent a trailing NULL, so start the count at -1, so it doesn't show up in the count
	while( (uLengthFound==0) && (msgLen<20) )
	{
		if(msgString[++msgLen] == 0)	// Found string terminator
		{
			uLengthFound = 1;
		}
	}
			
	// Append the msgString to the end of UARTOutBuff if there is room, otherwise start back at the beginning
	if (indexS + msgLen + 1 >= UART_OUT_BUFF_SIZE)
	{
		indexS = 0;
	}

	// Copy received string into UARTOutBuff.
	for(i=0; i<msgLen; i++)
	{
		UARTOutBuff[indexS + i] = msgString[i];
	}

	returnValue = WriteUART(UART_TARGET_EMETER, msgLen, &UARTOutBuff[indexS]);		// target,count,pointer
	
	indexS += msgLen;			// Point to next available location for next pass.

	if(returnValue != 0)
	{
		// Do something...
	}

	return (returnValue);
}



//==========================================================================================
// Function:		uart_read()
//
// Description: 	This routine recieves data into the supplied buffer.
//
// Parameters:	  	buf - buffer to read data into.
//					offset - byte offset in buf to begin receiving chars.
//					cnt - number of data samples to capture into buffer.
//
// Return:			Last character read.
//
// Revision History:
//==========================================================================================
u16 uart_read(u16* pBuf, u16 offset, u16 cnt)
{
	u16		uReturnChar;

INTR_GLOBAL_DISABLE();
	while (cnt--)
	{
		while (uUartBufferPointerIn == uUartBufferPointerOut)
		{
			// Wait for RX data ready.
		}

		uReturnChar = upUartBufferFifo[uUartBufferPointerOut];
		if(++uUartBufferPointerOut >= UART_BUFFER_SIZE)
		{
			uUartBufferPointerOut = 0;
		}

		// even byte? (first half goes in high nibble)
		if(offset/2 == (offset+1)/2)
		{
			pBuf[offset/2] &= 0x00FF;	// Clear bits
			pBuf[offset/2] |= (u8) (uReturnChar & 0x00FF)<<8;
		}
		else	// odd.
		{
			pBuf[offset/2] &= 0xFF00;
			pBuf[offset/2] |= (u8) (uReturnChar & 0x00FF);
		}
		offset++;
	}
INTR_GLOBAL_ENABLE();

	return(uReturnChar);
}


//==========================================================================================
// Function:		SelectUARTTarget()
//
// Description: 	This function selects the target for UART communication.
//					Choices are UART_TARGET_HOST (1) or UART_TARGET_EMETER (0).
//
// Revision History:
//==========================================================================================
void SelectUARTTarget(u16 UARTTarget)
{
	uUARTTarget = UARTTarget;		// Set global variable
	AssignBits(GPIOSR,       1<<5, UARTTarget<<5);	// Send target receive select signal via DSP GPIO pin 	

	if(UARTTarget == UART_TARGET_HOST) 		// 1
	{
		AssignBits(UART_MCR_REG, 1<<3, 0);	// Send target transmit select signal via OUT2 pin on 16C550
	}
	else
	{
		AssignBits(UART_MCR_REG, 1<<3, 1<<3);	// Send target transmit select signal via OUT2 pin on 16C550
	}

	AssignBits(UART_MCR_REG, 1<<2, UARTTarget<<2);	// Send target transmit select signal via OUT2 pin on 16C550
	DebugDelay();									// Flush C54x if in debug mode.

	DelayNus(100);		// Improves errors related to RS232/RS485 switching.
}



//==========================================================================================
// Function:		SelectRS485Direction()
//
// Description: 	This function selects the data flow direction of the RS485 connection.
//					Choices are RS485_TALK (3) or RS485_LISTEN (0).
//
//					Note that the default direction is LISTEN.  Code that changes it to
//					TALK, MUST restore it.
//
// Revision History:
//==========================================================================================
void SelectRS485Direction(u16 RS485Dir)
{
	AssignBits(GPIOSR,  3<<3, RS485Dir<<3);		// Send direction control signal via GPIO pins 
	DebugDelay();								// Flush C54x if in debug mode.

	// Give drives time to get up.
	DelayNus(25);
}


//==========================================================================================
// Function:		UartISR()
//
// Description: 	This is the Interrupt Service Routine for INT1 which is tied to the
//					16C550.  It handles switching RS485 direction between talk and listen
//					after the transmit message has been sent, along with source switching
//					between the host and emeter if required.
//
// Revision History:
//==========================================================================================
interrupt void UartISR(void)
{
	// Check reason for interrupt.
	if(UART_IIR_REG & UART_IIR_TRANSMIT_EMPTY == UART_IIR_TRANSMIT_EMPTY)	// Data has gone out
	{
		// To get to this point, means we've just finished sending a string to the emeter.
		// Now reconfigure the 485 to listen, and if we're not expecting a return value from the
		// emeter, set the 16C550 to listen to the host, not the meter.   If we are expecting an
		// emter reply, the switch back to the host will be handled after receiving the emeter data.

		DelayNus(10);		// Time for last bit to get transfered.  Probably not needed, but 10 usec won't hurt anything.

		// We turn off PLC traffic while the last byte is transferred to make sure that the plc
		// traffic doesn't hold off this interrupt and prevent us from switching back to LISTEN.
		// The same flag (uHoldOffPLC) is also used to disable PLC traffic during an flash
		// update, so only Re-enable it here if we were stopped for the last byte.
		if(uLastByteFlag == 1)
		{
			uHoldOffPLC = 0;	// Allow PLC to continue.
			uLastByteFlag = 0;	// Reset for next time.
		}

		SelectRS485Direction(RS485_LISTEN);		// Set RS485 to listen to e-meter.

		if (uBoard == BOARD_MASTER)
		{
			if(uUartState == UART_RECEIVE_COMMAND)	// This gets set by ProcessMasterCommand() before command is issued
			{										// It covers the problem of the EMeter not sending anything back
													// but the host still needing a response.
				SelectUARTTarget(UART_TARGET_HOST);

				if(uAckAfter485 == 1)
				{
					// No real status to send back, this just lets the host know that we're ready
					// for the next command.
					WriteUARTValue(UART_TARGET_HOST, SUCCESS);
					uAckAfter485 = 0;
					ulAutoPollCounter = 0L;
					uAutoPollPause = 0;
				}
			}
			//else	// uUartState == UART_RECEIVE_RESPONSE.  We're expecting to get data back
			//{		//  from the emeter.  Nothing else to do other than switch to RS485_LISTEN.
			//}		//  which was done above.
		}
		else	// board == slave.
		{
			if(uAckAfter485 == 1)
			{
				// Note that this response isn't actually from the emeter.
				uAckAfter485 = 0;
				uTransmitPacketReady = 1;
			}
		}
	}
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -