梦见梅花鹿是什么预兆| 螳螂吃什么| dell是什么牌子的电脑| 乔丹是什么牌子| 周瑜是什么生肖| 女人喝红酒有什么好处| 长期手淫会有什么危害| 馕是什么意思| 烛光晚餐是什么意思| 抗结剂对人有什么伤害| 翩跹是什么意思| 每天坚持跑步有什么好处| 颞下颌关节炎吃什么药| 子午是什么时间| k1是什么意思| 沙发客是什么意思| 数字五行属什么| ich是什么意思| 程门立雪什么意思| 牛和什么生肖最配| 桂皮是什么| 11月16号是什么星座| 身上起红疙瘩是什么原因| 董事总经理是什么职位| 走水是什么意思| 脚肿腿肿是什么原因引起的| 做爱时间短吃什么药| 腰扭伤吃什么药| jet是什么意思| 为什么玉镯不能戴左手| 纳豆是什么豆| 肝火旺吃什么药| 有趣的什么填空| 肛门塞什么东西最舒服| 蒸鱼豉油什么时候放| 两女一杯是什么| 肾钙化是什么意思| 心律不齐吃什么药效果好| 油为什么会浮在水面上| 脚筋疼是什么原因| 为什么身上会起小红点| 说风就是雨什么意思| 嗝什么意思| 黄片是什么| r是什么牌子衣服| SEX是什么| 蜈蚣怕什么| 铁扫帚命是什么意思| 老汉推车是什么姿势| 凝血高是什么原因| 逆钟向转位是什么意思| 黄发指什么| 刘备的马叫什么名字| 为什么一吃饭就拉肚子| 孕妇为什么不能参加婚礼| 腿容易麻是什么原因| 世界上最大的湖泊是什么湖| 颈椎用什么字母表示| 敬谢不敏是什么意思| 为什么会有流星雨| 女性的排卵期是什么时候| 北京大学什么专业最好| 什么是热病| 先父什么意思| 黄桃什么时候上市| levi是什么意思| 抛锚是什么意思| 器质性心脏病是什么意思| 晚上扫地有什么说法| 珂润属于什么档次| 夜盲症缺什么| 石敢当是什么神| 神经元特异性烯醇化酶是什么意思| 长寿花用什么肥料最好| 肾亏是什么意思| 12月出生是什么星座| 三途苦是指的什么| 4ever是什么意思| 什么不什么什么| 喜气洋洋是什么意思| 什么是pin| 做包子用什么面粉好| 抑郁症什么症状| 大鱼际疼是什么原因| 头孢克肟和头孢拉定有什么区别| 吃什么水果对嗓子好| 白带有血丝是什么原因| 为什么崴脚了休息一晚脚更疼| 愚痴是什么意思| 遣返回国有什么后果| 湖南有什么好玩的地方| 身上发冷是什么原因| 海带属于什么类| 艾灸什么时候做最好| 子宫肌瘤有什么症状表现| 氡气是什么| 泰迪狗长什么样子| 人生没有什么不可放下| 冰箱什么牌子好又省电质量又好| 及时是什么意思| 宝宝大便酸臭味是什么原因| 长沙有什么玩的| xo是什么酒| 牙出血是什么病的前兆| 口子念什么| 什么是卤水| a型血的人是什么性格| 低密度脂蛋白低是什么原因| 胸口隐隐作痛挂什么科| 男人性功能太强是什么原因| 框框是什么意思| apl是什么意思| lgbtq是什么意思| 巴雷特是什么| 女人练瑜伽有什么好处| 婴儿湿疹用什么药膏| ab型血和o型血生的孩子是什么血型| 端午节吃什么菜呢| 什么叫知己| 肝阴虚吃什么药| 今年农历是什么年| 小舅子是什么意思| 白头发是缺什么维生素| 趴在桌子上睡觉有什么坏处| 现在最好的避孕方法是什么| 梦见被熊追是什么意思| 怀孕三个月吃什么对胎儿好| 酸菜鱼用什么鱼做好吃| 什么的月光| 头发麻是什么病的前兆| 什么是滑膜炎| 下面有炎症用什么药| mds是什么| 经常手淫对身体有什么危害| 书的五行属性是什么| 护理部主任是什么级别| 九月十号什么星座| 这是为什么| ana医学上是什么意思| 梦见娃娃是什么意思| 盆腔炎吃什么药有效| 什么是修养| 直径是什么意思| 看淋巴挂什么科室| 孕妇梦见掉牙齿是什么意思| 垂问是什么意思| 感恩节是什么时候| p代表什么意思| 鬼门关是什么意思| 乾隆为什么不喜欢雍正| 白色虫子是什么虫图片| 什么动物最安静| 十月十三是什么星座| 医学ns是什么意思| 左上腹疼是什么原因| 9月28日什么星座| 乳糖酶是什么东西| 什么叫小微企业| 吃了西瓜不能吃什么| 县纪委副书记什么级别| 阴婚是什么意思| 酸碱度偏低是什么原因| 月经为什么来了一点又不来了| 鲁肃的性格特点是什么| 女人血稠吃什么食物好| 头发长的慢是什么原因| 杏色配什么颜色好看| 学兽医需要什么学历| 自五行属什么| 强势是什么意思| 全身骨显像是查什么的| 洋参片泡水喝有什么功效| 细胞结构包括什么| 什么口服液补血补气最好| 92年属猴的是什么命| 农历六月十七是什么日子| 吃什么可以排出霉菌| 乌鸦长什么样| dic是什么病的简称| 脾胃虚寒吃什么中成药| 流苏是什么东西| 热浪是什么意思| 苋菜长什么样| 一眼万年是什么意思| 为什么有的人招蚊子| 咀嚼食用是什么意思| 外阴炎什么症状| 血府逐瘀丸治什么病| 1948年属什么| 白目是什么意思| 为什么筋膜炎一躺下才会疼| 曾舜晞是什么星座| 旖旎风光是什么意思| 什么空调最省电| 什么样的伤口需要打破伤风针| 什么是篮球基本功| 乳腺结节应该挂什么科| 蛇头疮用什么治疗最快| 烧心是什么感觉| 频次是什么意思| 英姿的动物是什么生肖| 一张纸可以做什么| 逍遥丸是治什么的| 潜血阳性是什么意思| 绿幽灵五行属什么| 脚上长鸡眼去医院挂什么科| 什么叫水印| 离婚要什么手续| tommyhilfiger什么牌子| 正骨有什么好处和坏处| 黄体酮吃了有什么副作用| 脑白质病变吃什么药| butter是什么意思| 梦到自己头发白了是什么意思| 意欲何为是什么意思| 脂肪是什么意思| 什么叫双向情感障碍| 潘多拉魔盒是什么意思| 双花红棍什么意思| 牛肉丸子配什么菜好吃| 小孩下面痒用什么药| 血淋是什么意思| 月经量多是什么原因| 电器发生火灾用什么灭火器| 挂什么科| 湿肺是什么意思| 大连有什么好吃的| 麻蛇是什么蛇| 脑瘤是什么原因引起的| 孟买血型是什么意思| 孩子肚子有虫子有什么症状| 胸膜炎有什么症状| 做b超能查出什么| 查艾滋病挂什么科| 沙门氏菌是什么| 效果是什么意思| 摸头是什么意思| 夕阳什么意思| 分泌物发黄是什么原因| 蚁后长什么样| 拍证件照穿什么衣服| 健身rm是什么意思| 孩子结膜炎用什么眼药水| 海瓜子是什么| camouflage什么意思| 丝状疣用什么药| 属蛇的是什么星座| 补牙属于口腔什么科| otg线是什么| 头皮发痒是什么原因引起的| 龟头炎用什么药膏好| 二氧化钛是什么东西| 耐药性什么意思| 什么是用户名| 1993年属鸡是什么命| 跳蚤咬了擦什么药最好| 节律是什么意思| 什么是龟头炎| 口气臭吃什么能改善| 在野是什么意思| 炒菜用什么油比较好| 来褐色分泌物是什么原因| 五行属火适合什么行业| 1959年是什么年| 百度
这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 ? 论坛首页 ? 企业专区 ? TI ? 基于MSPM0L1306的MODBUS-RTU协议通讯实验

共2条 1/1 1 跳转至

基于MSPM0L1306的MODBUS-RTU协议通讯实验

菜鸟
2025-08-04 16:35:10   被打赏 120 分(兑奖)     打赏
百度 超过58%的网友表示,会牺牲睡眠时间完成最重要的工作,不得不说,大家真的都很拼!  “特困生”类型三:熬夜学习无法自拔  有关小学生熬夜写作业之类的话题,相信大家并不陌生。

一、试验介绍

1. 目的:利用485模块进行中间转发,测试MSPM0L1306MODBUS通讯功能,该功能基于TTL硬件层协议编写;

2. 过程:MSPM0L1306采用双串口内部通讯方式做外部转接,程序部分结合CDSN网站及育某视频代码,参考TORRI YANGd的计时器部分,完成软件MODBUS协议软件层协议的编写;

3. 代码编写:MODBUS协议部分围绕基本的解码、打包功能、CRC校验功能进行编写,未做其他处理,如设备地址校验等未做处理。

二、硬件材料及验证

1. 基本材料

开发板:MSPM0L1306;(厂商:德州仪器;)

转接模块:TTL485模块2个;(厂商:国星电子;型号:SN75176

IMU模块:基于485MODBUS通讯IMU模块;(厂商:广运电子;型号:GY-485-6DOF

导线部分:杜邦闲若干;

2. 接线方式

新建 PPTX 演示文稿_01(1).png

 

其中MSPM0L1306的串口收发口分别是:

UART0(接PC485转接模块):PA23TX-PA22RX);

UART1(接IMU485转接模块):PA10TX-PA13RX);

3. 验证软件

A. 串口调试助手(野人家园V5.0.3.16 免费版)

串口调试助手.png

 

B. MODBUS调试精灵()

 

MODBUS精灵.png


4. 程序流程图

流程图.png

三、软件代码部分

#include "ti_msp_dl_config.h"

#include <stdint.h>

#include<modbus.h>

 

#define Buffer_SIZE 8

uint8_t length;

unsigned char txBuffer[Buffer_SIZE];

unsigned char rxBuffer[Buffer_SIZE];//unsigned char数组声明并初始化,所有元素赋值为0,防止后边调用后,数值被覆盖;

 

void sendString_UART0(char txBuffer,int length);

void sendString_UART1(char txBuffer,int length);

 

//Modbus初始化

uint8_t ModbusInit(void);

//打包数据

uint8_t ModbusPackData(stc_modbus *pstcModbus);

//解析数据

uint8_t ModbusParseData(stc_modbus *pstcModbus);

//CRC查表法计算

uint16_t CRC16table(uint8_t *ptr, uint16_t len);

stc_modbus pstcModbus;//把stc_modbus重命名为*pstcModbus;

 

int main(void)

{

    SYSCFG_DL_init();

    NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);

    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);

 

    NVIC_ClearPendingIRQ(UART_1_INST_INT_IRQN);

    NVIC_EnableIRQ(UART_1_INST_INT_IRQN);

 

    while (1)

    {

    }

}



void UART_0_INST_IRQHandler(void)

{

    switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {

        case DL_UART_MAIN_IIDX_RX:

            if(length<Buffer_SIZE)

            {

                rxBuffer[length]=DL_UART_receiveDataBlocking(UART_0_INST);//串口0接到数据存储到给缓冲区;

                pstcModbus.frame[length]=rxBuffer[length];

                length++;

            }

            length=0;

          //sendString_UART1(*rxBuffer,Buffer_SIZE);  

            ModbusParseData(&pstcModbus);//解析函数,对接收到的串口数据进行解析;调用此种函数方法,用&;                          

            NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);

            ModbusPackData(&pstcModbus);//打包函数

            sendString_UART1(*pstcModbus.frame,Buffer_SIZE);

            DL_TimerG_startCounter(TIMER_0_INST);              

            break;

        default:

            break;

    }

}

 

void UART_1_INST_IRQHandler(void)

{

    switch (DL_UART_Main_getPendingInterrupt(UART_1_INST)) {

        case DL_UART_MAIN_IIDX_RX:

            if(length<Buffer_SIZE)

            {

                rxBuffer[length]=DL_UART_receiveDataBlocking(UART_1_INST);//串口1接到数据存储到给缓冲区;

                pstcModbus.frame[length]=rxBuffer[length];

                length++;

            }

            length=0;

          //sendString_UART0(*rxBuffer,Buffer_SIZE);  

            ModbusParseData(&pstcModbus);//解析函数,对接收到的串口数据进行解析;调用此种函数方法,用&;                          

            NVIC_EnableIRQ(TIMER_1_INST_INT_IRQN);

            ModbusPackData(&pstcModbus);//打包函数

            sendString_UART0(*pstcModbus.frame,Buffer_SIZE);

           // delay_cycles(160000);

           // DL_GPIO_togglePins(GPIO_LEDS_PORT,

           // GPIO_LEDS_LED_0_PIN  | GPIO_LEDS_LED_26_PIN );

            DL_TimerG_startCounter(TIMER_1_INST);    

            break;

        default:

            break;

    }

}


//定义串口0发送函数,参数包括字符串缓存区,及大小

void sendString_UART0(char txBuffer,int length)

{

 

       if(length<=Buffer_SIZE)

       {

           DL_UART_Main_transmitDataBlocking(UART_0_INST, txBuffer);

       }

       else

       {

            while (DL_UART_Main_isBusy(UART_0_INST))

            {

                DL_UART_Main_transmitDataBlocking(UART_0_INST, txBuffer);

            }

       }

}

 

//定义串口1发送函数,参数包括字符串缓存区,及大小

void sendString_UART1(char txBuffer,int length)

{

 

       if(length<=Buffer_SIZE)

       {

           DL_UART_Main_transmitDataBlocking(UART_1_INST, txBuffer);

       }

       else

       {

            while (DL_UART_Main_isBusy(UART_1_INST))

            {

                DL_UART_Main_transmitDataBlocking(UART_1_INST, txBuffer);

            }

       }

}

 

//计时器0中断函数,其中计时8ms后重新进行计时;

void TIMER_0_INST_IRQHandler(void)

{

    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {

        case DL_TIMER_IIDX_ZERO:

            delay_cycles(10);

            break;

        default:

            break;

    }

}

//计时器1中断函数,其中计时8ms后重新进行计时;

void TIMER_1_INST_IRQHandler(void)

{

    switch (DL_TimerG_getPendingInterrupt(TIMER_1_INST)) {

        case DL_TIMER_IIDX_ZERO:

            delay_cycles(10);

            break;

        default:

            break;

    }

}

 

//打包数据,将pstcModbus结构体内相关元素根据不同功能码帧结构存入发送帧缓存,并加CRC校验

//函数运行完毕后可根据pstcModbus.frame_len直接调用串口发送函数发送指定字节数的帧数据

uint8_t ModbusPackData(stc_modbus *pstcModbus)

{

    uint16_t i   =   0;

    uint16_t crc    =   0;

    //将地址、功能码、操作寄存器地址或首地址存入帧,任何功能码此部分相同

    pstcModbus->frame[0]    =   pstcModbus->address;

    pstcModbus->frame[1]    =   pstcModbus->function;

    pstcModbus->frame[2]    =   (pstcModbus->reg_addr >> 8) & 0xFF;

    pstcModbus->frame[3]    =   pstcModbus->reg_addr & 0xFF;

    //判断功能码,并根据不同功能码进行处理

    switch (pstcModbus->function) {

        //读线圈/离散输入/保持寄存器/输入寄存器帧格式在寄存器地址或首地址后均是读取数量、CRC,故可以将case条件合并

        case READ_COIL_REG:

        case READ_DIS_INPUT_REG:

        case READ_HOLD_REG:

        case READ_INPUT_REG:

            //存放读取数量

            pstcModbus->frame[4]    =   (pstcModbus->reg_num >> 8) & 0xFF;

            pstcModbus->frame[5]    =   pstcModbus->reg_num & 0xFF;

            //CRC计算

            crc    =   CRC16table(pstcModbus->frame, 6);

            //存放CRC校验码

            pstcModbus->frame[6]    =   (crc >> 8) & 0xFF;

            pstcModbus->frame[7]    =   crc & 0xFF;

            //帧长度

            pstcModbus->frame_len    =   8;

            break;

        //写单个寄存器线圈/保持寄存器帧格式在寄存器地址后均是写入数据、CRC,故可以将case条件合并

        case WRITE_SIN_COIL_REG:

        case WRITE_SIN_HOLD_REG:

            //存入要写入寄存器的数据

            pstcModbus->frame[4]    =   pstcModbus->data[0];

            pstcModbus->frame[5]    =   pstcModbus->data[1];

            //CRC计算

            crc    =   CRC16table(pstcModbus->frame, 6);

            //存放CRC校验码

            pstcModbus->frame[6]    =   (crc >> 8) & 0xFF;

            pstcModbus->frame[7]    =   crc & 0xFF;

            //帧长度

            pstcModbus->frame_len    =   8;

            break;

        //写多个线圈/保持寄存器帧格式在寄存器地址后均是写入寄存器数量、写入数据、CRC,故可以将case条件合并

        case WRITE_MULT_COIL_REG:

        case WRITE_MULT_HOLD_REG:

            //存放写入寄存器数量

            pstcModbus->frame[4]    =   (pstcModbus->reg_num >> 8) & 0xFF;

            pstcModbus->frame[5]    =   pstcModbus->reg_num & 0xFF;

            //存放写入数据字节数

            pstcModbus->frame[6]    =   pstcModbus->byte_num;

            //存放写入数据

            for(i=0;i<pstcModbus->byte_num;i++)

                pstcModbus->frame[7+i]    =   pstcModbus->data[i];

            //CRC计算

            crc    =   CRC16table(pstcModbus->frame, pstcModbus->byte_num+7);

            //存放CRC校验码

            pstcModbus->frame[pstcModbus->byte_num+7]    =   (crc >> 8) & 0xFF;

            pstcModbus->frame[pstcModbus->byte_num+8]    =   crc & 0xFF;

            //帧长度

            pstcModbus->frame_len    =   pstcModbus->byte_num+9;

            break;

        default:

            break;

    }

    return SUCCESS;

}

 

//解析数据,将帧缓存中的数据解析到pstcModbus结构体相关元素中

//帧缓存数据可以来自串口接收

//此函数运行完毕后可根据pstcModbus结构体内的功能码读取结构体内有用的数据

uint8_t ModbusParseData(stc_modbus *pstcModbus)

{

    uint8_t sta    =   ERROR;

    uint16_t i   =   0;

    uint16_t crc    =   0;

    //将帧缓存中不同功能码共有的元素解析到pstcModbus结构体对应元素:设备地址、功能码

    pstcModbus->address    =   pstcModbus->frame[0];

    pstcModbus->function   =   pstcModbus->frame[1];

    //判断功能码,并根据不同功能码进行处理

    switch (pstcModbus->function) {

        //读线圈/离散输入/保持寄存器/输入寄存器帧格式在功能码后均是返回的读取字节数量、返回的读取数据、CRC,故可以将case条件合并

        case READ_COIL_REG:

        case READ_DIS_INPUT_REG:

        case READ_HOLD_REG:

        case READ_INPUT_REG:

            //存放接收帧中的返回数据域字节数量

            pstcModbus->byte_num    =   pstcModbus->frame[2];

            //将接收帧中的返回数据域数据存入 pstcModbus->data[i]

            for(i=0;i<pstcModbus->byte_num;i++)

                pstcModbus->data[i]    =   pstcModbus->frame[3+i];

            //根据有原始帧数据进行CRC计算并与接收的CRC进行验证

            crc    =   ((pstcModbus->frame[pstcModbus->byte_num+3]&0x00FF)  <<8);

            crc    |=  (pstcModbus->frame[pstcModbus->byte_num+4]&0x00FF);

            pstcModbus->frame_len    =   pstcModbus->byte_num;

            if(crc == CRC16table(pstcModbus->frame, pstcModbus->byte_num+3))

                sta    =   SUCCESS;

            break;

        //写单个寄存器线圈/保持寄存器帧格式在功能码后均是写入寄存器地址、写入的数据、CRC,故可以将case条件合并

        case WRITE_SIN_COIL_REG:

        case WRITE_SIN_HOLD_REG:

            //存放接收帧中的寄存器地址、数据域数据

            pstcModbus->address    =   ((pstcModbus->frame[2]&0x00FF) <<8);

            pstcModbus->address    |=  (pstcModbus->frame[3]&0x00FF);

            pstcModbus->data[0]    =   pstcModbus->frame[4];

            pstcModbus->data[1]    =   pstcModbus->frame[5];

            pstcModbus->frame_len    =   2;

            //根据有原始帧数据进行CRC计算并与接收的CRC进行验证

            crc    =   ((pstcModbus->frame[6]&0x00FF)  <<8);

            crc    |=  (pstcModbus->frame[7]&0x00FF);

            if(crc == CRC16table(pstcModbus->frame, 6))

                sta    =   SUCCESS;

            break;

        //写多个线圈/保持寄存器帧格式在功能码后均是写入寄存器地址、操作的寄存器数量、CRC,故可以将case条件合并

         case WRITE_MULT_COIL_REG:

         case WRITE_MULT_HOLD_REG:

            //存放接收帧中的寄存器地址、操作的寄存器数量

            pstcModbus->address    =   ((pstcModbus->frame[2]&0x00FF) <<8);

            pstcModbus->address    |=  (pstcModbus->frame[3]&0x00FF);

            pstcModbus->reg_num    =   ((pstcModbus->frame[4]&0x00FF) <<8);

            pstcModbus->reg_num    |=  (pstcModbus->frame[5]&0x00FF);

            //根据有原始帧数据进行CRC计算并与接收的CRC进行验证

            crc    =   ((pstcModbus->frame[6]&0x00FF)  <<8);

            crc    |=  (pstcModbus->frame[7]&0x00FF);

            if(crc == CRC16table(pstcModbus->frame, 6))

                sta    =   SUCCESS;

            break;

        default:

            break;

    }

    return sta;

}

 

