OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2331|回复: 2

求助关于STM32F103串口问题

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-12-2
在线时间
8 小时
发表于 2018-10-29 20:35:23 | 显示全部楼层 |阅读模式
大家好!有个问题请教大家。
硬件版本:战舰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 )//·¢&#203;í×′ì&#172;£&#172;&#195;&#182;&#190;ùààDí &#191;&#213;&#207;D×′ì&#172;&#187;ò·¢&#203;í×′ì&#172;
    {
        /* We should not get a transmitter event if the transmitter is in
         * idle state.  */
    case STATE_TX_IDLE://&#191;&#213;&#207;D×′ì&#172;
        /* enable receiver/disable transmitter. */
        vMBPortSerialEnable( TRUE, FALSE );
        break;

    case STATE_TX_XMIT:
        /* check if we are finished. */
        if( usSndBufferCount != 0 )
        {
            xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );//&#207;ò′&#174;&#191;ú·¢&#203;íêy&#190;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;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-12-2
在线时间
8 小时
 楼主| 发表于 2018-10-29 20:38:22 | 显示全部楼层
发送 01 04 00 00 00 08 时候 ,也会发生错误 ,从机接收的同样  把地址 和功能码都变成0 了  我查看从机接收的方法是 接收到数据之后 立刻再发送给电脑。
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-12-2
在线时间
8 小时
 楼主| 发表于 2018-10-29 22:54:45 | 显示全部楼层
而且调试发现,设备第一次上电,返回数据少了一个地址  即电脑接收的数据从03功能码开始
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 12:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表