通用从机MODBUS,可移植
// 功能码3处理
void MODBUS_RD_HOLD(volatile MODBUS_Define *mv,u16 Adrr,u16 RegNum,u8 ADDRESS )
{
u8 i = 0,LenCNT=0;
s32 data = 0;
u16 TEMPCRC = 0;
switch(ADDRESS)//串口号
{
case 1:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS;//0x02
break;
case 2:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS2;//0x03
break;
case 3:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS3;//0x04
break;
default :
break;
}
mv->txBuf[LenCNT++]=MODBUS_RD_HOLD_REG;//0x03
mv->txBuf[LenCNT++]=0;//数据长度
switch(ADDRESS)
{
case 1:
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = * HoldReg_4xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
break;
case 2:
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = * HoldReg_4xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
break;
case 3:
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = * HoldReg_4xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
break;
default :
break;
}
mv->txBuf[2] = LenCNT - 3;
TEMPCRC = ModbusCRC(mv->txBuf,LenCNT);
mv->txBuf[LenCNT++] = LBYTE(TEMPCRC);
mv->txBuf[LenCNT++] = HBYTE(TEMPCRC);
mv->txLen = LenCNT;
}
// 功能码4处理
void MODBUS_IN_HOLD(volatile MODBUS_Define *mv,u16 Adrr,u16 RegNum,u8 ADDRESS)
{
u8 i = 0,LenCNT=0;
s32 data = 0;
u16 TEMPCRC = 0;
switch(ADDRESS)//串口号
{
case 1:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS;//0x01
break;
case 2:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS2;//
break;
case 3:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS3;//0x04
break;
case 4:
mv->txBuf[LenCNT++] = MODBUS__ADDRESS4;//0x05
break;
default :
break;
}
mv->txBuf[LenCNT++]=MODBUS_RD_IN_REG;//0x04
mv->txBuf[LenCNT++]=0;//数据长度
switch(ADDRESS)//串口号
{
case 1:
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = *InputReg_3xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
break;
case 2:
if((Adrr<=0x01DA)&&(Adrr>0))
{
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = *InputReg_3xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
}else if((Adrr>0x01DA)&&(Adrr<=0x031E)&&(Adrr>0))//SOC
{
for(i=(Adrr-0x01DB);i<((Adrr+RegNum)-0x01DB);i++)
{
mv->txBuf[LenCNT++] = li_battery_.Cell_SOC[i]>>8;
mv->txBuf[LenCNT++] = li_battery_.Cell_SOC[i]&0xFF;
}
}
else if((Adrr<=0x462)&&(Adrr>0x031E)&&(Adrr>0))//SOH
{
for(i=(Adrr -0x031F);i<((Adrr+RegNum)-0X031F);i++)
{
mv->txBuf[LenCNT++] = li_battery_.Cell_SOH[i]>>8;
mv->txBuf[LenCNT++] = li_battery_.Cell_SOH[i]&0xFF;
}
}
break;
case 3:
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = *InputReg_3xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
break;
case 4:
if(Adrr<0x01C5)
{
for(i=Adrr;i<((Adrr+RegNum));i++)
{
data = *InputReg_3xxxx[i];
mv->txBuf[LenCNT++] = data>>8;
mv->txBuf[LenCNT++] = data&0xFF;
}
}
else if((Adrr>=0x01C5)&&(Adrr<0x02E5))//SOC
{
for(i=(Adrr-0x01C5);i<((Adrr+RegNum)-0x01C5);i++)
{
mv->txBuf[LenCNT++] = li_battery_.Cell_SOC[i]>>8;
mv->txBuf[LenCNT++] = li_battery_.Cell_SOC[i]&0xFF;
}
}
else if((Adrr<0x405)&&(Adrr>=0x02E5))//SOH
{
for(i=(Adrr -0x02DD);i<((Adrr+RegNum)-0X02DD);i++)
{
mv->txBuf[LenCNT++] = li_battery_.Cell_SOH[i]>>8;
mv->txBuf[LenCNT++] = li_battery_.Cell_SOH[i]&0xFF;
}
}
break;
default :
break ;
}
mv->txBuf[2] = LenCNT - 3;
TEMPCRC = ModbusCRC(mv->txBuf,LenCNT);
mv->txBuf[LenCNT++] = LBYTE(TEMPCRC);
mv->txBuf[LenCNT++] = HBYTE(TEMPCRC);
mv->txLen = LenCNT;
}
好用可移植,接收数据采用中断方式