/* CRC高字节表 */

const static uint8_t crctableh[] = {

    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,

    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,

    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,

    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

    0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,

    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

    0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,

    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

    0x40

};

/* CRC低字节表 */

const static uint8_t crctablel[] = {

    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,

    0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,

    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,

    0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,

    0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,

    0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,

    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,

    0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,

    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,

    0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,

    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,

    0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,

    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,

    0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,

    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,

    0x40

};

//CRC查表函数,返回CRC-16校验码低字节在前

uint16_t CRC16table(uint8_t *ptr, uint16_t len)

{

    uint8_t crch = 0xFF;

    uint8_t crcl = 0xFF;

    uint16_t index;

    while (len--)

    {

        index = crcl ^ *ptr++;

        crcl = crch ^ crctableh[index];

        crch = crctablel[index];

    }

    return ((uint16_t)(crch | crcl << 8));

}

四、测试照片


图片4.png


图片5.png

empty_LP_MSPM0L1306_nortos_ticlang.zip


专家
2025-08-04 20:32:13     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]
行政工作主要负责什么 人参泡酒有什么功效和作用 股票里xd是什么意思 acer是什么牌子 女宝胶囊的作用和功效是什么
刀枪不入是什么生肖 乳环是什么 孕妇适合喝什么茶 强身之道的强是什么意思 luky是什么意思
supor是什么品牌 心悸气短是什么症状 拉谷谷女装什么档次的 小腿内侧是什么经络 脸红什么
白虎什么意思 薄荷有什么功效 肛门痛是什么原因 1999年属什么生肖 明矾和白矾有什么区别
小孩咳嗽不能吃什么食物baiqunet.com 口淡无味是什么原因hcv8jop1ns5r.cn 云为什么是白色的hcv8jop2ns5r.cn 腻是什么意思xjhesheng.com joseph是什么意思hcv8jop9ns9r.cn
安宫牛黄丸什么时候吃hcv9jop7ns4r.cn 海淘是什么意思啊hcv8jop9ns2r.cn 鸿运当头是什么意思hcv7jop4ns8r.cn 喉咙发炎吃什么水果好hcv9jop7ns3r.cn 肺部ct能查出什么病jinxinzhichuang.com
白砂糖和冰糖有什么区别hcv9jop0ns1r.cn 黑曜石是什么材质hcv7jop7ns3r.cn 陈皮是什么hcv8jop4ns8r.cn 颈椎曲度变直有什么症状96micro.com 替拉依是什么药hcv9jop3ns4r.cn
09年的牛是什么命hcv7jop9ns0r.cn 尼泊尔是什么人种hcv9jop4ns4r.cn 做大生化挂什么科hcv9jop0ns4r.cn 咳嗽买什么药hcv8jop9ns7r.cn 佳偶天成是什么意思hcv8jop1ns2r.cn
百度