OpenEdv-开源电子网

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

F767阿波罗移植freemodbus返回数据第一位地址不对,跪求大神解决

[复制链接]

1

主题

12

帖子

0

精华

高级会员

Rank: 4

积分
820
金钱
820
注册时间
2018-7-3
在线时间
17 小时
发表于 2018-10-2 12:09:01 | 显示全部楼层 |阅读模式
1金钱
按照八度大神的移植教程移植了freemodbus到F767上,因为采用HAL库以及寄存器上的一些变更花了不少时间去分析,采用的是第一种移植方法,没有使用RTOR,待会使用RTOR省一个寄存器的方法来做下
移植调试出数据之后发现一个很奇怪但是怎么都解决不了的问题,返回的从机地址老是不对,其余没问题,查看发送缓存中的数据也是正确的。
回过头来使用RS485例程收发数据,也没有问题。
如下是调试数据在MBRtu.c xMBRTUTransmitFSM函数中ucRTUBuf中数据是正确的,在中断发送函数xMBPortSerialPutByte()中读出的第一第二位也是正确的
ucRTUBuf[0] re is 1
ucRTUBuf[1] re is 4
ucRTUBuf[2] re is 2
ucRTUBuf[3] re is 0
ucRTUBuf[4] re is f
ucRTUBuf[5] re is f9
ucRTUBuf[6] re is 34
ucRTUBuf[7] re is ca
USART2_RS485Handler.Instance->TDR is 1
USART2_RS485Handler.Instance->TDR is 4
但是modbus poll实际接收salve address一直不变是C0,显示CRC校验失败
000387-Tx:01 04 00 00 00 01 31 CA
000388-Rx:C0 04 02 00 0F F9 34
000389-Tx:01 04 00 00 00 01 31 CA
000390-Rx:C0 04 02 00 0F F9 34
000391-Tx:01 04 00 00 00 01 31 CA
000392-Rx:C0 04 02 00 0F F9 34
000393-Tx:01 04 00 00 00 01 31 CA
000394-Rx:C0 04 02 00 0F F9 34
000395-Tx:01 04 00 00 00 01 31 CA
000396-Rx:C0 04 02 00 0F F9 34
000397-Tx:01 04 00 00 00 01 31 CA
000398-Rx:C0 04 02 00 0F F9 34

使用了很多方法包括
1将xMBRTUTransmitFSM中发送部分使用例程中的RS485_Send_Data替代,这个替代之后没有输出,因为使用的函数调用东西太多timeout吧,个人认为。

       if( usSndBufferCount != 0 )
        {
            xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
            pucSndBufferCur++;  // next byte in sendbuffer.
            usSndBufferCount--;
                       
        }

        //RS485_Send_Data(ucRTUBuf,usSndBufferCount);
                //delay_ms(10);

2、将mbrtu.c中eMBRTUSend函数中pucSndBufferCur = ( UCHAR * ) pucFrame - 1; 的地址多减 pucSndBufferCur = ( UCHAR * ) pucFrame - 2,然后再多减一结果发现从第二位的slaveadd
往后的数据对了,但是起始固定的C0不变,CRC结果少发了一位,肯定也是CRC校验失败。
000397-Tx:01 04 00 00 00 01 31 CA
000398-Rx:C0 01 04 02 00 0F F9

3、直接将slaveadd第一字节强制发送,使用变量CNT反转来控制只发一次。结果一样。起始从一开始读取的值就知道,在TDR中都没问题
4、查看之前的都是1FF,但是发现在767配套的HAL_UART_Transmit和HAL_UART_Receive中对于USART2_RS485Handler.Init.WordLength=UART_WORDLENGTH_8B;使用的mask是FF,改过来之后没啥变化,一样的。
//USART2_RS485Handler.Instance->TDR = (ucByte& (uint16_t)0x01FFU);
  USART2_RS485Handler.Instance->TDR = (ucByte& (uint8_t)0xFFU);

目标是用F767 阿波罗做主机,就怕这个问题在做主机时还会发生,跪求大神协助。万分感谢


modbus 485实验.zip

2.08 MB, 下载次数: 101

移植程序

最佳答案

