?? 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 + -