📄 f280x_modbusprotocol.c
字号:
offset++;
}
*/
if (offset>=DigitalComm[j].data_num)
{
if ((offset+DigitalComm[j].start_addr)>=DigitalComm[j+1].start_addr && j<DIGITAL_NO-1)
{
offset = 0;j++;
value = *(DigitalComm[j].p_addr+offset);
}
else value=0;//状态量清0
}
else
{
value = *(DigitalComm[j].p_addr+(offset>>4));
if ( ((offset>>4)<<1) != offset>>3 ) { value >>=8;}//(offset/16*2 !=offset/8) is high--8bit of 16bit
}
offset +=8;
SerModbus.send_msg[i+3]=value&0xff;
}
SerModbus.crc_len=SerModbus.send_msg[2]+3;
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 3://Read Holding Registers
///offset=SerModbus.receive_msg[2]*256+SerModbus.receive_msg[3];
///d_num=SerModbus.receive_msg[4]*256+SerModbus.receive_msg[5];
s_addr=SerModbus.receive_msg[2]*256+SerModbus.receive_msg[3];//起始地址
d_num=SerModbus.receive_msg[4]*256+SerModbus.receive_msg[5];//数据个数
j=0; while((s_addr<AnalogComm[j].start_addr || s_addr>=AnalogComm[j+1].start_addr ) && j<ANALOG_NO-1){j++;}//检索起始地址--地址范围:Start_pre<=x && x<Start_next
offset = s_addr-AnalogComm[j].start_addr;
if (j>=ANALOG_NO-1)
{
j=ANALOG_NO-1;
if (s_addr>=CommSoeEventAddr && s_addr < CommSoeEventAddr+CommSoeEventNum)
{//召唤SOE---!!!ThinkRoad special function
id=(s_addr-CommSoeEventAddr)/(MACROFAULT_BYTE>>1); offset = 0;
GetSoe(id); //soe_id:0~127
bitclr(&soe_status[0],id);//召SOE成功则清SOE状态标志//080414
}
else
{
ErrorResponse(3);//非法数据值
return;
}
}
//召唤数据地址检测
if (d_num<1 || d_num+5>MACROCOMM_S_NO)
{
ErrorResponse(3);//非法数据值
return;
}
//响应数据帧
//数据类型为WORD--16bit
SerModbus.send_msg[2]=2*d_num;
for(i=0;i<d_num;i++)
{
//响应数据区域索引
if (offset>=AnalogComm[j].data_num)
{
if ((offset+AnalogComm[j].start_addr)>=AnalogComm[j+1].start_addr && j<ANALOG_NO-1)
{
offset = 0;j++;
value=*(AnalogComm[j].p_addr+offset);
}
else value=0;
}
else value=*(AnalogComm[j].p_addr+offset);
/*********定值控制字逻辑变量**********/
if ((AnalogComm[j].p_addr+offset)>=(Uint16 *)&dzkg1 && (AnalogComm[j].p_addr+offset)<((Uint16 *)&dzkg1+(MACROSETDZKG_NO<<4)) && AnalogComm[j].start_addr>=CommSetDz1Addr)//!!!控制字寄存器变量设置区域
{
k=AnalogComm[j].p_addr+offset-(Uint16 *)&dzkg1;
if (bittst((Uint16 *)&dzkg1,k))
value = 1;
else
value = 0;
}
/************************************/
offset++;
SerModbus.send_msg[2*i+3]=(value>>8)&0xff;//数据高位字节
SerModbus.send_msg[2*i+4]=value&0xff;//数据低位字节
}
SerModbus.crc_len=SerModbus.send_msg[2]+3;
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 4://Read Input Registers--遥测量
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 5://Force Single Coil
ctrl_point=SerModbus.receive_msg[2]*256+SerModbus.receive_msg[3];//--主机修改定值点号
value=SerModbus.receive_msg[4]*256+SerModbus.receive_msg[5];
if(ctrl_point>CONTROL_NO-1)
{
ErrorResponse(3);//非法数据值
return;
}
if(ctrl_point<8 && dzyk_s == 1)
{//遥控出口
if(value)//value == 0xFF00
{
SerModbus.ck_point=ctrl_point;
bitset(&kc_value,ctrl_point);
bitset((Uint16 * )&SerModbus.ck_flag,ctrl_point);
}
else
{
SerModbus.ck_point=ctrl_point;
bitclr(&kc_value,ctrl_point);
bitclr((Uint16 * )&SerModbus.ck_flag,ctrl_point);
}
bitset((Uint16 * )&SerModbus.event_report,0);
}
else CommSelCtrl(ctrl_point);
SerModbus.send_msg[2]=SerModbus.receive_msg[2];//定值通道号高位字节
SerModbus.send_msg[3]=SerModbus.receive_msg[3];//定值通道号低位字节
SerModbus.send_msg[4]=SerModbus.receive_msg[4];//数据高位字节
SerModbus.send_msg[5]=SerModbus.receive_msg[5];//数据低位字节
SerModbus.crc_len=6;
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 6://Preset Single Resister--遥控量
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 7://Read Exception Status
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 8://Reserve 回送诊断校验,把诊断校验报文送从机,以对通信处理进行评鉴
SerModbus.send_count=0;
break;
case 9://编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑
SerModbus.send_count=0;
break;
case 10://控询(只用于484)
SerModbus.send_count=0;
break;
case 11://Fech Comm Event Ctr
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 12://Fech Comm Event Log
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 13://编程(只用于484)使主机模拟编程器作用,修改PC从机逻辑
SerModbus.send_count=0;
break;
case 14://控询(只用于484)
SerModbus.send_count=0;
break;
case 15://Force Mutiple Coils
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 16://Preset Multiple Regs--遥调量
///offset=SerModbus.receive_msg[2]*256+SerModbus.receive_msg[3];
///d_num=SerModbus.receive_msg[4]*256+SerModbus.receive_msg[5];
s_addr=SerModbus.receive_msg[2]*256+SerModbus.receive_msg[3];//起始地址
d_num=SerModbus.receive_msg[4]*256+SerModbus.receive_msg[5];//数据个数
byte=SerModbus.receive_msg[6];//字节长度
j=0; while((s_addr<AnalogComm[j].start_addr || s_addr>=AnalogComm[j+1].start_addr) && j < ANALOG_NO-1 ){j++;}//检索起始地址--地址范围:Start_pre<=x && x<Start_next
offset = s_addr-AnalogComm[j].start_addr;
if (d_num<1 || d_num+5>MACROCOMM_S_NO /*|| d_num!=byte/2*/)
{
ErrorResponse(3);//非法数据值
return;
}
for(i=0;i<d_num;i++)
{
value=(SerModbus.receive_msg[i*2+7])*256+SerModbus.receive_msg[i*2+8];
//响应数据区域索引
if (offset>=AnalogComm[j].data_num)
{
if ((offset+AnalogComm[j].start_addr)>=AnalogComm[j+1].start_addr && j<ANALOG_NO-1)
{offset = 0;j++; }
else
break;
}
*(AnalogComm[j].p_addr+offset)=value;
//定值类型检测
if ((AnalogComm[j].p_addr+offset)>=(Uint16*)&clockrade && (AnalogComm[j].p_addr+offset)<((Uint16*)&clockrade+0x06))
{//时钟区域
p_addr = (Uint16 *)&clockwrite;
*(p_addr+ (AnalogComm[j].p_addr+offset-(Uint16*)&clockrade)) = value;
flag = 0x01;
}
else if ((AnalogComm[j].p_addr+offset)>=(Uint16*)&nvdd_accu && (AnalogComm[j].p_addr+offset)<((Uint16*)&nvdd_accu+0x0e))
{//电度区域
flag = 0x02;
}
else if ((AnalogComm[j].p_addr+offset)>=(Uint16* )&DzDat0.Point[0] && (AnalogComm[j].p_addr+offset)<((Uint16* )&DzDat0.Point[0]+0x40) && AnalogComm[j].start_addr<CommSetDz1Addr)
{//用户区域
flag = 0x03;
}
else if ((AnalogComm[j].p_addr+offset)>=(Uint16*)&dzkg1 && (AnalogComm[j].p_addr+offset)<((Uint16*)&dzkg1+(MACROSETDZKG_NO<<4)) && AnalogComm[j].start_addr>=CommSetDz1Addr)//!!!控制字寄存器变量设置区域
{//控制字逻辑变量区域
flag = 0x04;
k=AnalogComm[j].p_addr+offset-(Uint16*)&dzkg1;
if(value)
bitset((Uint16 *)&dzkg1,k);
else
bitclr((Uint16 *)&dzkg1,k);
}
else if ((AnalogComm[j].p_addr+offset)>=(Uint16* )DDRAM_DAT_ABS && (AnalogComm[j].p_addr+offset)<((Uint16* )DDRAM_DAT_ABS+0x40))
{//其它参数区域
flag = 0x05;
}
else if ((AnalogComm[j].p_addr+offset)>=(Uint16* )&DzDat1.Point[0] && (AnalogComm[j].p_addr+offset)<((Uint16* )&DzDat1.Point[0]+0x40))
{//调试区域
flag = 0x06;
}
else {ErrorResponse(3);return;}//非法数据值
offset++;
}
//定值类型检测
if (flag==0x01)
ClockSet();//时钟设置
else if(flag==0x02)
read_energy();//电度设置(将nvdd值写入DDRAM)
else if(flag==0x03 || flag==0x04)
bitset(&save_event_flag,0);//用户定值
else if(flag==0x06)
bitset(&save_event_flag,1);//调试定值
else if(flag==0x05)
;//其它参数(自动保存)
SerModbus.send_msg[2]=SerModbus.receive_msg[2];//定值通道号高位字节
SerModbus.send_msg[3]=SerModbus.receive_msg[3];//定值通道号低位字节
SerModbus.send_msg[4]=SerModbus.receive_msg[4];//数据高位字节
SerModbus.send_msg[5]=SerModbus.receive_msg[5];//数据低位字节
SerModbus.crc_len=6;
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 17://Report Slave
SerModbus.send_count=0;
break;
case 18://(884和MICRO84)
SerModbus.send_count=0;
break;
case 19://重置通信链路
SerModbus.send_count=0;
break;
case 20://Read Gerenal Reference
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 21://Write General Reference
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 22://Mask Write 4X Register
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 23://Read/Write 4X Registers
SerModbus.send_count=SerModbus.crc_len+2;
break;
case 24://Read FIFO Queue
SerModbus.send_count=SerModbus.crc_len+2;
break;
default:
SerModbus.send_count=0;
break;
}
//广播命令或者发送字节为0立即返回
if(broad_flag==0xff || SerModbus.send_count==0)
{
SerModbus.Busy=0;
SerModbus.Access=0;
SerModbus.send_count=0;
Ser.port_right=0;
return;
}
// 发送数据校验
crc_result=CRC16((Uchar *)&SerModbus.send_msg[0],SerModbus.crc_len);
SerModbus.send_msg[SerModbus.crc_len]=(crc_result>>8)&0xff;
SerModbus.send_msg[SerModbus.crc_len+1]=crc_result&0xff;
SerModbus.s_timer=0;//发送记时清零
SerModbus.send_flag=0xff;//置发送标志
//com_type=COM_SER;
//ComSendCtrl(com_type);//通讯口发送控制
ComSendCtrl(Com.port_typ);
}
/*
void GetSoe(Uint16 no)
{
Uint16 * p_data;
Uint16 start,size;
p_data=(Uint16*)&fault_soe;
size=FAULT_BYTE_NO/MACROFAULT_PAGE;
start=FAULTAREA_ADDR+size*no;
ReadFm24cl((Uint16*)p_data,start,size,1,FM2416_ID);//共保存7120字节故障记录 64条故障记录
}
*/
void GetSoe(Uint16 no)
{
Uint16 *p_data,*p_fault;
Uint16 start,size;
Uint16 id,i;
p_data=(Uint16*)&fault_soe;
if ((no+1) != soe_id)
{//主机主动召唤SOE
start=FAULTAREA_ADDR+MACROFAULT_BYTE*no;
ReadFm24cl((Uint16*)p_data,start,MACROFAULT_BYTE,1,FM2416_ID);//共保存7120字节故障记录 64条故障记录
}
else
{//从机请求召唤SOE
///id = soe_id-1-fault_block_wr*MACROFAULT_PAGE;
id = no-no/MACROFAULT_PAGE*MACROFAULT_PAGE;
p_fault = (Uint16* )&fault_record[id];
for(i=0;i<(MACROFAULT_BYTE>>1);i++) {*(p_data++) = *(p_fault++);}
if (soe_count>0)
{
soe_count--;
if(++soe_id>MACROFAULT_SOE) { soe_id=1; }
bitset(&soe_status[0],soe_id-1);//置SOE状态标志
}
if (soe_count==0) {soe_id=0;}//SOE传输完成
}
}
//===========================================================================
// No more.
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -