📄 hldb.c
字号:
//=================================================================================
//程序编写人:张征
//编写日期 :2007-5-18(于河南杞县苏木变)
//程序说明 :浙江华立电度表(485接口,1200BD,偶校验)
//程序功能 :正向有功总、正向无功总、反向有功总、反向无功总
//=================================================================================
#include "HLDB.h"
/* 设备标识及通讯端口 */
static WORD dev_id=SYS_IED_NIL;//设备ID号,first set device id is 0,SYS_IED_NIL=0 is defined in SYSTEM.H;
static WORD dev_port=UART_PORT_A;//default device port is A,UART_PORT_A=0 is defined in UART.H;
T_PULSE ym[4];
/* 轮询任务 */
static NU_TASK m_232_task;//NU_TASK is struction of array[42];
static BYTE m_232_stack[0x2000];
static VOID task_232(UNSIGNED argc, VOID *argv);
/* 通讯资源 */
static BYTE tx_buf[UART_PACKET_SIZE];//Transform buffer,UART_PACKET_SIZE=300,defined in UART.H;
static BYTE rx_buf[UART_PACKET_SIZE];//Recieve buffer;
static NU_SEMAPHORE com_lock;/*NU_SEMAPHORE is struction of array[10]*/
/* 锁定通讯资源,底层函数 */
#define DEV_LOCK_COM() NU_Obtain_Semaphore(&com_lock, NU_SUSPEND)
/* 开放通讯资源,底层函数 */
#define DEV_UNLOCK_COM() NU_Release_Semaphore(&com_lock)
/*T_IED结构 is defined DEV_MNG.H */
static T_IED ied_list[]=
{
{1, HLDB_service, 0, 0, {1,1}},//正向有功
{2, HLDB_service, 0, 0, {1,2}},//正向无功
{3, HLDB_service, 0, 0, {1,3}},//反向有功
{4, HLDB_service, 0, 0, {1,4}},//反向无功
};
/*初始化IDE设备,并且分配资源,系统自动调用,*/
BOOL IED_Initialize()
{
return DEV_Create_IED(ied_list, sizeof(ied_list)/sizeof(T_IED));
}
/* 接收中断回调函数,用以判断数据帧的结束。*/
static WORD pro_check_packet(const BYTE *p_data, WORD data_len)
{
if(data_len<11) return UART_PKT_CON;
if(p_data[0]!=0x68) return UART_PKT_ERR;
if(data_len<(p_data[10]+13)) return UART_PKT_CON;
return UART_PKT_FIN;/*UART_PKT_FIN=0*/
}
/* 协议初始化,这部分相对固定,一般不需修改 */
static BOOL pro_initialize()
{
T_UART_CONFIG config;
STATUS status;
if (dev_port == UART_PORT_A)
{
/*uart_a 是一个T_UART_CONFIG 结构,用来确定通信的波特率、校验方式等*/
config =g_sys_config.uart_a;
}
else if (dev_port == UART_PORT_B)
{
config =g_sys_config.uart_b;
}
else
{
return FALSE;
}
/*[这里用来接受程序的中断调用]*/
config.pcb =0;
/*打开串口*/
if(!UART_Open(dev_port, &config)) return FALSE;
/*底层函数,用来开辟一个资源堆栈,先进先出*/
/*可以调用DEV_LOCK_COM,和DEV_LOCK_COM函数*/
NU_Create_Semaphore(&com_lock, "COM_LOCK", 1, NU_FIFO);
/*创建一个任务,通过这个任务,我们与外设进行通信*/
status =NU_Create_Task(&m_232_task, "TASK_232", task_232, 0, NU_NULL,
m_232_stack, 0x2000, 10, 0, NU_PREEMPT, NU_START);
return(status == NU_SUCCESS);
}
/* 设备初始化 */
static BOOL pro_open_ied(const T_IED *p_ied)
{
return TRUE;
}
/* 设备服务接口,系统自动调用 */
BOOL HLDB_service(T_IED *p_ied, T_MESSAGE *p_msg)
{
BOOL ret_code =FALSE;
/* [初始化部分] */
switch(p_msg->m_type)
{
case MSG_T_INIT:/*MSG_T_INIT代表一种信息类型,在DEV_MNG.H中定义*/
return pro_initialize();/* 初始化协议 */
case MSG_T_OPEN:
return pro_open_ied((T_IED *)(p_msg->m_data));/* 初始化设备 */
default:
break;
}
/*[设备操作接口部分]如果不支持任何设备操作,可在此处立即返回FALSE.*/
return ret_code;
}
/*请求脉冲数据*/
static BOOL GetPulse(T_IED *p_ied)
{
BYTE cpu=0,i=0,dbnumber=0,len=0;
WORD Low=0,High=0;
int flag=0;
for(dbnumber=0;dbnumber<DBNUMBER;dbnumber++)/*寻检每一块表*/
{
for(cpu=1;cpu<=4;cpu++)/*每一块表询问4次*/
{
tx_buf[0] =0x68;
tx_buf[1] =DB_Address[dbnumber][4]*16+DB_Address[dbnumber][5];
tx_buf[2] =DB_Address[dbnumber][2]*16+DB_Address[dbnumber][3];
tx_buf[3] =0x20;
tx_buf[4] =0x00;
tx_buf[5] =0x00;
tx_buf[6] =0x00;
tx_buf[7] =0x68;
tx_buf[8] =0x01;
tx_buf[9] =0x02;
switch(cpu)
{
case 1://正向有功
tx_buf[10]=0x52;
tx_buf[11]=0xC3;
break;
case 2://正向无功
tx_buf[10]=0x52;
tx_buf[11]=0xC4;
break;
case 3://反向有功
tx_buf[10]=0x62;
tx_buf[11]=0xC3;
break;
case 4://反向无功
tx_buf[10]=0x62;
tx_buf[11]=0xC4;
break;
};
tx_buf[12]=0x00;
for(i=0;i<=11;i++)/*计算校验码*/
tx_buf[12]=tx_buf[12]+tx_buf[i];
tx_buf[12]=tx_buf[12]&0xff;
tx_buf[13]=0x16;
UART_Write(dev_port,tx_buf,14);/*向断口发送数据*/
/*接收数据,并检测*/
len=UART_Read(dev_port,rx_buf,2000);
if((rx_buf[0]==0x68)&&(rx_buf[8]==0x81))
{
Low=Bcd2Hex(MAKEWORD(rx_buf[12]-0x33, rx_buf[13]-0x33));
High=Bcd2Hex(MAKEWORD(rx_buf[14]-0x33, rx_buf[15]-0x33));
ym[cpu-1].ps_val[dbnumber]=High*10000+Low;
INF_Set_Pulse(cpu,&ym[cpu-1]);
}
NU_Sleep(50);
}
NU_Sleep(200);
}
return TRUE;
}
/* module's task */
static VOID task_232(UNSIGNED argc, VOID *argv)
{
BYTE i=0;
T_IED *p_ied;
p_ied=DEV_First_IED();
memset(&ym,0,sizeof(ym));
ym[0].ps_num=ym[1].ps_num=ym[2].ps_num=ym[3].ps_num=DBNUMBER;//number of YM
Loop:
NU_Sleep(3*SYS_SECOND_TICKS);
GetPulse(p_ied);
goto Loop;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -