OpenEdv-开源电子网

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

MODBUS通信求助(从机)

[复制链接]

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
发表于 2016-12-22 10:59:37 | 显示全部楼层 |阅读模式
20金钱
在论坛看到一些大神移植的modbus,我打算自己也搞一个简单的。能通信,通CRC检验就行,
在移植之后,我用八度大神的uart_qm999cn_调试工具发送数据。
我现在先关了CRC校准,只判断接收数据的位数是不是大于设定的最小位数。我发的是6个字节。MB_SER_PDU_SIZE_MIN =4接收最小字节是4
在接收函数中
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.
     */

        *pucByte = USART_ReceiveData(USART2);  
       
        return TRUE;
}  


现在我只能收到1个字节。。。
就用这样一个函数就能实现接收串口发送的不定长数据吗?我之前用USART_ReceiveData就是只能接收一个字节?


eMBErrorCode
eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
{
    BOOL            xFrameReceived = FALSE;
    eMBErrorCode    eStatus = MB_ENOERR;

    ENTER_CRITICAL_SECTION(  );
    assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );

    /* Length and CRC check */
    if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )                //我只留下了 usRcvBufferPos >= MB_SER_PDU_SIZE_MIN  把CRC去了
        && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )     
    {
        /* Save the address field. All frames are passed to the upper layed
         * and the decision if a frame is used is done there.
         */
        *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];

        /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
         * size of address field and CRC checksum.
         */
        *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );

        /* Return the start of the Modbus PDU to the caller. */
        *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
        xFrameReceived = TRUE;
    }
    else
    {
        eStatus = MB_EIO;
    }

    EXIT_CRITICAL_SECTION(  );
    return eStatus;
}




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

使用道具 举报

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
 楼主| 发表于 2016-12-22 13:12:25 | 显示全部楼层
另外T35必须是3.5个字符时间还是 我随便设置一个都行 不如10个?
谢谢,我现在按3.5个字符设置的中断时间,每次都是新数据没来就进行定时器中断,又初始化了。
回复

使用道具 举报

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
 楼主| 发表于 2016-12-22 14:29:12 | 显示全部楼层
我发送数据1234567890到单片机
接收数据的过程是:先接收12中断处理,放到数组中a[i],i++,定时器重置
然后34到来,又进去中断,再放到数组中a[i],i++。定时器重置
直到90接收完成,没有数据了,定时器不会被重置,定时器中断,完成对数组a[i]中数据的处理
这个理解是对的吧?
我现在的问题是只能收到12 后边的收不到,我定时器的时间定时4s。。。
我是根据八度空间大神的帖子修改到F1上边,没有M4的板子,试不了他的程序。
回复

使用道具 举报

10

主题

45

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2013-7-2
在线时间
20 小时
发表于 2016-12-22 17:09:05 | 显示全部楼层
肯定是程序逻辑的问题,MODBUS程序接收数据的时候配合定时器使用,串口超过8ms没有数据就可以判断接受到了所有的数据了。你自己看下
疾风追电,满月夜郎啸苍天,我辈少年狂!!
回复

使用道具 举报

28

主题

288

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1213
金钱
1213
注册时间
2011-4-9
在线时间
97 小时
发表于 2016-12-22 17:14:23 | 显示全部楼层
每收到一个字节,缓存地址要增加的
回复

使用道具 举报

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
 楼主| 发表于 2016-12-22 19:19:51 | 显示全部楼层
羽落 发表于 2016-12-22 17:09
肯定是程序逻辑的问题,MODBUS程序接收数据的时候配合定时器使用,串口超过8ms没有数据就可以判断接受到了 ...

串口超过多长时间没收到数据就判定,数据接收完成。这个就是用定时器自己设定的时间吧?
我开始设定的是4ms,后来怕是定时短了影响,我改成秒级别的。
我用八度大神给的那个串口发数据的助手。
我直接发送1234567890
这样每个字节的间断时间是很短的吧?不会超时的吧?
波特率9600
回复

使用道具 举报

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
 楼主| 发表于 2016-12-22 19:22:30 | 显示全部楼层
山峰雪狼 发表于 2016-12-22 17:14
每收到一个字节,缓存地址要增加的

我加了,移植的那个modbus协议已经自己写好了
我发送1234567890
只能收到12,后边的收不到。
难道是我发送的方式不对?
另外我在3楼写的对modbus通讯协议的理解对吗?
谢谢
回复

使用道具 举报

50

主题

193

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-11
在线时间
141 小时
 楼主| 发表于 2016-12-23 09:45:36 | 显示全部楼层
自顶一下
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-26 12:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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