📄 modbus16.c
字号:
Cputime_Start=0;
//软件复位SCI
SciaRegs.SCICTL1.bit.SWRESET=0;
SciaRegs.SCICTL1.bit.SLEEP=1;
SciaRegs.SCICTL1.bit.SWRESET=1;
SciaRegs.SCIFFTX.bit.SCIRST = 0;
SciaRegs.SCIFFTX.bit.SCIRST = 1; //SCI FIFO resume transmit or receive.
ResolveModbus();
}
}
Uint16 Crc16(Uint16 *puchMsg, Uint16 usDataLen)
{
Uint16 uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
Uint16 uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
Uint32 uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输消息缓冲区 */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
//接收数据从机地址检查
Uint16 AddrCheck(Uint16 AddrStart,Uint16 Num,Uint16 AddrMax)
{
Uint16 Result=0;
//错误2:查询中的数据地址对于从机来说是非法的
if(AddrStart<0 || Num<=0 || AddrStart+Num>AddrMax)
{
ModbusExcep(RdataA[1],ILLEGAL_DATA_ADDRESS);
SciaTx_Response();
Result=1;
}
return Result;
}
//读线圈状态01H
void ReadCoil(void)
{
Uint16 AddrStart=0; //起始地址
Uint16 TempAddr=0;
Uint16 CoilCount=0; //线圈数目
Uint16 ByteCount=0; //读取数据区字节个数
Uint16 CRCCheck=0; //CRC校验码
Uint16 TempData=0;
Uint16 i=0,k=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
CoilCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = CoilCount/8;
if(CoilCount%8 != 0) //不足8位的,当作一个字节
ByteCount+=1;
if(AddrCheck(AddrStart,CoilCount,MaxQ))
{//有错误
return;
}
TempAddr=AddrStart;
for(k=0;k<ByteCount;k++)
{
SdataA[k + 3] = 0;
for(i=0;i<8;i++)
{
GetCoilVal(TempAddr,&TempData);
SdataA[k + 3] |= TempData << i;
TempAddr++;
if(TempAddr >= AddrStart+CoilCount)
{ //读完
goto Label;
}
}
}
Label:
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = ByteCount;
CRCCheck = Crc16(SdataA,ByteCount+3);
SdataA[ByteCount+3] = CRCCheck >> 8;
SdataA[ByteCount+4] = CRCCheck & 0xff;
SdataA_Num = ByteCount+5;
SciaTx_Response();
}
//读输入状态02H
void ReadInputState(void)
{
Uint16 AddrStart=0; //起始地址
Uint16 TempAddr=0;
Uint16 InputCount=0; //读取数字输入量个数
Uint16 ByteCount=0; //读取数据区字节个数
Uint16 CRCCheck=0; //CRC校验码
Uint16 TempData=0;
Uint16 i=0,k=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr=AddrStart;
InputCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = InputCount / 8;
if(InputCount%8 != 0)
ByteCount+=1;
if(AddrCheck(AddrStart,InputCount,MaxI))
{//有错误
return;
}
for(k=0;k<ByteCount;k++)
{
SdataA[k + 3] = 0;
for(i=0;i<8;i++)
{
GetInputVal(TempAddr,&TempData);
SdataA[k + 3] |= TempData << i;
TempAddr++;
if(TempAddr >= AddrStart+InputCount)
{ //读完
goto Label;
}
}
}
Label:
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = ByteCount;
CRCCheck = Crc16(SdataA,ByteCount+3);
SdataA[ByteCount+3] = CRCCheck >> 8;
SdataA[ByteCount+4] = CRCCheck & 0xff;
SdataA_Num = ByteCount+5;
SciaTx_Response();
}
//读保持寄存器03H
void ReadHoldRegisters(void)
{
Uint16 AddrStart=0; //4X寄存器起始地址
Uint16 TempAddr=0;
Uint16 CRCCheck=0;
Uint16 RegistersCount=0; //要读寄存器的个数
Uint16 ByteCount=0; //字节计?
Uint16 TempData=0;
Uint16 i=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr=AddrStart;
RegistersCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = RegistersCount * 2;
if(AddrCheck(AddrStart,RegistersCount,MaxHold))
{//有错误
return;
}
for(i=0;i<ByteCount;i+=2,TempAddr++)
{
GetRegisterVal(TempAddr,&TempData);
SdataA[i+3] = TempData >> 8;
SdataA[i+4] = TempData & 0xff;
}
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = ByteCount;
CRCCheck = Crc16(SdataA,ByteCount+3);
SdataA[ByteCount+3] = CRCCheck >> 8;
SdataA[ByteCount+4] = CRCCheck & 0xff;
SdataA_Num = ByteCount + 5;
SciaTx_Response();
}//void readRegisters(void)
//读输入寄存器04H
void ReadInputRegisters(void)
{
Uint16 AddrStart=0; //寄存器起始地址
Uint16 TempAddr=0;
Uint16 CRCCheck=0;
Uint16 RegistersCount=0; //要读寄存器的个数
Uint16 ByteCount=0; //字节计数
Uint16 TempData = 0;
Uint16 i=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr=AddrStart;
RegistersCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = RegistersCount * 2;
if(AddrCheck(AddrStart,RegistersCount,MaxAI))
{//有错误
return;
}
for(i=0;i<ByteCount;i+=2,TempAddr++)
{
GetInputRegisterVal(TempAddr,&TempData);
SdataA[i+3] = TempData >> 8;
SdataA[i+4] = TempData & 0xff;
}
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = ByteCount;
CRCCheck = Crc16(SdataA,ByteCount+3);
SdataA[ByteCount+3] = CRCCheck >> 8;
SdataA[ByteCount+4] = CRCCheck & 0xff;
SdataA_Num = ByteCount + 5;
SciaTx_Response();
}
//强制单个线圈
void ForceSingleCoil(void)
{
Uint16 AddrStart=0;
Uint16 TempAddr=0;
Uint16 TempData=0;
Uint16 SetData=0;
Uint16 i=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr = AddrStart;
SetData = (RdataA[4]<<8) + RdataA[5];
if(AddrCheck(AddrStart,1,MaxQ))
{//有错误
return;
}
/////////////////////////////
//这里不同的上位机可能不同,要测试一下该功能?
/////////////////////////////
if(SetData == 0xFF00)
{ //设为ON
TempData = 1;
}
else if(SetData == 0x0000)
{ //设为OFF
TempData = 0;
}
SetCoilVal(TempAddr,TempData);
for(i=0;i<RdataA_Num;i++)
{
SdataA[i] = RdataA[i];
}
SdataA_Num = RdataA_Num;
SciaTx_Response();
}
//设置单个保持寄存器
void PresetSingleRegister(void)
{
Uint16 AddrStart=0;
Uint16 TempAddr=0;
Uint16 SetData=0;
Uint16 i=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr = AddrStart;
SetData = (RdataA[4]<<8) + RdataA[5];
if(AddrCheck(AddrStart,1,MaxHold))
{//有错误
return;
}
SetRegisterVal(TempAddr,SetData);
for(i=0;i<RdataA_Num;i++)
{
SdataA[i] = RdataA[i];
}
SdataA_Num = RdataA_Num;
SciaTx_Response();
}
//设置多个线圈
void ForceMultipleCoils(void)
{
Uint16 AddrStart=0;
Uint16 TempAddr=0;
Uint16 ByteCount=0;
Uint16 SetCount=0;
Uint16 CRCCheck=0;
unsigned TempState=0;
Uint16 i=0,k=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr = AddrStart;
SetCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = RdataA[6];
if(AddrCheck(AddrStart,SetCount,MaxQ))
{//有错误
return;
}
for(k=0;k<ByteCount;k++)
{
for(i=0;i<8;i++)
{
TempState = (RdataA[k+7]>>i) & 0x01;
SetCoilVal(TempAddr,TempState);
TempAddr++;
if(TempAddr >= AddrStart+SetCount)
{ //写完
goto Lable1;
}
}
}
Lable1:
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = AddrStart >> 8;
SdataA[3] = AddrStart & 0xff;
SdataA[4] = SetCount >> 8;
SdataA[5] = SetCount & 0xff;
CRCCheck = Crc16(SdataA,6);
SdataA[6] = CRCCheck >> 8;
SdataA[7] = CRCCheck & 0xff;
SdataA_Num = 8;
SciaTx_Response();
}
//设置多个保持寄存器
void PresetMultipleRegisters(void)
{
Uint16 AddrStart=0;
Uint16 TempAddr=0;
Uint16 ByteCount=0;
Uint16 SetCount=0;
Uint16 CRCCheck=0;
Uint16 TempData=0;
Uint16 i=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
TempAddr = AddrStart;
SetCount = (RdataA[4]<<8) + RdataA[5];
ByteCount = RdataA[6];
if(AddrCheck(AddrStart,SetCount,MaxHold))
{//有错误
return;
}
for(i=0;i<SetCount;i++,TempAddr++)
{
TempData = (RdataA[i*2+7]<<8) + RdataA[i*2+8];
SetRegisterVal(TempAddr,TempData);
}
SdataA[0] = Local;
SdataA[1] = RdataA[1];
SdataA[2] = AddrStart >> 8;
SdataA[3] = AddrStart & 0xff;
SdataA[4] = SetCount >> 8;
SdataA[5] = SetCount & 0xff;
CRCCheck = Crc16(SdataA,6);
SdataA[6] = CRCCheck >> 8;
SdataA[7] = CRCCheck & 0xff;
SdataA_Num = 8;
SciaTx_Response();
}//void presetMultipleRegisters(void)
//掩码设置保持寄存器
void MaskWrite4XRegister(void)
{
Uint16 AddrStart=0;
Uint16 OrMark=0;
Uint16 AndMark=0;
Uint16 i=0;
Uint16 TempData=0;
AddrStart = (RdataA[2]<<8) + RdataA[3];
AndMark = (RdataA[4]<<8) + RdataA[5];
OrMark = (RdataA[6]<<8) + RdataA[7];
if(AddrCheck(AddrStart,1,MaxHold))
{//有错误
return;
}
switch(AddrStart & 0x00ff)
{
case 0:
TempData=nData4Test[0];//将寄存器的值赋给TempData
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[0]=TempData;//将新的TempData值赋给寄存器
break;
case 1:
TempData=nData4Test[1];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[1]=TempData;
break;
case 2:
TempData=nData4Test[2];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[2]=TempData;
break;
case 3:
TempData=nData4Test[3];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[3]=TempData;
break;
case 4:
TempData=nData4Test[4];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[4]=TempData;
break;
case 5:
TempData=nData4Test[5];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[5]=TempData;
break;
case 6:
TempData=nData4Test[6];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[6]=TempData;
break;
case 7:
TempData=nData4Test[7];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[7]=TempData;
break;
case 8:
TempData=nData4Test[8];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[8]=TempData;
break;
case 9:
TempData=nData4Test[9];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[9]=TempData;
break;
case 10:
TempData=nData4Test[10];//将寄存器的值赋给TempData
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[10]=TempData;//将新的TempData值赋给寄存器
break;
case 11:
TempData=nData4Test[11];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[11]=TempData;
break;
case 12:
TempData=nData4Test[12];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[12]=TempData;
break;
case 13:
TempData=nData4Test[13];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[13]=TempData;
break;
case 14:
TempData=nData4Test[14];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[14]=TempData;
break;
case 15:
TempData=nData4Test[15];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[15]=TempData;
break;
case 16:
TempData=nData4Test[16];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[16]=TempData;
break;
case 17:
TempData=nData4Test[17];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[17]=TempData;
break;
case 18:
TempData=nData4Test[18];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[18]=TempData;
break;
case 19:
TempData=nData4Test[19];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[19]=TempData;
break;
case 20:
TempData=nData4Test[20];//将寄存器的值赋给TempData
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[20]=TempData;//将新的TempData值赋给寄存器
break;
case 21:
TempData=nData4Test[21];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[21]=TempData;
break;
case 22:
TempData=nData4Test[22];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[22]=TempData;
break;
case 23:
TempData=nData4Test[23];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[23]=TempData;
break;
case 24:
TempData=nData4Test[24];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[24]=TempData;
break;
case 25:
TempData=nData4Test[25];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[25]=TempData;
break;
case 26:
TempData=nData4Test[26];
TempData=MarkCompute(TempData,AndMark,OrMark);
nData4Test[26]=TempData;
break;
case 27:
TempData=nData4Test[27];
TempData=MarkCompute(TempData,AndMark,OrMark);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -