Ai
1 Star 0 Fork 4

eleluq1234/TCP协议栈

forked from 邵温财/TCP协议栈 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
modbus_slave.c 22.39 KB
一键复制 编辑 原始数据 按行查看 历史
邵温财 提交于 2021-07-13 16:22 +08:00 . 完成modbustcp设备测点转发
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
#include "modbus_slave.h"
#include "CRC.h"
#define BIG_ENDIAN (0)
#define LITTLE_ENDIAN (1)
static int mode = 0;
/*********************************************************************************************************
*Modbus功能码01处理程序 读输出开关量
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码+ 数据字节数 + 数据 + CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_01_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
uint16_t calCRC;
uint16_t RegNum;
uint16_t ByteNum;
uint16_t i,k;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8) | pDc->RX_BUFF[3];//获取寄存器起始地址
RegNum = (((uint16_t)pDc->RX_BUFF[4])<<8) | pDc->RX_BUFF[5];//获取寄存器数量 等价于获取bit位数
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1];
ByteNum = RegNum/8;//字节数
if(RegNum%8) ByteNum += 1;//如果位数还有余数,则字节数+1
pDc->TX_BUFF[2] = ByteNum;//返回要读取的字节数
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
for(i=0; i<RegNum;)
{
pDc->TX_BUFF[3+i/8] = itemMap[k].data[(startRegAddr-itemMap[k].start_addr)/8];
if(i+8 > RegNum)
{
pDc->TX_BUFF[3+i/8] &= (0xff >> (RegNum - i) );
}
if((startRegAddr-itemMap[k].start_addr)/8 + 1 >= itemMap[k].size)
{
k++;
}
startRegAddr = startRegAddr+8;
i = i+8;
}
calCRC=CRC_Compute(pDc->TX_BUFF,ByteNum+3);
pDc->TX_BUFF[ByteNum+3] = calCRC&0xFF;
pDc->TX_BUFF[ByteNum+4] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,ByteNum+5);
}
/*********************************************************************************************************
*Modbus功能码02处理程序 读输入开关量
*收到:设备地址+功能码 +起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码 + 数据字节数 + 数据 + CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_02_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
Modbus_01_Solve(pDc,itemMap,itemNum);
}
/*********************************************************************************************************
*Modbus功能码03发送程序 读保持寄存器
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码 + 数据字节数N + N个字节的数据 + CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_03_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
uint16_t calCRC;
uint16_t RegNum;
uint8_t i,k;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8) | pDc->RX_BUFF[3];//获取寄存器起始地址
RegNum= (((uint16_t)pDc->RX_BUFF[4])<<8) | pDc->RX_BUFF[5];//获取寄存器数量
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
pDc->TX_BUFF[0]=pDc->RX_BUFF[0];
pDc->TX_BUFF[1]=pDc->RX_BUFF[1];
pDc->TX_BUFF[2]=RegNum*2; //寄存器数是以字为单位,返回的是字节数 所以*2
for(i=0; i<RegNum; i++)
{
if(mode == LITTLE_ENDIAN && itemMap[k].auto_convert == 1)
{
pDc->TX_BUFF[3+i*2] = itemMap[k].data[itemMap[k].size - 1 - (startRegAddr-itemMap[k].start_addr)*2];
if((startRegAddr-itemMap[k].start_addr)*2+1 >= itemMap[k].size)
{
k++;
startRegAddr++;
continue;
}
pDc->TX_BUFF[4+i*2] = itemMap[k].data[itemMap[k].size - 1 - ((startRegAddr-itemMap[k].start_addr)*2+1)];
}
else
{
pDc->TX_BUFF[3+i*2] = itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2];
if((startRegAddr-itemMap[k].start_addr)*2+1 >= itemMap[k].size)
{
k++;
startRegAddr++;
continue;
}
pDc->TX_BUFF[4+i*2] = itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2+1];
}
if((startRegAddr-itemMap[k].start_addr)*2+2 >= itemMap[k].size)
{
k++;
}
startRegAddr++;
}
calCRC = CRC_Compute(pDc->TX_BUFF,RegNum*2+3);
pDc->TX_BUFF[RegNum*2+3] = calCRC&0xFF;
pDc->TX_BUFF[RegNum*2+4] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,RegNum*2+5);
}
/*********************************************************************************************************
*Modbus功能码04发送程序 读输入寄存器
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码 + 数据字节数N + N个字节的数据 + CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_04_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
Modbus_03_Solve(pDc,itemMap,itemNum);
}
/*********************************************************************************************************
*Modbus功能码05发送程序 写单个输出开关量
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+变更数据(高位)+变更数据(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码+起始地址(高位)+起始地址(低位)+变更数据(高位)+变更数据(低位)+CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_05_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
int k;
uint16_t calCRC;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8) | pDc->RX_BUFF[3];//获取寄存器起始地址
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
if((pDc->RX_BUFF[4]==0xFF)&&(pDc->RX_BUFF[5]==0x00))
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)/8] |= (0x01 << ((startRegAddr-itemMap[k].start_addr)%8));
}
else if((pDc->RX_BUFF[4]==0x00)&&(pDc->RX_BUFF[5]==0x00))
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)/8] &= (~(0x01 << ((startRegAddr-itemMap[k].start_addr)%8)));
}
else//变更数据不正确 因为输出值必须为0x0000 或者 0xff00
{
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1] | 0x80;
pDc->TX_BUFF[2] = 0x03; //异常码
calCRC=CRC_Compute(pDc->TX_BUFF,3);
pDc->TX_BUFF[3] = calCRC&0xFF;
pDc->TX_BUFF[4] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,5);
return;
}
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1];
pDc->TX_BUFF[2] = pDc->RX_BUFF[2];
pDc->TX_BUFF[3] = pDc->RX_BUFF[3];
pDc->TX_BUFF[4] = pDc->RX_BUFF[4];
pDc->TX_BUFF[5] = pDc->RX_BUFF[5];
calCRC=CRC_Compute(pDc->TX_BUFF,6);
pDc->TX_BUFF[6] = calCRC&0xFF;
pDc->TX_BUFF[7] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,8);
}
/*********************************************************************************************************
*Modbus功能码06发送程序 写单个保持寄存器
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+变更数据(高位)+变更数据(低位)+CRC(低位)+CRC(高位)
*发送:设备地址+功能码+起始地址(高位)+起始地址(低位)+变更数据(高位)+变更数据(低位)+CRC(低位)+CRC(高位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_06_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
int k;
uint16_t calCRC;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8)|pDc->RX_BUFF[3];//获取寄存器起始地址
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
if(mode == LITTLE_ENDIAN && itemMap[k].auto_convert == 1)
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2] = pDc->RX_BUFF[5];
if((startRegAddr-itemMap[k].start_addr)*2+1 < itemMap[k].size)
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2+1] = pDc->RX_BUFF[4];
}
}
else
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2] = pDc->RX_BUFF[4];
if((startRegAddr-itemMap[k].start_addr)*2+1 < itemMap[k].size)
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2+1] = pDc->RX_BUFF[5];
}
}
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1];
pDc->TX_BUFF[2] = pDc->RX_BUFF[2];
pDc->TX_BUFF[3] = pDc->RX_BUFF[3];
pDc->TX_BUFF[4] = pDc->RX_BUFF[4];
pDc->TX_BUFF[5] = pDc->RX_BUFF[5];
calCRC=CRC_Compute(pDc->TX_BUFF,6);
pDc->TX_BUFF[6] = calCRC&0xFF;
pDc->TX_BUFF[7] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,8);
}
/*********************************************************************************************************
*Modbus功能码15发送程序 写多个输出开关量
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)
* +字节数N + N个变更数据 + CRC(低位)+CRC(高位)
*发送:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_15_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
uint16_t calCRC;
uint16_t RegNum;
uint16_t startRegAddr;
uint16_t i,k;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8)|pDc->RX_BUFF[3];//获取寄存器起始地址
RegNum = (((uint16_t)pDc->RX_BUFF[4])<<8)|pDc->RX_BUFF[5];//获取寄存器数量
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
for(i=0; i<RegNum;)
{
if(i+8 > RegNum)
{
pDc->RX_BUFF[7+i/8] |= ((itemMap[k].data[(startRegAddr-itemMap[k].start_addr)/8] >> (RegNum - i) ) << (RegNum - i));
}
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)/8] = pDc->RX_BUFF[7+i/8];
if((startRegAddr-itemMap[k].start_addr)/8 + 1 >= itemMap[k].size)
{
k++;
}
startRegAddr = startRegAddr+8;
i = i+8;
}
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1];
pDc->TX_BUFF[2] = pDc->RX_BUFF[2];
pDc->TX_BUFF[3] = pDc->RX_BUFF[3];
pDc->TX_BUFF[4] = pDc->RX_BUFF[4];
pDc->TX_BUFF[5] = pDc->RX_BUFF[5];
calCRC=CRC_Compute(pDc->TX_BUFF,6);
pDc->TX_BUFF[6] = calCRC&0xFF;
pDc->TX_BUFF[7] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,8);
}
/*********************************************************************************************************
*Modbus功能码16发送程序 写多个保持寄存器
*收到:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)
* +字节数N + N/2个字变更数据(先高位再低位) + CRC(低位)+CRC(高位)
*发送:设备地址+功能码+起始地址(高位)+起始地址(低位)+寄存器数(高位)+寄存器数(低位)
*异常:设备地址+功能码|0x80 + 异常码 + CRC(低位)+CRC(高位)
**********************************************************************************************************/
static void Modbus_16_Solve(MODBUS_DC_TCM *pDc,ITEM_T *itemMap,uint16_t itemNum)
{
uint16_t calCRC;
uint8_t i,k;
uint16_t RegNum;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8) | pDc->RX_BUFF[3];//获取寄存器起始地址
RegNum = (((uint16_t)pDc->RX_BUFF[4])<<8) | pDc->RX_BUFF[5]; //获取寄存器数量
for(k=0; k<itemNum; k++)
{
if(startRegAddr >= itemMap[k].start_addr && startRegAddr < itemMap[k].end_addr)
{
break;
}
}
for(i=0; i<RegNum; i++)
{
if(mode == LITTLE_ENDIAN && itemMap[k].auto_convert == 1)
{
itemMap[k].data[itemMap[k].size - 1 - (startRegAddr-itemMap[k].start_addr)*2] = pDc->RX_BUFF[7+i*2];
if((startRegAddr-itemMap[k].start_addr)*2+1 >= itemMap[k].size)
{
k++;
startRegAddr++;
continue;
}
itemMap[k].data[itemMap[k].size - 1 - ((startRegAddr-itemMap[k].start_addr)*2+1)] = pDc->RX_BUFF[8+i*2];;
}
else
{
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2] = pDc->RX_BUFF[7+i*2];
if((startRegAddr-itemMap[k].start_addr)*2+1 >= itemMap[k].size)
{
k++;
startRegAddr++;
continue;
}
itemMap[k].data[(startRegAddr-itemMap[k].start_addr)*2+1] = pDc->RX_BUFF[8+i*2];
}
if((startRegAddr-itemMap[k].start_addr)*2+2 >= itemMap[k].size)
{
k++;
}
startRegAddr++;
}
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1];
pDc->TX_BUFF[2] = pDc->RX_BUFF[2];
pDc->TX_BUFF[3] = pDc->RX_BUFF[3];
pDc->TX_BUFF[4] = pDc->RX_BUFF[4];
pDc->TX_BUFF[5] = pDc->RX_BUFF[5];
calCRC=CRC_Compute(pDc->TX_BUFF,6);
pDc->TX_BUFF[6] = calCRC&0xFF;
pDc->TX_BUFF[7] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,8);
return;
}
static void Modbus_Parse_Hand(MODBUS_DC_TCM *pDc)
{
uint16_t calCRC;
uint8_t j;
uint16_t RegNum;
uint16_t startRegAddr;
startRegAddr = (((uint16_t)pDc->RX_BUFF[2])<<8) | pDc->RX_BUFF[3];//获取寄存器起始地址
RegNum = (((uint16_t)pDc->RX_BUFF[4])<<8) | pDc->RX_BUFF[5]; //获取寄存器数量
switch(pDc->RX_BUFF[1])//根据不同的功能码进行处理
{
case 05://写单个输出开关量
RegNum = 1;
case 01://读输出开关量
case 02://读输入开关量
case 15://写多个输出开关量
for(j=0; j<pDc->status_map_num; j++)
{
if(pDc->status_map_tab[j].fun_code != pDc->RX_BUFF[1])
{
continue;
}
if(startRegAddr < pDc->status_map_tab[j].start_addr)
{
continue;
}
if((startRegAddr+RegNum) > pDc->status_map_tab[j].end_addr)
{
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1] | 0x80;
pDc->TX_BUFF[2] = 0x02; //异常码
calCRC=CRC_Compute(pDc->TX_BUFF,3);
pDc->TX_BUFF[3] = calCRC&0xFF;
pDc->TX_BUFF[4] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,5);
return;
}
break;
}
if(j == pDc->status_map_num)
{
return;
}
break;
case 06://写单个保持寄存器
RegNum = 1;
case 03://读保持寄存器
case 04://读输入寄存器
case 16://写多个保持寄存器
for(j=0; j<pDc->analog_map_num; j++)
{
if(pDc->analog_map_tab[j].fun_code != pDc->RX_BUFF[1])
{
continue;
}
if(startRegAddr < pDc->analog_map_tab[j].start_addr)
{
continue;
}
if((startRegAddr+RegNum) > pDc->analog_map_tab[j].end_addr)
{
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1] | 0x80;
pDc->TX_BUFF[2] = 0x02; //异常码
calCRC=CRC_Compute(pDc->TX_BUFF,3);
pDc->TX_BUFF[3] = calCRC&0xFF;
pDc->TX_BUFF[4] = (calCRC>>8)&0xFF;
pDc->SendData(pDc->TX_BUFF,5);
return;
}
break;
}
if(j == pDc->analog_map_num)
{
return;
}
break;
default://功能码错误
pDc->TX_BUFF[0] = pDc->RX_BUFF[0];
pDc->TX_BUFF[1] = pDc->RX_BUFF[1] | 0x80;
pDc->TX_BUFF[2] = 0x01; //异常码
calCRC=CRC_Compute(pDc->TX_BUFF,3);
pDc->TX_BUFF[3] = calCRC & 0xFF;
pDc->TX_BUFF[4] = (calCRC>>8) & 0xFF;
pDc->SendData(pDc->TX_BUFF,5);
break;
}
switch(pDc->RX_BUFF[1])//根据不同的功能码进行处理
{
case 01://读输出开关量
{
Modbus_01_Solve(pDc,pDc->status_map_tab[j].itemMap,pDc->status_map_tab[j].itemNum);
break;
}
case 02://读输入开关量
{
Modbus_02_Solve(pDc,pDc->status_map_tab[j].itemMap,pDc->status_map_tab[j].itemNum);
break;
}
case 03://读保持寄存器
{
Modbus_03_Solve(pDc,pDc->analog_map_tab[j].itemMap,pDc->analog_map_tab[j].itemNum);
break;
}
case 04://读输入寄存器
{
Modbus_04_Solve(pDc,pDc->analog_map_tab[j].itemMap,pDc->analog_map_tab[j].itemNum);
break;
}
case 05://写单个输出开关量
{
Modbus_05_Solve(pDc,pDc->status_map_tab[j].itemMap,pDc->status_map_tab[j].itemNum);
break;
}
case 06: //写单个保持寄存器
{
Modbus_06_Solve(pDc,pDc->analog_map_tab[j].itemMap,pDc->analog_map_tab[j].itemNum);
break;
}
case 15: //写多个输出开关量
{
Modbus_15_Solve(pDc,pDc->status_map_tab[j].itemMap,pDc->status_map_tab[j].itemNum);
break;
}
case 16: //写多个保持寄存器
{
Modbus_16_Solve(pDc,pDc->analog_map_tab[j].itemMap,pDc->analog_map_tab[j].itemNum);
break;
}
}
}
void Modbus_RTU_Service(MODBUS_DC_TCM *pDc)
{
uint16_t calCRC;
uint16_t recCRC;
if(pDc->RX_CNT > MAX_FRAME_LENGTH || pDc->RX_CNT < MIN_FRAME_LENGTH)
{
//打印帧格式错误
}
else if(pDc->RX_BUFF[0] == pDc->Modbus_Addr)//地址正确
{
calCRC = CRC_Compute(pDc->RX_BUFF,pDc->RX_CNT-2);//计算所接收数据的CRC
recCRC = pDc->RX_BUFF[pDc->RX_CNT-2] | (((uint16_t)pDc->RX_BUFF[pDc->RX_CNT-1])<<8);//接收到的CRC(低字节在前,高字节在后)
if(calCRC == recCRC)//CRC校验正确
{
Modbus_Parse_Hand(pDc);
}
else
{
//回复校验码错误
}
}
pDc->RX_CNT = 0;//接收计数器清零
}
void Modbus_TCP_Service(MODBUS_DC_TCM *pDc)
{
uint8_t Len;
if(pDc->RX_CNT < 6)
{
pDc->RX_CNT = 0;
return;
}
if(pDc->RX_CNT < (pDc->RX_BUFF[5] + 6))
{
pDc->RX_CNT = 0;
return;
}
Len = pDc->RX_BUFF[5];
memcpy(pDc->RX_BUFF,&pDc->RX_BUFF[6],Len);
Modbus_Parse_Hand(pDc);
pDc->RX_CNT = 0;
}
/*************************************************************对外接口****************************************************************/
void Set_Modbus_Status_Map(MODBUS_DC_TCM *pDc,uint16_t start_addr,uint8_t fun_code,ITEM_T *status_map,unsigned int num)
{
int i = 0;
int total_size = 0;
pDc->status_map_tab[pDc->status_map_num].itemMap = status_map;
pDc->status_map_tab[pDc->status_map_num].start_addr = start_addr;
pDc->status_map_tab[pDc->status_map_num].fun_code = fun_code;
pDc->status_map_tab[pDc->status_map_num].itemNum = num;
for(i=0;i<num;i++)
{
status_map[i].start_addr = start_addr + total_size*8;
//printf("startaddr:%x\r\n",status_map[i].start_addr);
total_size += status_map[i].size;
status_map[i].end_addr = start_addr + total_size*8;
//printf("endaddr:%x\r\n",status_map[i].end_addr);
}
pDc->status_map_tab[pDc->status_map_num].end_addr = start_addr + total_size*8;
pDc->status_map_num++;
}
void Set_Modbus_Analog_Map(MODBUS_DC_TCM *pDc,uint16_t start_addr,uint8_t fun_code,ITEM_T *analog_map,unsigned int num)
{
int i = 0;
int total_size = 0;
pDc->analog_map_tab[pDc->analog_map_num].itemMap = analog_map;
pDc->analog_map_tab[pDc->analog_map_num].start_addr = start_addr;
pDc->analog_map_tab[pDc->analog_map_num].fun_code = fun_code;
pDc->analog_map_tab[pDc->analog_map_num].itemNum = num;
for(i=0;i<num;i++)
{
analog_map[i].start_addr = start_addr + total_size/2;
//printf("startaddr:%x\r\n",analog_map[i].start_addr);
total_size += analog_map[i].size;
if(total_size%2)
{
total_size++;
}
analog_map[i].end_addr = start_addr + total_size/2;
//printf("endaddr:%x\r\n",analog_map[i].end_addr);
}
pDc->analog_map_tab[pDc->analog_map_num].end_addr = start_addr + total_size/2;
pDc->analog_map_num++;
}
/******************************
*设置回调函数
*返回0 设置失败 返回1 设置成功
******************************/
int Set_Modbus_Cb(MODBUS_DC_TCM *pDc,uint8_t Fun_Code, void (*callback)(uint16_t startRegAddr))
{
if(!callback)
{
return 0;
}
switch(Fun_Code)
{
}
return 1;
}
/*modbus一切服务从这里开始*/
int Create_Modbus_Service(MODBUS_DC_TCM *pDc,uint8_t addr,int (*SendData)(uint8_t *,int))
{
int data = 0x12345678;
char *ch = (char *)&data;
memset(pDc,0,sizeof(MODBUS_DC_TCM));
pDc->Modbus_Addr = addr;//设置modbus本机地址
pDc->SendData = SendData;
if(*ch == 0x78)
{
mode = LITTLE_ENDIAN;
}
else
{
mode = BIG_ENDIAN;
}
return 1;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/eleluq1234/tcp-stack.git
git@gitee.com:eleluq1234/tcp-stack.git
eleluq1234
tcp-stack
TCP协议栈
master

搜索帮助