Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Modbus
RT-Thread一般讨论
国民技术_N32G45x
N32G45x 硬件CRC 计算Modbus的CRC16【已修正问题】
发布于 2022-03-30 18:54:33 浏览:1332
订阅该版
[tocm] ### N32G45x 硬件CRC 计算Modbus的CRC16 以前都是使用软件CRC,浪费计算时间,有硬件CRC不用,真是可惜。本次使用硬件CRC对ModBus的CRC进行计算,测试时,遇到点问题,自带的库文件里面,把方法写死了,结果和Modubs的对不上。   文档上说的公式和modbus是一样的,那么就有可能是初值与异或值不同造成的,先相信硬件不会出错嘛。  自带的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 **发现问题,这个数据太迷惑了,以上代码有问题,请不要使用**  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
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
FAL
RTC
rt-smart
I2C_IIC
cubemx
UART
ota在线升级
ESP8266
WIZnet_W5500
BSP
PWM
flash
packages_软件包
freemodbus
潘多拉开发板_Pandora
GD32
ADC
定时器
编译报错
flashDB
keil_MDK
socket
中断
rt_mq_消息队列_msg_queue
Debug
ulog
SFUD
msh
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
6
个答案
3
次被采纳
xiaorui
3
个答案
1
次被采纳
yans
2
个答案
1
次被采纳
tjrong
1
个答案
1
次被采纳
miandian_7
1
个答案
1
次被采纳
本月文章贡献
Pai同学
8
篇文章
11
次点赞
Rick98
3
篇文章
10
次点赞
RTT_逍遥
2
篇文章
10
次点赞
加缪
1
篇文章
2
次点赞
河南理工大学恁带劲儿
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部