⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c103_485.c

📁 以太网103转四方串口103,以太网103转四方串口103
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -