📄 c103_485.c
字号:
#include "string.h"
#include "nucleus.h" /* nucleus os functions */
#include "mo_defs.h" //predefine for Motorola CPU
#include "sy_defs.h"
#include "ke_defs.h"
#include "cl_defs.h"
#include "cc_defs.h"
#include "en_defs.h"
#include "se_defs.h"
#include "c103_485.h"
#include "P103def.h"
#define UART_RCV_SIZE 260
static WORD flag;
static WORD wave_flag;
static BYTE scn;
BYTE m_tx_buf[UART_RCV_SIZE];
BYTE buf103[800];
BYTE setzone_buf[10];
BYTE last_cmd;
BYTE last_id;
BYTE tot_leng;
BYTE byte_send;
BYTE number_send;
BYTE ngd;
BYTE rii;
BYTE fan0;
BYTE fan1;
BYTE acc;
BOOL Has_Reset = false;
BOOL Has_Event = false;
BOOL Modify_Set_Valid = false;
EN_EVENT_RECORD Current_Event_Record;
CL_TIME polling_time;
/*******************************主站侧初始化***********************************/
/* 主站侧初始化 */
int COM_Initialize(void)
{
STATUS status;
//生成通讯接收任务
{
static BYTE task_com_stack[0x800];
static NU_TASK task_com_key;
status=NU_Create_Task(&task_com_key,
"COM ",
Task_Serial,
3,
NU_NULL,
task_com_stack,
0x800,
50,
0,
NU_NO_PREEMPT,
NU_START);
}
if(status!=NU_SUCCESS)
return false;
SEC_Option_B.se_mode=SE_CM_NORMAL;
SEC_Option_B.se_baud=SYC_MMI_Config.sy_comm2_baud;
SEC_Option_B.se_parity=SE_PARITY_NO;
SEC_Option_B.se_rts_enable=0x00;
SEC_Option_B.se_cts_enable=0x00;
SEC_Option_B.se_byte_overtime=15;
SEC_Option_B.se_add_position=0;
SEC_Option_B.se_length_position=3;
SEC_Option_B.se_min_length=5;
SEC_Option_B.se_extra_length=5;
SEC_Option_B.se_broadcast_add=0xff;
SEC_Option_B.se_filter=true;
SEC_Setting(SE_CHANNEL_B);
return true;
}
/* 串口发送 */
static void UART_Write(BYTE *m_tx_buf,BYTE txLen)
{
if(SYC_MMI_Config.sy_comm2_mode == SE_B_485)
NU_Sleep(2);//Delay 10~20ms
SEC_Send(SE_CHANNEL_B, m_tx_buf, txLen);
}
/* 发送固定帧长报文 */
static void send_fix_packet(BYTE byDevAddr, BYTE f_ctrl)
{
BYTE m_tx_len;
m_tx_buf[0] = 0x10;
m_tx_buf[1] = f_ctrl;
m_tx_buf[2] = byDevAddr;
m_tx_buf[3] = Makecrc(&m_tx_buf[1], 2);
m_tx_buf[4] = 0x16;
m_tx_len =5;
tot_leng = m_tx_len;
UART_Write(m_tx_buf, m_tx_len);
}
/* 发送可变帧长报文 */
static void send_var_packet(BYTE byDevAddr, BYTE f_ctrl, BYTE data_len)
{
WORD m_tx_len;
m_tx_buf[0] = 0x68;
m_tx_buf[1] = data_len + 2;
m_tx_buf[2] = data_len + 2;
m_tx_buf[3] = 0x68;
m_tx_buf[4] = f_ctrl;
m_tx_buf[5] = byDevAddr;
/*
user data marked by data_len in bytes
*/
m_tx_buf[data_len+6] = Makecrc(&m_tx_buf[4], (WORD)(data_len+2));
m_tx_buf[data_len+7] = 0x16;
m_tx_len = data_len + 8;
tot_leng = m_tx_len;
UART_Write(m_tx_buf, m_tx_len);
}
/* 串口任务 */
VOID Task_Serial(UNSIGNED argc, VOID *argv)
{
BYTE m_rx_buf[260];
for (;;)
{
BYTE c_crc,r_crc;
int recvLen;
recvLen = SEC_Receive(SE_CHANNEL_B,m_rx_buf,260,NU_SUSPEND);
if (recvLen < 5)
continue;
//check CRC
r_crc = m_rx_buf[recvLen - 2];
c_crc = Makecrc(&m_rx_buf[3], m_rx_buf[2]);
if ((r_crc != c_crc) || (recvLen != m_rx_buf[2]))
{
continue;
}
Serial_Interpret(m_rx_buf);
}
}
/* 数据接受处理函数 */
static void Serial_Interpret(BYTE *m_rx_buf)
{
BYTE off_set;
BYTE byDevAddr;
for (off_set = 0; off_set < SYC_MMI_Status.sy_CPUs; off_set++)
{
byDevAddr = SYC_MMI_Config.sy_add + off_set;
switch (m_rx_buf[0])
{
case FRAME_T_CON:
if (m_rx_buf[2] == byDevAddr)
{
process_fix_packet(m_rx_buf, byDevAddr);
return;
}
break;
case FRAME_T_VOL:
if (m_rx_buf[5] == byDevAddr || m_rx_buf[5] == 0xff)
{
process_var_packet(m_rx_buf, byDevAddr);
return;
}
break;
default:
return;
}
}
}
//可变帧长报文的处理
static void process_var_packet(BYTE *m_rx_buf,BYTE byDevAddr)
{
switch(m_rx_buf[6])
{
case ASDU_6:
Reply_Asdu06(m_rx_buf, byDevAddr);//对时
return;
case ASDU_7:
Relpy_Asdu07(m_rx_buf, byDevAddr);//总查询
return;
case ASDU_10:
Reply_Asdu10(m_rx_buf, byDevAddr);//通用分类数据
return;
case ASDU_20:
Reply_Asdu20(m_rx_buf, byDevAddr);//一般命令(复归保护信号)
return;
case ASDU_21:
Reply_Asdu21(m_rx_buf, byDevAddr);//通用分类命令
return;
case ASDU_24:
Reply_Asdu24(m_rx_buf, byDevAddr);//扰动数据的传输
return;
case ASDU_25:
Reply_Asdu25(m_rx_buf, byDevAddr);//扰动数据的认可
default:
return;
}
}
//固定帧长报文的处理
static void process_fix_packet(BYTE* m_rx_buf,BYTE byDevAddr)
{
BYTE data_len;
BYTE f_ctrl;
if (m_rx_buf[1] == last_cmd && byDevAddr == last_id)
{
//将上次报文重发
data_len = tot_leng;
UART_Write(m_tx_buf, data_len);
return;
}
last_cmd = m_rx_buf[1];
last_id = byDevAddr;
switch(m_rx_buf[1]&0x0f)
{
case 0x00:
//复位通信单元
memset(m_tx_buf, 0, UART_RCV_SIZE);
flag = FLAG_RESET_CU;
Has_Reset = true;
send_fix_packet(byDevAddr, 0x20);
break;
case 0x07:
//复位帧计数位
flag = FLAG_RESET_FCB;
Has_Reset = true;
send_fix_packet(byDevAddr, 0x20);
break;
case 0x0a:
if (!Has_Reset)
{
//f_ctrl = 0x0e 链路服务未工作
send_fix_packet(byDevAddr, 0x0e);
}
if (flag == FLAG_RESET_CU)
{
//回答复位通信单元报文
ASDU05(m_rx_buf,byDevAddr);
flag = FLAG_POWER_ON;
return;
}
if (flag == FLAG_RESET_FCB)
{
//回答复位帧计数报文
ASDU05(m_rx_buf,byDevAddr);
flag = FLAG_POWER_ON;
return;
}
if (flag == FLAG_POWER_ON)
{
ASDU05(m_rx_buf,byDevAddr);
flag = 0x00;
return;
}
//检查是否总查询发生
if (flag == FLAG_POLLING)
{
//回答全遥信
T_103_ASDU *p_asdu = (T_103_ASDU *)&m_tx_buf[6];
p_asdu->type = 0x01;
p_asdu->vsq = 0x81;
p_asdu->cot = 0x09;
p_asdu->addr = byDevAddr;
p_asdu->fun = 128;//@@@@@@@@@@@@@FUN 待定
if (flag == FLAG_SEND_SOFW)
{
}
return;
}
//总查询时送被记录的扰动表
if (wave_flag == FLAG_QUERYSEND_WAVE_TABLE || wave_flag == FLAG_AUTOSEND_WAVE_TABLE)
{
BYTE i,j;
BYTE wave_table_num;
BYTE *pt;
T_103_ASDU *p_asdu = (T_103_ASDU *)&m_tx_buf[6];
T_103_WAVE *p_wave = (T_103_WAVE *)&p_asdu->data[0];
p_asdu->type = 23;
p_asdu->vsq = 0x81;
if (wave_flag == FLAG_AUTOSEND_WAVE_TABLE)
{
p_asdu->cot = 0x01;
wave_flag = 0;
f_ctrl = 0x08;
}
else
{
flag = FLAG_POLLING_END;
wave_flag = 0;
p_asdu->cot = 0x09;
f_ctrl = 0x20;
}
p_asdu->addr = byDevAddr;
p_asdu->fun = 128;//@@@@@@@@@@@@@FUN 待定
p_asdu->inf = 0;
Get103_fault_table(buf103, byDevAddr);
pt = buf103;
wave_table_num = *pt++;
data_len = 6;
for (i = 0; i < wave_table_num; i ++)
{
p_wave->fanl = *pt++;
p_wave->fanh = *pt++;
p_wave->sof = *pt++;
data_len += 3;
for (j = 0; j < 7; j++)
{
p_wave->data[j] = *pt++;
data_len++;
}
p_wave = (T_103_WAVE *) ((BYTE *)p_wave + 10);
}
send_var_packet(byDevAddr, f_ctrl, data_len);
}
//总查询的终止
if (flag == FLAG_POLLING_END)
{
ASDU08(m_rx_buf,byDevAddr);
return;
}
if (flag == FLAG_SEND_EVENT)
{
EN_EVENT *p_event=&Current_Event_Record.en_event;
T_103_ASDU *p_asdu = (T_103_ASDU *)&m_tx_buf[6];
p_asdu->type = 0x01;
p_asdu->vsq = 0x81;
p_asdu->cot = 0x01;//自发(突发)
p_asdu->addr = byDevAddr;
p_asdu->fun = 128;//@@@@@@@@@FUN 待定
switch (p_event->en_type & 0x7f)
{
case EN_RELAY_EVENT:
case EN_RELAY_PRINT_EVENT:
p_asdu->inf = p_event->en_code + EVT_BEGIN;
break;
case EN_ALARM_EVENT:
p_asdu->inf = p_event->en_code + ALA_BEGIN;
break;
case EN_DI_EVENT:
p_asdu->inf = p_event->en_code + DIC_BEGIN;
break;
default:
return;
}
p_asdu->data[0] = 2;//双点信息
p_asdu->data[1] = (BYTE) Current_Event_Record.en_event.en_time.cl_ms;
p_asdu->data[2] = (BYTE) (Current_Event_Record.en_event.en_time.cl_ms >> 8);
p_asdu->data[3] = Current_Event_Record.en_event.en_time.cl_minute;
p_asdu->data[4] = Current_Event_Record.en_event.en_time.cl_hour;
p_asdu->data[5] = 1;//@@@@@@@@@@@SIN 待定
if (!Has_Event)
{
Has_Event =
ENC_Get_Event_From_Queue(&ENC_QU_Event_Comm2,NU_NO_SUSPEND,&Current_Event_Record);
}
if(!Has_Event)
{
if(NU_Obtain_Semaphore(&SYC_Test_Event_Sema,NU_NO_SUSPEND) == NU_SUCCESS)
{
Current_Event_Record.en_event = ENC_Test_Event;
Has_Event = true;
}
}
if (Has_Event)
{
f_ctrl = 0x20;
flag = FLAG_SEND_EVENT;
}
else
{
f_ctrl = 0x09;
flag = 0;
wave_flag = FLAG_AUTOSEND_WAVE_TABLE;
Has_Event = false;
}
data_len = 12;
send_var_packet(byDevAddr, f_ctrl, data_len);
return;
}
if (wave_flag == FLAG_SEND_DATA_READY)
{
BYTE i;
BYTE *pr;
BYTE *pt;
T_103_ASDU *p_asdu = (T_103_ASDU *) &m_tx_buf[6];
p_asdu->type = 0x1a;
p_asdu->vsq = 0x81;
p_asdu->cot = 31;
p_asdu->addr = byDevAddr;
p_asdu->fun = 128; //@@@@@@@@@??????FUN
p_asdu->inf = 0;
p_asdu->data[0] = 0;
Get103_data_ready(buf103, byDevAddr, fan0, fan1);
pr = buf103;
pt = &p_asdu->data[1];
for (i = 0; i < 14; i++)
{
*pt++ = *pr++;
}
f_ctrl = 0x20;
data_len = 21;
send_var_packet(byDevAddr, f_ctrl, data_len);
}
if (wave_flag == FLAG_SEND_STATE_READY)
{
//ASDU28
send_state_ready();
}
if (wave_flag == FLAG_SEND_ORIGINAL_STATE)
{
//ASDU29
send_original_state();
}
if (wave_flag == FLAG_SEND_CHANGE_STATE)
{
//ASDU29
send_change_state();
}
if (wave_flag == FLAG_SEND_STATE_END)
{
//ASDU31
send_state_end();
}
if (wave_flag == FLAG_SEND_CHANEL_READY)
{
//ASDU27
send_channel_ready();
}
if (wave_flag == FLAG_SEND_CHANEL_DATA)
{
//ASDU30
send_channel(m_rx_buf, byDevAddr, acc);
}
if (wave_flag == FLAG_SEND_CHANEL_END)
{
//ASDU31
send_channel_end();
}
/* //传送描述表
if (flag == FLAG_READ_LIST)
{
}
//是否传送遥信量
if(flag == FLAG_READ_DI)
{
}
//是否要传送遥测值
if(flag == FLAG_READ_MEASURE)
{
}
//检查是否要传送软压板
if(flag == FLAG_READ_SFC)
{
}
*/
//检查是否要传送保护定值 asdu10
if (flag == FLAG_GENERAL_READ)
{
BYTE i = 0, j;
BYTE *ps = buf103;
T_103_ASDU *p_asdu = (T_103_ASDU *) &m_tx_buf[6];
T_103_DATA *p_rec = (T_103_DATA *) &p_asdu->data[2];
p_asdu->type = 0x0a;
p_asdu->vsq = 0x81;
p_asdu->cot = 0x2a;
p_asdu->addr = byDevAddr;
p_asdu->fun = 0xfe;
p_asdu->inf = 0xf1;
p_asdu->data[0] = 0;//@@@@@@@RII
if (byte_send == 0)
{
ngd = *ps++;//定值数目
byte_send++;
}
if ((ngd - number_send) > 20)
{
ngd |= 0x80;
f_ctrl = 0x20;
}
else
{
f_ctrl = 0x08;
}
p_asdu->data[1] = ngd;
data_len = 8;
ps = buf103 + byte_send;
while (i < 20)
{
if (number_send < (ngd&0x3f))
{
p_rec->ginl = *ps++;
p_rec->ginh = *ps++;
p_rec->kod = *ps++;
p_rec->type = *ps++;
p_rec->size = *ps++;
p_rec->num = *ps++;
byte_send += 6;
data_len += 6;
for (j = 0; j < p_rec->size * p_rec->num; j++)
{
p_rec->data[j] = *ps++;
byte_send++;
data_len++;
}
p_rec =(T_103_DATA *)((BYTE *)p_rec+6+p_rec->num*p_rec->size);
number_send++;
i++;
}
}
send_var_packet(byDevAddr, f_ctrl, data_len);
return;
}
//回答无所响应数据报文
send_fix_packet(byDevAddr, 0x09);
break;
case 0x0b:
//检查是否产生了一级用户数据(开入量是否有变化&&是否有保护事件发生)
if (!Has_Event)
{
Has_Event =
ENC_Get_Event_From_Queue(&ENC_QU_Event_Comm2,NU_NO_SUSPEND,&Current_Event_Record);
}
if(!Has_Event)
{
if(NU_Obtain_Semaphore(&SYC_Test_Event_Sema,NU_NO_SUSPEND) == NU_SUCCESS)
{
Current_Event_Record.en_event = ENC_Test_Event;
Has_Event = true;
}
}
if(Has_Event)
{
send_fix_packet(byDevAddr, 0x20);
flag = FLAG_SEND_EVENT;
return;
}
//回答无二类数据报文
send_fix_packet(byDevAddr, 0x09);
default:
return;
}
}
void Reply_Asdu05(BYTE *m_rx_buf,BYTE byDevAddr)
{
BYTE inf;
BYTE cot;
BYTE data_len;
BYTE control;
BYTE *p_buf103;
T_103_ASDU *p_asdu;
p_buf103 = buf103;
p_asdu = (T_103_ASDU *)&m_tx_buf[6];
switch(flag)
{
case FLAG_RESET_CU:
control = 0x28;
cot = 0x04;
inf = 0x03;
break;
case FLAG_RESET_FCB:
control = 0x28;
cot = 0x03;
inf = 0x02;
break;
default:
control = 0x08;
cot = 0x05;
inf = 0x04;
break;
}
p_asdu->type = 0x05;
p_asdu->vsq = 0x81;
p_asdu->cot = cot;
p_asdu->addr = byDevAddr;
p_asdu->fun = (BYTE) SYC_MMI_Config.sy_relay_type;//@@@@@@@@@FUN 待定
p_asdu->inf = inf;
p_asdu->data[0] = 0x03;
//拷贝厂家和版本信息
Get103_Manufacturer(p_buf103, byDevAddr); //制造厂名
p_asdu->data[1] = *p_buf103++;
p_asdu->data[2] = *p_buf103++;
p_asdu->data[3] = *p_buf103++;
p_asdu->data[4] = *p_buf103++;
p_asdu->data[5] = *p_buf103++;
p_asdu->data[6] = *p_buf103++;
p_asdu->data[7] = *p_buf103++;
p_asdu->data[8] = *p_buf103++;
Get103_E_Id(p_buf103, byDevAddr); //装置标识
p_asdu->data[9] = *p_buf103++;
Get103_M_No(p_buf103, byDevAddr); //出厂编号
p_asdu->data[10] = *p_buf103++;
Get103_Soft_Ver(p_buf103, byDevAddr); //软件版本号
p_asdu->data[11] = *p_buf103++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -