C语言串口通信R8T8,工控人必须掌握 | 串口通讯与MODBUS协议介绍

(1).CRC16算法:

INT16U CRC16(INT8U *puchMsg, INT16U usDataLen)

{

INT8U uchCRCHi = 0xFF;               /*高CRC字节初始化*/

INT8U uchCRCLo = 0xFF;               /*低CRC字节初始化*/

INT8U uIndex;                        /* CRC循环中的索引*/

while (usDataLen--)                  /*传输消息缓冲区*/

{

uIndex = uchCRCHi ^*puchMsg++;   /*计算CRC */

uchCRCHi = uchCRCLo ^auchCRCHi[uIndex];

uchCRCLo = auchCRCLo[uIndex];

}

return (uchCRCHi << 8 |uchCRCLo);

}

(2)发送命令程序

本例程以Mag64为核心CPU

void Read_InPut(INT8U Addr,INT16UStart,INT16U Len)

{

INT16U CRC;

SendBuffer_485[0]=Addr;                  //设备地址

SendBuffer_485[1]=0x04;                  //modbus功能码

SendBuffer_485[2]=Start/256;             //Start为寄存器地址

SendBuffer_485[3]=Start%256;

SendBuffer_485[4]=Len/256;               //Len为读取寄存器长度

SendBuffer_485[5]=Len%256;

CRC=CRC16(SendBuffer_485,6);

SendBuffer_485[6]=CRC/256;               //CRC校验高位

SendBuffer_485[7]=CRC%256;               //CRC校验低位

R485_OUT;                                //使能RS485发送

SendLen_485=8;

SendNum_485=0;

CloseINT0();                            //关闭串口接受中断

UCSR0B |= BIT(UDRIE0);                  //打开串口发送中断

}

(3)返回数据解析

数据接收使用串口中断,ReceivedBuffer_485为接收数据组,ReceivedNum_485为接收到数据长度,ReceivedFlag_485接收到数据标志。函数float

Datasum(INT8UBYTE1, INT8U BYTE2, INT8U BYTE3, INT8U

BYTE4)把浮点数的4个字节转换为1个浮点数。

float Datasum(INT8U FloatByte1, INT8U FloatByte2,INT8U FloatByte3, INT8U FloatByte4)

{

float aa;

union IntTOFP

{

FP32       F32;

INT8U      T8[4];

};

union IntTOFPaa;

aa.T8[0] = FloatByte1;

aa.T8[1] = FloatByte2;

aa.T8[2] = FloatByte3;

aa.T8[3] = FloatByte4;

return aa;

}

void Read_Lmag(INT8U Ad)

{

INT8U  i,j;

INT8U  Num1[10],BIT;

INT16UCRC1,CRC2;

FP32  Flow;                                 //aaa为瞬时流量数值

ReceivedFlag_485=1;

Open_Time1_Ms5(20);

Read_InPut(Ad,0x1010,2);                   //发送设备地址、寄存器地址、寄存器长度

while(ReceivedFlag_485);                   //等待接收结束

if((ReceivedNum_485==9)&&(ReceivedBuffer_485[0]==Ad))    //判断数据是否正确

{

CRC1=CRC16(ReceivedBuffer_485,7);

CRC2=ReceivedBuffer_485[7]*256+ReceivedBuffer_485[8];

if(CRC1==CRC2)

{//转换数据为浮点数

Flow= Datasum(ReceivedBuffer_485[6], ReceivedBuffer_485[5], ReceivedBuffer_485[4] ,ReceivedBuffer_485[3]);

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值