📄 f340_modbus.c
字号:
sendBuf[7]=dat>>8;sendBuf[8]=(char)dat; //数据内容
crcData.U16 = crc16(sendBuf,9); //CRC
sendBuf[9]=crcData.U8[MSB]; //CRC高字节
sendBuf[10]=crcData.U8[LSB]; //CRC低字节
sendCount =11; //发送字节数
beginSend(); //开始发送
}//-----------------------------------------------------------------------------
// sendComm0Modbus
//
// Modbus状态机,在MAIN中调用
//
//-----------------------------------------------------------------------------
void sendComm0Modbus(void)
{
U8 i,j;
if(FM_alarming[3]==0x0f&&menu_alarm_set[3]==-1)MB_SetAlarm|=0x20;else MB_SetAlarm&=~0x20; //反向回转
if(FM_alarming[3]==0xff&&menu_alarm_set[3]==-1)MB_SetAlarm|=0x40;else MB_SetAlarm&=~0x40; //正向回转
i=FM_alarming[0]|FM_alarming[2]|FM_alarming[4];j=menu_alarm_set[0]|menu_alarm_set[2];
if(i==-1&&j==-1)MB_SetAlarm|=0x08;else MB_SetAlarm&=~0x08; //起升向上
i=FM_alarming[1]|FM_alarming[2]|FM_alarming[4];j=menu_alarm_set[1]|menu_alarm_set[2];
if(i==-1&&j==-1)MB_SetAlarm|=0x10;else MB_SetAlarm&=~0x10; //变幅向外
if(!bMB_idle) //空闲
{
if(bMB_setup) //设置状态
{
if(menu_comm0_test>0&&menu_comm0_test<6) //发送诊断
Modbus_CommandSend(menu_comm0_test,8,0xaa);
else if(menu_brChange!=SetReg0) //改变波特率
{ Modbus_CommandSend(0,6,menu_brChange);SetReg0=menu_brChange;}
}
else //工作状态
{
if(MB_SendNum>12)MB_SendNum=1;
else MB_SendNum+=1;
for(i=0;i<5;i++)
{
if (menu_comm0_addr[i]=='Y'&& MB_SendNum==i+1) //FunC:01
{ Modbus_CommandSend(i+1,4,16);return;}
else if(menu_comm0_addr[i]=='Y'&& MB_SendNum==i+6) //FunC:03
{ Modbus_CommandSend(i+1,1, 8*4);return;}
else if(menu_comm0_addr[0]=='Y'&& MB_SendNum==11) //FunC:15
{ if(MB_c15done=='S')Modbus_DataSend(1,15,0,SignalSet);return;}
else if(menu_comm0_addr[0]=='Y'&& MB_SendNum==12) //FunC:15
{ Modbus_DataSend(1,15,16,MB_SetAlarm);return;}
}
}
}
}
//-----------------------------------------------------------------------------
// beginSend
//
//开始发送
//-----------------------------------------------------------------------------
void beginSend(void)
{
b485Send = 1; //设为发送
bMB_idle = 1; //Modbus占用
sendPosi = 0;
if(sendCount > 1) sendCount--;
ACC = sendBuf[0];
TB80 = P;
SBUF0 = sendBuf[0];
}
//-----------------------------------------------------------------------------
// checkComm0Modbus
//
// Modbus状态机,在MAIN中调用
//
//-----------------------------------------------------------------------------
void checkComm0Modbus(void)
{
U16 crcData;
U16 tempData;
if(receCount > 4)
{
MB_ErrorCode=0; //Modbus错误清零
switch(receBuf[1])
{
case 1: //读取线圈状态(读取点 16位以内)
case 2: //读取输入状态(读取点 16位以内)
tempData = receBuf[2];
tempData += 5; //数据个数
if(receCount >= tempData)
{
if(receBuf[0]==sendBuf[0] && checkoutError==0)
{
crcData = crc16(receBuf,tempData-2);
if(crcData==(receBuf[tempData-2]<<8)+receBuf[tempData-1])
Master_readCoil(); //保存数据
else MB_ErrorCode=92; //CRC错误
MB_BroadTimer=0;MB_TimeOut=0;
bMB_idle=0; //释放总线
}
receCount = 0;checkoutError = 0;
}
break;
case 3: //读取保持寄存器(一个或多个)
case 4: //读取输入寄存器(一个或多个)
tempData =receBuf[2];
tempData += 5;
if(receCount >= tempData)
{
if(receBuf[0]==sendBuf[0] && checkoutError==0)
{
crcData = crc16(receBuf,tempData-2);
if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
Master_readRegisters();
else MB_ErrorCode=92; //CRC错误
MB_BroadTimer=0;MB_TimeOut=0;
bMB_idle=0; //释放总线
}
receCount = 0;checkoutError = 0;
}
break;
case 5: //强制单个线圈
case 6: //设置单个寄存器
case 8: //回送诊断校验
case 15: //设置多个线圈(128)
case 16: //设置多个寄存器(16)
if(receCount >= 8) //接收完成一组数据
{
if((receBuf[0]==sendBuf[0]) && checkoutError==0)
{
crcData = crc16(receBuf,6);
if(crcData != receBuf[7]+(receBuf[6]<<8))MB_ErrorCode=92; //CRC错误
else if(receBuf[1]==8){if(receBuf[5]==0xaa)MB_TestEcho=0xaa;} //数据正确
else if(receBuf[1]==15)MB_c15done=15; //c15完成
MB_BroadTimer=0;MB_TimeOut=0;
bMB_idle=0; //释放总线
}
receCount = 0;checkoutError = 0;
}
break;
default: //非法功能处理
if(receBuf[1]>=0x80)
{
MB_ErrorCode=receBuf[2]; //出错代码
MB_BroadTimer=0;MB_TimeOut=0;
bMB_idle=0; //释放总线
}
}
}
}
//-----------------------------------------------------------------------------
// Master_readCoil
//
//读线圈状态:读出从机数据保存到主机
//-----------------------------------------------------------------------------
void Master_readCoil(void)
{
U8 addr;
U8 tempAddr;
U8 bitCount;
UU16 tempData;
U8 i,k;
U8 exit = 0;
addr = (sendBuf[2]<<8)+sendBuf[3];
bitCount = (sendBuf[4]<<8)+sendBuf[5];
tempAddr =addr;
for(k=0;k<receBuf[2];k++)
{ //字节位置
tempData.U8[0] = receBuf[3+k];
for(i=0;i<8;i++)
{
tempData.U16=tempData.U16>>1; //位信息存在tempData.U8[1]最高位
setCoilVal(tempAddr,tempData.U8[1]);
tempData.U8[1] = 0;
tempAddr++;
if(tempAddr >= addr+bitCount){exit = 1;break;}//读完
}
if(exit == 1) break;
}
}
//-----------------------------------------------------------------------------
// Master_readRegisters
//
//读寄存器:读出从机数据保存到主机
//-----------------------------------------------------------------------------
void Master_readRegisters(void)
{
U8 addr;
U8 tempAddr;
U8 byteCount;
U16 i;
U16 tempData = 0;
addr = 0;
tempAddr = addr;
byteCount = receBuf[2];
for(i=0;i<byteCount;i++,tempAddr++)
{
tempData = (receBuf[i*2+3]<<8) + receBuf[i*2+4];
setRegisterVal(tempAddr,tempData);
}
}
//-----------------------------------------------------------------------------
// setCoilVal
//
//设定线圈状态 返回0表示成功
//-----------------------------------------------------------------------------
U16 setCoilVal(U16 addr,U8 tempData)
{
U16 result = 0;
U8 tempAddr;
U8 d,f;
d=1;
tempAddr = addr/8;
f = addr%8;
d = d <<f;
if (tempData != 0) SetCoil[receBuf[0]-1][tempAddr] |= d;
else SetCoil[receBuf[0]-1][tempAddr] &= ~d;
return result;
}
//-----------------------------------------------------------------------------
// setRegisterVal
//
//设置寄存器值 返回0表示成功
//-----------------------------------------------------------------------------
U16 setRegisterVal(U16 addr,U16 tempData)
{
U16 result = 0;
SetReg[receBuf[0]-1][addr] = tempData;
return result;
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -