Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Modbus
RT-Thread一般讨论
国民技术_N32G45x
N32G45x 硬件CRC 计算Modbus的CRC16【已修正问题】
发布于 2022-03-30 18:54:33 浏览:1192
订阅该版
[tocm] ### N32G45x 硬件CRC 计算Modbus的CRC16 以前都是使用软件CRC,浪费计算时间,有硬件CRC不用,真是可惜。本次使用硬件CRC对ModBus的CRC进行计算,测试时,遇到点问题,自带的库文件里面,把方法写死了,结果和Modubs的对不上。 ![image.png](https://oss-club.rt-thread.org/uploads/20220330/96f90755d096cd26ddbfa6fb4b1ca69e.png) ![image.png](https://oss-club.rt-thread.org/uploads/20220330/22ddc022dc13bd6ac331f9e09db7ee19.png) 文档上说的公式和modbus是一样的,那么就有可能是初值与异或值不同造成的,先相信硬件不会出错嘛。 ![image.png](https://oss-club.rt-thread.org/uploads/20220330/b3558aca9774e1c079a0d4ea683e8948.png) 自带的crc库也不要用了,一共没有用到3个寄存器,直接搞。 ``` uint16_t rt_hw_get_crc16_modbus(uint8_t *pdat, uint16_t len) { CRC->CRC16D = 0xffff; //init dat CRC->CRC16CTRL = 0x0002; //LSB while (len--) { CRC->CRC16DAT = *pdat++; } return (CRC->CRC16D); } ``` 当然初始化时钟是要加上的啦 ``` RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE); ``` 就是这么简单,再不用担心写错CRC代码了,肯定是算错了,硬件不会错😜 给它上个锁,避免被抢占打断后,计算出错。add 2022-03031 ``` #include
#include
#include
#include
/* 指向互斥量的指针 */ static rt_mutex_t crc_mutex = RT_NULL; void hw_crc_init(void) { RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE); /* 创建一个动态互斥量 */ crc_mutex = rt_mutex_create("crc_mutex", RT_IPC_FLAG_PRIO); if (crc_mutex == RT_NULL) { rt_kprintf("create crc mutex failed.\n"); return; } } uint16_t rt_hw_get_crc16(uint8_t *pdat, uint16_t len) { uint16_t crc_16 = 0; rt_mutex_take(crc_mutex, RT_WAITING_FOREVER); /*init dat*/ CRC->CRC16D = 0xffff; /*LSB*/ CRC->CRC16CTRL = 0x0002; while (len--) { CRC->CRC16DAT = *pdat++; } crc_16 = CRC->CRC16D; rt_mutex_release(crc_mutex); return crc_16; } ``` 2022-04-01 **发现问题,这个数据太迷惑了,以上代码有问题,请不要使用** ![image.png](https://oss-club.rt-thread.org/uploads/20220401/10a9a3bde81dec8321a991446da1b33f.png) 2022-04-06 在国民技术王工的帮助之下,终于可以正确的使用CRC硬件进行modbus的CRC16计算了. ``` uint16_t rt_reverse_16(uint16_t dat) { uint16_t x = dat; x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1)); x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2)); x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4)); return ((x >> 8) | (x << 8)); } uint16_t rt_hw_get_crc16(const uint8_t *pdat, uint16_t len) { uint16_t crc_16 = 0; rt_mutex_take(crc_mutex, RT_WAITING_FOREVER); CRC->CRC16CTRL = CRC16_LSB | CRC16_CLR; CRC->CRC16D = 0xFFFF; CRC->LRC = 0; while (len--) { CRC->CRC16DAT = *pdat++; } crc_16 = CRC->CRC16D; rt_mutex_release(crc_mutex); crc_16 = rt_reverse_16(crc_16); return crc_16; } ``` 这么搞之后就是modbus的CRC16啦
3
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
wlof
这个家伙不懒,什么也没写
文章
16
回答
64
被采纳
0
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部