硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3660|回复: 5
收起左侧

[有问必答] MODBUS程序里面有一处没看明白!

[复制链接]

1

主题

1

回帖

7

积分

新手上路

积分
7
发表于 2017-12-30 11:39:11 | 显示全部楼层 |阅读模式
代码取自安富莱教程里的范例
QQ截图20171230113136.png

这个函数作用是对发送过来的数据包进行解析,然后再执行相应的动作。
有一处不太明白:       
crc1 = CRC16_Modbus(g_tModS.RxBuf, g_tModS.RxCount);
        if (crc1 != 0)
        {
                goto err_ret;
        }


这里本应该是用于判断CRC16校验码的结果的正确性的,但是又对接收到的数据包(一帧完整的数据,包括校验码)进行一次CRC校验是什么情况!!?有点看不明白了。。。
如果要修改的话,该怎么修改呢!?

V5-RS485 MODBUS从站例程(V1.4).rar

4.71 MB, 下载次数: 134

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107452
QQ
发表于 2017-12-30 11:42:47 | 显示全部楼层
无需任何修改,这里是对接收到数据和数据中带的CRC部分一起做了校验,检验值就是0。

而无需再麻烦的单独计算数据校验值,再跟发送过来的CRC校验值做比较。

回复

使用道具 举报

1

主题

1

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2017-12-30 12:09:52 | 显示全部楼层
uint16_t CRC16_Modbus(uint8_t *_pBuf, uint16_t _usLen)
{
        uint8_t ucCRCHi = 0xFF; /* ¸ßCRC×Ö½ú3õê¼»ˉ */
        uint8_t ucCRCLo = 0xFF; /* μíCRC ×Ö½ú3õê¼»ˉ */
        uint16_t usIndex;  /* CRCÑ-»·ÖDμÄË÷òy */

    while (_usLen--)
    {
                usIndex = ucCRCHi ^ *_pBuf++; /* ¼ÆËãCRC */
                ucCRCHi = ucCRCLo ^ s_CRCHi[usIndex];
                ucCRCLo = s_CRCLo[usIndex];
    }
    return ((uint16_t)ucCRCHi << 8 | ucCRCLo);
}

这个函数没有看明白,是说 不带CRC校验的数据包进入这个函数,返回校验值。。而带校验的数据包进如该函数,返回0。是吗?
如果我要拓展功能,使用更多的寄存器,这个函数依然有效吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107452
QQ
发表于 2017-12-30 13:51:14 | 显示全部楼层
仰慕者 发表于 2017-12-30 12:09
uint16_t CRC16_Modbus(uint8_t *_pBuf, uint16_t _usLen)
{
        uint8_t ucCRCHi = 0xFF; /* &#184;&#223;C ...

1. 是的,要活学活用。
   接收到数据计算CRC,跟接收到的CRC数值再计算CRC,就是0,这么说是否明白了。

2. 是的。

回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2018-1-10 13:55:59 | 显示全部楼层
eric2013 发表于 2017-12-30 11:42
无需任何修改,这里是对接收到数据和数据中带的CRC部分一起做了校验,检验值就是0。

而无需再麻烦的单独 ...

你好,我参照你的中断程序(主要是使用FIFO,cubeMx很难实现),但是发现无法接收第一帧数据(都不进中断),第二帧数据就正常了,   不知道是什么原因?  

初始化是cubMx生成的,
----------------------------
void MX_USART1_UART_Init(uint32_t _baud)
{
  LL_USART_InitTypeDef USART_InitStruct;

  LL_GPIO_InitTypeDef GPIO_InitStruct;
  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
  
  /**USART1 GPIO Configuration  
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  LL_USART_ConfigAsyncMode(USART1);
  
  LL_USART_EnableIT_RXNE(USART1);  /* 使能接收中断 */
  /*
      USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
      注意: 不要在此处打开发送中断
      发送中断使能在SendUart()函数打开
*/

  LL_USART_Enable(USART1);
    /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
        如下语句解决第1个字节无法正确发送出去的问题 */
    LL_USART_ClearFlag_TC(USART1);     /* 清发送完成标志,Transmission Complete flag */
}
求解
------------------------------------
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107452
QQ
发表于 2018-1-11 00:48:40 | 显示全部楼层
ck123 发表于 2018-1-10 13:55
你好,我参照你的中断程序(主要是使用FIFO,cubeMx很难实现),但是发现无法接收第一帧数据(都不进中断), ...

排查下硬件或者你的串口线没问题吧。如果没有问题估计是HAL/LL库哪里的配置有些问题,具体这个库,我没有研究过。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-1 20:48 , Processed in 0.325746 second(s), 34 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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