新手上路
- 积分
- 30
- 金钱
- 30
- 注册时间
- 2017-12-2
- 在线时间
- 8 小时
|
大家好!有个问题请教大家。
硬件版本:战舰V3
软件:freemodbus1.5。
我在移植之后发现一个问题,使用modbuspoll工具,发送指令01 03 00 00 00 08 校验 校验 时 是没问题的,从机一直能无错误的返回。
但是发送 01 03 00 01 00 08 校验 校验 时,发现从机有一半左右是不返回数据的,调试发现此时STM32 接收的是00 00 00 01 00 08 校验 校验 这个校验和电脑发送的校验是一样的。
不知道是什么原因,卡在这里了 请教大家 希望帮忙。谢谢了。
以下为部分代码
void USART1_IRQHandler(void) //串口中断
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
prvvUARTRxISR();
}
if(USART_GetITStatus(USART1, USART_IT_TC) == SET)
{
USART_ClearITPendingBit(USART1, USART_IT_TC);
prvvUARTTxReadyISR();
}
}
BOOL
xMBRTUReceiveFSM( void )//这个函数 是串口接收到数据产生中断后,调用的
{
BOOL xTaskNeedSwitch = FALSE;
UCHAR ucByte;
assert( eSndState == STATE_TX_IDLE );
/* Always read the character. */
( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
switch ( eRcvState )
{
/* If we have received a character in the init state we have to
* wait until the frame is finished.
*/
case STATE_RX_INIT:
vMBPortTimersEnable( );
break;
/* In the error state we wait until all characters in the
* damaged frame are transmitted.
*/
case STATE_RX_ERROR:
vMBPortTimersEnable( );
break;
/* In the idle state we wait for a new character. If a character
* is received the t1.5 and t3.5 timers are started and the
* receiver is in the state STATE_RX_RECEIVCE.
*/
case STATE_RX_IDLE:
usRcvBufferPos = 0;
ucRTUBuf[usRcvBufferPos++] = ucByte;//Ö÷»ú·¢ËíÄ3D©êy¾Yê±£¬′ó»ú½óêÕμı¨ÎÄǰá½×Ö½ú¶¼êÇ0x00£¬2»ÖaμàÎaé¶¡£
BUFERR[BUFERR_COUNT]=ucRTUBuf[usRcvBufferPos-1];
eRcvState = STATE_RX_RCV;
/* Enable t3.5 timers. */
vMBPortTimersEnable( );
break;
/* We are currently receiving a frame. Reset the timer after
* every character received. If more than the maximum possible
* number of bytes in a modbus frame is received the frame is
* ignored.
*/
case STATE_RX_RCV:
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
{
ucRTUBuf[usRcvBufferPos++] = ucByte;
BUFERR_COUNT++;
BUFERR[BUFERR_COUNT]=ucRTUBuf[usRcvBufferPos-1];
}
else
{
eRcvState = STATE_RX_ERROR;
}
vMBPortTimersEnable();
break;
}
return xTaskNeedSwitch;
}
BOOL
xMBRTUTransmitFSM( void )//这个函数 是串口发送完成中断 调用的
{
BOOL xNeedPoll = FALSE;
assert( eRcvState == STATE_RX_IDLE );
switch ( eSndState )//·¢Ëí×′쬣¬Ã¶¾ùààDí ¿ÕÏD×′쬻ò·¢Ëí×′ì¬
{
/* We should not get a transmitter event if the transmitter is in
* idle state. */
case STATE_TX_IDLE://¿ÕÏD×′ì¬
/* enable receiver/disable transmitter. */
vMBPortSerialEnable( TRUE, FALSE );
break;
case STATE_TX_XMIT:
/* check if we are finished. */
if( usSndBufferCount != 0 )
{
xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );//Ïò′®¿ú·¢Ëíêy¾Y
pucSndBufferCur++; /* next byte in sendbuffer. */
usSndBufferCount--;
}
else
{
xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
/* Disable transmitter. This prevents another transmit buffer
* empty interrupt. */
vMBPortSerialEnable( TRUE, FALSE );
eSndState = STATE_TX_IDLE;
}
break;
}
return xNeedPoll;
}
以下两个函数为串口发送数据和接收数据
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
/* Put a byte in the UARTs transmit buffer. This function is called
* by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
* called. */
MODBUS_USART->DR = (ucByte & (uint16_t)0x01FF);
return TRUE;
}
BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
/* Return the byte in the UARTs receive buffer. This function is called
* by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
*/
u8 bytebuf;
bytebuf=(u8)(MODBUS_USART->DR & (uint16_t)0x01FF);
*pucByte =bytebuf;
//USART_SendData(MODBUS_USART,bytebuf) ;
return TRUE;
}
|
|