}
/*
读取设备地址,此地址存储在EE或FLASH下, 可以改成其他方式如拨码开关等
*/
u8 MODBUS_SLAVE_BASE::ReadAddress(void)
{
#if USE_EEPROM
Address = EE.ReadByte(EE_ID_ADDR);
#elif USE_FLASG_EE
u16 adr[5];
fe.MemRead(FLASH_ID_PAGE, adr,5);
Address = adr[2] ;
#else
Address = 1;
#endif
if(Address <1 || Address >127) //地址范围
Address = 1;
return Address;
}
/*
从机协议解析(RTU)
*/
void MODBUS_SLAVE_BASE::Transfer(UARTMsgType *msg)
{
if(!msg->rcOK) return; //未接收完一帧数据
// if(msg->rcIndex<8) //帧长度<8 ,如果不支持日志等几个外,则长度一定>=8
// {
// msg->rcOK = false;
// msg->rcIndex = 0;
// return;
// }
if((Address==msg->Buf.msg.addr) || (msg->Buf.msg.addr==0)) // 地址正确或广播地址 则计算CRC
{
WORD crc = CRC16(msg->Buf.buf ,
(msg->Buf.msg.cmd!=16)? 6 : (msg->Buf.msg_16.bytecnt + 7));
if(crc.Value != ((msg->Buf.msg.cmd!=16)? \
msg->Buf.msg_3_4.crc : \
(*(u16*)((u8*)msg->Buf.buf + msg->Buf.msg_16.bytecnt + 7 ))) )
{//CRC错误
msg->rcOK = false;
msg->rcIndex = 0;
return;
}
#if USE_FLASG_EE
u16 adr[5];
int ij;
#endif
if(msg->Buf.msg.addr==0) //广播地址
{
switch(msg->Buf.msg.cmd )
{
case 0xcc: //自定义命令 -更改设备地址,可去掉
Address = msg->Buf.buf[5];
#if USE_EEPROM
EE.WriteByte(EE_ID_ADDR,Address );
#elif USE_FLASG_EE
for(ij=0;ij<5;ij++)
adr[ij] = Address ;
fe.MemWrite(FLASH_ID_PAGE, adr,5);
#endif
break;
default:
break;
}
for(int i=0;i<8;i++)
msg->Buf.buf = msg->Buf.buf;
SendMessage(msg,8);
msg->rcOK = false;
msg->rcIndex = 0;
return;
}
//正常操作
u16 shift,number; //计算偏移、数量/数值 供后面使用
shift = DATA_CHG_INT16(msg->Buf.msg_3_4.shift);
number= DATA_CHG_INT16(msg->Buf.msg_3_4.number);
msg->Buf.buf[0] = msg->Buf.msg.addr;
msg->Buf.buf[1] = msg->Buf.msg.cmd;
switch(msg->Buf.msg.cmd ) //modbus?ü??
{
case 0: //
break;
case 1: //????????×???
break;
case 2: //????????×???
break;
case 3: //????±????????÷(±ê?¨????)
case 4: //?????????????÷(???ù????)
msg->Buf.buf[2] = number*2;
if((shift + number) <= ((msg->Buf.msg_3_4.cmd==3)?NumOfHR:NumOfIR)) //不能越界
{
u8 *p = (u8*)(((msg->Buf.msg_3_4.cmd==3)?DatasOfBD.buf

atasOfDT.buf) + shift*2);
指针位置
for(int i=0; i<number; i++) //????????
{
msg->Buf.buf[3+ 2*i ] = p[2*i+1];
msg->Buf.buf[3+ 2*i+1] = p[2*i ];
}
crc.Value = 0xffff; //CRC计算
crc = CRC16(crc, msg->Buf.buf, 3 + number*2) ;
msg->Buf.buf[3 + number*2]=crc.cV[0] ;
msg->Buf.buf[4 + number*2]=crc.cV[1] ;
SendMessage(msg,(5 + number*2)) ; //返回数据
}
break;
case 5: //??????????
break;
case 6: //设置单个寄存器
DatasOfBD.Datas[shift] = number;
#if USE_EEPROM
EE.WriteByte(EE_BD_START + shift*2 + 0, DatasOfBD.buf[2*shift+0]);
EE.WriteByte(EE_BD_START + shift*2 + 1, DatasOfBD.buf[2*shift+1]);
#endif
#if USE_FLASG_EE
fe.MemWrite(FLASH_ID_PAGE+1,(u16*)DatasOfBD.buf,NumOfHR);
#endif
for(int i=2;i<8;i++)
msg->Buf.buf = msg->Buf.buf;
SendMessage(msg,8);
break;
case 16: //配置多组寄存器
if(shift + number < NumOfHR)
{
u16 *p = (u16*)((u8*)msg->Buf.buf + 7); //???????????·
for(int i=0; i<number; i++)
{
DatasOfBD.Datas[shift+i] = DATA_CHG_INT16(p);
#if USE_EEPROM
EE.WriteByte(EE_BD_START + (shift+i)*2 + 0, DatasOfBD.buf[2*(shift+i)+0]);
EE.WriteByte(EE_BD_START + (shift+i)*2 + 1, DatasOfBD.buf[2*(shift+i)+1]);
#endif
#if USE_FLASG_EE
fe.MemWrite(FLASH_ID_PAGE+1,(u16*)DatasOfBD.buf,NumOfHR);
#endif
}
for(int i=2; i<6;i++)
msg->Buf.buf = msg->Buf.buf;
crc = CRC16(msg->Buf.buf, 6) ;
msg->Buf.buf[6]=crc.cV[0] ;
msg->Buf.buf[7]=crc.cV[1] ;
SendMessage(msg,8);
}
break;
default:
break;
}
}
msg->rcOK = false;
msg->rcIndex = 0;
}