21# huanben
呵呵,CSMA/CD算法足以,贴一段上来好了,反正只是做着玩玩..
/*******************************************************************************************************************************
* Function Name : RS485_Tx_Mainloop
* Description : Frame architecture
* Parameter :
* Return :
* Notes :
*******************************************************************************************************************************/
void RS485_Tx_Mainloop(void)
{
register UINT8 i;
UINT8 mTxDataTemp;
UINT8 mCheckSum;
// RS485 Protocol processing(Send)
switch(eRS485_TxStateMachine)
{
case eBusIdle:
l_TxBufferProber++;
if(l_TxBufferProber == TX_FRAME_BUFFER_SIZE)
{
l_TxBufferProber = 0;
}
if(sTxFrameBuffer[l_TxBufferProber].mFrameBufferEmpty)
{
pRxFrameCompare = &l_FrameCompare[0];
mTxDataTemp = (UINT8)sTxFrameBuffer[l_TxBufferProber].eTxFrameType;
switch(mTxDataTemp)
{
case eFrameType_MsgUnicast:
case eFrameType_MsgMulticast:
// Byte 1: 0x80/0x90|Length
l_RxFrameCount = sTxFrameBuffer[l_TxBufferProber].mFrameLength + 6;
mTxDataTemp |= l_RxFrameCount;
*pRxFrameCompare++ = mTxDataTemp;
mCheckSum = mTxDataTemp;
// Byte 2: TargetAddress(Unicast or Multicast)
mTxDataTemp = sTxFrameBuffer[l_TxBufferProber].mFrameTargetAddress;
*pRxFrameCompare++ = mTxDataTemp;
mCheckSum += mTxDataTemp;
break;
case eFrameType_MsgBroadcast:
// Byte 1: 0xA0|Length
l_RxFrameCount = sTxFrameBuffer[l_TxBufferProber].mFrameLength + 5;
mTxDataTemp |= l_RxFrameCount;
*pRxFrameCompare++ = mTxDataTemp;
mCheckSum = mTxDataTemp;
break;
default:
assert(0);
break;
}
// Common: MsgWord[0], MsgParam[1-mFrameLength]
sTxFrameBuffer[l_TxBufferProber].mFrameContentHead = 0;
for(i = 0; i <= sTxFrameBuffer[l_TxBufferProber].mFrameLength; i++)
{
mTxDataTemp = sTxFrameBuffer[l_TxBufferProber].mFrameContent[i];
if(mTxDataTemp & 0x80)
{
mTxDataTemp &= 0x7F;
sTxFrameBuffer[l_TxBufferProber].mFrameContentHead |= (0x01 << i);
}
*pRxFrameCompare++ = mTxDataTemp;
mCheckSum += mTxDataTemp;
}
// Common: MsgParamHead
mTxDataTemp = sTxFrameBuffer[l_TxBufferProber].mFrameContentHead;
*pRxFrameCompare++ = mTxDataTemp;
mCheckSum += mTxDataTemp;
// Common: LocalAddress
*pRxFrameCompare++ = gUnicastAddress;
mCheckSum += gUnicastAddress;
// Last Byte: CheckSum(Delete the most significant bit)
mTxDataTemp = mCheckSum & 0x7F;
*pRxFrameCompare = mTxDataTemp;
eRS485_TxStateMachine = eTxBusDetect;
}
break;
case eTxBusDetect:
BusDetect_Init();
eRS485_TxStateMachine = eTxBusDetectResult;
break;
case eTxBusDetectResult:
switch(BusDetect_Results())
{
case eScanning:
break;
case eBusbusy:
eRS485_TxStateMachine = eTxBusDetect;
break;
case eBusLeisure:
l_RxFrameCompareChecksum = 0;
l_RxFrameCount = l_FrameCompare[0] & 0x0F;
pRxFrameCompare = &l_FrameCompare[0];
l_TxFrameSendError = 0;
l_TxFrameSendComplete = 0;
for(i = 0; i < (l_FrameCompare[0] & 0x0F); i++)
{
Uart0_Push(l_FrameCompare[i]);
}
eRS485_TxStateMachine = eTxSending;
default:
assert(0);
break;
}
break;
case eTxSending:
if(l_TxFrameSendError)
{
switch(sTxFrameBuffer[l_TxBufferProber].mFrameResendTime)
{ // mFrameResendTime: 1 - 255(The number of times a frame to send), 0 - unlimited
case 0: // Unlimited number of try again
l_TxBufferProber--;
break;
case 1: // Give up this frame data
sTxFrameBuffer[l_TxBufferProber].mFrameBufferEmpty = 0;
break;
default: // 2 - 255: Try to send data once again
l_TxBufferProber--;
sTxFrameBuffer[l_TxBufferProber].mFrameResendTime--;
break;
}
eRS485_TxStateMachine = eBusIdle;
}
else if(l_TxFrameSendComplete)
{ // Data frame sent successfully, Clear the buffer
sTxFrameBuffer[l_TxBufferProber].mFrameBufferEmpty = 0;
eRS485_TxStateMachine = eBusIdle;
}
break;
default:
assert(0);
break;
}
}
#endif /*---------------------------------------------------------------------------------------------------------------------*/
/*******************************************************************************************************************************
* Function Name : Uart_FrameHandle_Register
* Description : Registration. Allocation function processing receives the legal frame
* Parameter : pFunction - Scan code callback function pointer
* Return :
* Notes :
*******************************************************************************************************************************/
void Uart_FrameHandle_Register(void (*pFunction)(struct RxFrameArchitecture *pEffectiveFrame))
{
sRxFrameArchitecture.pFramehandler = pFunction;
}
/*******************************************************************************************************************************
* Function Name : Uart_Rx_Mainloop
* Description : Deal with the received data from a serial port
* Parameter :
* Return :
* Notes :
*******************************************************************************************************************************/
void Uart_Rx_Mainloop(void)
{
register UINT8 temp;
assert(sRxFrameArchitecture.pFramehandler != NULL);
// RS485 Protocol processing(Receive)
while(Uart0_ReciNum())
{
temp = Uart0_Pop();
if(temp & 0x80)
{ // Frame head is always 1XXXXXXXB
eUart_RxStateMachine = eRxFindFrameHead;
}
switch(eUart_RxStateMachine)
{
case eRxFindFrameHead:
sRxFrameArchitecture.eRxFrameType = temp & 0xF0;
sRxFrameArchitecture.mFrameLength = temp & 0x0F;
sRxFrameArchitecture.pFrameBuffer = &sRxFrameArchitecture.mFrameBuffer[0];
sRxFrameArchitecture.mFrameCheckSum = temp;
switch(sRxFrameArchitecture.eRxFrameType)
{
case eFrameType_MsgUnicast:
case eFrameType_MsgMulticast:
// Except 3-Bytes(FrameHead + TargetAddress + Checksum)
sRxFrameArchitecture.mRxDataCounter = sRxFrameArchitecture.mFrameLength - 3;
eUart_RxStateMachine = eRxFrameAddressCompire;
break;
case eFrameType_MsgBroadcast:
// Except 2-Bytes(FrameHead + Checksum)
sRxFrameArchitecture.mRxDataCounter = sRxFrameArchitecture.mFrameLength - 2;
eUart_RxStateMachine = eRxFrameReceiving;
break;
default:
assert(0);
break;
}
break;
case eRxFrameAddressCompire:
switch(sRxFrameArchitecture.eRxFrameType)
{
case eFrameType_MsgUnicast:
eUart_RxStateMachine = (gUnicastAddress == temp) ? eRxFrameReceiving : eRxFrameIgnore;
break;
case eFrameType_MsgMulticast:
eUart_RxStateMachine = (gMulticastAddress == temp) ? eRxFrameReceiving : eRxFrameIgnore;
break;
default:
assert(0);
break;
}
sRxFrameArchitecture.mFrameCheckSum += temp;
break;
case eRxFrameReceiving:
if(1 < sRxFrameArchitecture.mRxDataCounter)
{
sRxFrameArchitecture.mRxDataCounter--;
*sRxFrameArchitecture.pFrameBuffer++ = temp;
sRxFrameArchitecture.mFrameCheckSum += temp;
}
else if(1 == sRxFrameArchitecture.mRxDataCounter)
{ // Record the sender's address
sRxFrameArchitecture.mRxDataCounter = 0;
sRxFrameArchitecture.mSenderAddress = temp;
sRxFrameArchitecture.mFrameCheckSum += temp;
}
else // Last Byte: CheckSum
{ // Frame have received success
if(temp == (sRxFrameArchitecture.mFrameCheckSum & 0x7F))
{ // The frame currently being processed is not sent to their own
if(gUnicastAddress != sRxFrameArchitecture.mSenderAddress)
{
(*sRxFrameArchitecture.pFramehandler)(&sRxFrameArchitecture);
}
}
eUart_RxStateMachine = eRxFrameIgnore;
}
break;
case eRxFrameIgnore:
break;
default:
assert(0);
break;
}
}
}
|