查看完整内容[请看2#楼]

查看手册针对TC形成有如下描述 Bit 6 TC: Transmission complete This bit is set by hardware if the transmission of a frame containing data is complete and if TXE is set. An interrupt is generated if TCIE=1 in the USART_CR1 register. It is cleared by software, writing 1 to the TCCF in the USART_ICR register or by a write to the USART_TDR register. An interrupt is generated if TCIE=1 in the USART ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

12

帖子

0

精华

高级会员

Rank: 4

积分
820
金钱
820
注册时间
2018-7-3
在线时间
17 小时
 楼主| 发表于 2018-10-2 12:09:02 | 显示全部楼层
查看手册针对TC形成有如下描述
Bit 6 TC: Transmission complete
This bit is set by hardware if the transmission of a frame containing data is complete and if
TXE is set. An interrupt is generated if TCIE=1 in the USART_CR1 register. It is cleared by
software, writing 1 to the TCCF in the USART_ICR register or by a write to the USART_TDR
register.
An interrupt is generated if TCIE=1 in the USART_CR1 register.
0: Transmission is not complete
1: Transmission is complete
Note: If TE bit is reset and no transmission is on going, the TC bit will be set immediately
关键在于最后Note这句,并不是只有发送一个字节能触发TC置1,把TE清零再置1同样能产生一个TCIE。所以在发送enable的时候将TE清零再置1,惊奇的发现hal库有这个函数,HAL_HalfDuplex_EnableTransmitter,不过里面将RE清零了,接收没问题,就懒得管了。手写清置TEslave返回数据没问题了。
问题从一开始就知道出在这个函数里面发的第一个字节,所以注销掉,使用TE位操作置TC产生中断。
eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    USHORT          usCRC16;

    ENTER_CRITICAL_SECTION(  );

    /* Check if the receiver is still in idle state. If not we where to
     * slow with processing the received frame and the master sent another
     * frame on the network. We have to abort sending the frame.
     */
    if( eRcvState == STATE_RX_IDLE )
    {
        /* First byte before the Modbus-PDU is the slave address. */
        pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
        usSndBufferCount = 1;

        /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
        pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
        usSndBufferCount += usLength;

        /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
        usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
        ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
        ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );


        //printf("pucSndBufferCur[0] re is %x \r\n",pucSndBufferCur[MB_SER_PDU_ADDR_OFF]);

        /* Activate the transmitter. */
        //发送状态转换,在中断中不断发送
        eSndState = STATE_TX_XMIT;
                //pucSndBufferCur_reset = 0 ;
               
        
        //启动第一次发送,这样才可以进入发送完成中断
        //xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
                //xMBPortSerialPutByte( (char )01 );
                //pucSndBufferCur++;  /* next byte in sendbuffer. */
        //usSndBufferCount--;
        //delay_us(10);
                       
        //使能发送状态,禁止接收状态
        vMBPortSerialEnable( FALSE, TRUE );
    }
    else
    {
        eStatus = MB_EIO;
    }
    EXIT_CRITICAL_SECTION(  );
    return eStatus;
}

vMBPortSerialEnable中做如下修改       
        if (xTxEnable)  
        {
                __HAL_UART_ENABLE_IT(&USART2_RS485Handler,USART_IT_TC);  
                RS485_TX_Set(1);
                //HAL_HalfDuplex_EnableTransmitter(&USART2_RS485Handler);
               
                /* Clear TE bits */
                CLEAR_BIT(USART2_RS485Handler.Instance->CR1, (USART_CR1_TE));
                /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
                SET_BIT(USART2_RS485Handler.Instance->CR1, USART_CR1_TE);

               
        }
回复

使用道具 举报

31

主题

158

帖子

0

精华

高级会员

Rank: 4

积分
738
金钱
738
注册时间
2020-4-30
在线时间
111 小时
发表于 2020-6-20 14:59:25 | 显示全部楼层
我要升级  怎么升级才能快啊
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2016-6-14
在线时间
22 小时
发表于 2020-6-21 19:41:24 | 显示全部楼层
Rockcheng 发表于 2018-10-2 12:09
查看手册针对TC形成有如下描述
Bit 6 TC: Transmission complete
This bit is set by hardware if the tr ...

嗨,你的这个问题解决了吗,我也遇到这个情况了,没有解决,

可否分享一下你的源码,谢谢
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-1 07:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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