举报
/******************************************************************************************************************************* * 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; } } }
您需要 登录 才可以下载或查看,没有账号?注册
简单来说就是各节点同时争抢总线,发送冲突检测随机时间退避算法。原理图??呵呵...485的EN脚还要用个IO去控制,岂不是浪费资源? 83413 zq1987731 发表于 2011-10-29 12:31
34# xyz769 你好 LZ已经批评我给他的帖子捣乱了 你更厉害 连LZ问什么问题都不看下。 huanben 发表于 2011-10-29 13:41
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
等级类勋章
发帖类勋章
时间类勋章
人才类勋章
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号