以前都是使用軟件CRC,浪費(fèi)計(jì)算時(shí)間,有硬件CRC不用,真是可惜。本次使用硬件CRC對(duì)ModBus的CRC進(jìn)行計(jì)算,測(cè)試時(shí),遇到點(diǎn)問(wèn)題,自帶的庫(kù)文件里面,把方法寫死了,結(jié)果和Modubs的對(duì)不上。
文檔上說(shuō)的公式和modbus是一樣的,那么就有可能是初值與異或值不同造成的,先相信硬件不會(huì)出錯(cuò)嘛。
自帶的crc庫(kù)也不要用了,一共沒(méi)有用到3個(gè)寄存器,直接搞。
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);
}
當(dāng)然初始化時(shí)鐘是要加上的啦
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE);
就是這么簡(jiǎn)單,再不用擔(dān)心寫錯(cuò)CRC代碼了,肯定是算錯(cuò)了,硬件不會(huì)錯(cuò)
給它上個(gè)鎖,避免被搶占打斷后,計(jì)算出錯(cuò)。
#include
#include
#include
#include
/* 指向互斥量的指針 /
static rt_mutex_t crc_mutex = RT_NULL;
void hw_crc_init(void)
{
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE);
/ 創(chuàng)建一個(gè)動(dòng)態(tài)互斥量 */
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;
}
發(fā)現(xiàn)問(wèn)題,這個(gè)數(shù)據(jù)太迷惑了,以上代碼有問(wèn)題,請(qǐng)不要使用
終于可以正確的使用CRC硬件進(jìn)行modbus的CRC16計(jì)算了.
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啦。
-
寄存器
+關(guān)注
關(guān)注
31文章
5434瀏覽量
124474 -
MODBUS
+關(guān)注
關(guān)注
28文章
2121瀏覽量
79567 -
CRC校驗(yàn)
+關(guān)注
關(guān)注
0文章
84瀏覽量
15604
發(fā)布評(píng)論請(qǐng)先 登錄
用STM32L05x的CRC模塊做modbus CRC16計(jì)算,結(jié)果不正確是為什么?
modbus_rtu crc16校驗(yàn)
CRC16和CRC8校驗(yàn)計(jì)算,已經(jīng)驗(yàn)證算法正確
Labview CRC16(XMODEN)程序
ModBus CRC16校驗(yàn)碼學(xué)習(xí)筆記(附手稿)精選資料分享
CRC16的計(jì)算校驗(yàn)碼的方式有哪幾種?
agile_modbus遇到一個(gè)rtu主機(jī)要求crc16值要swap時(shí)如何處理呢
CRYPTO中的CRC16計(jì)算結(jié)果有問(wèn)題怎么解決
crc16計(jì)算器 (計(jì)算工具)

CRC16校驗(yàn)碼計(jì)算器v1.2版應(yīng)用程序免費(fèi)下載

評(píng)論