📄 base.c
字号:
/////////////////////////////////////////////////////////////////////////////////////
// 程序名: BaseInitial.c //
// 包含系统运行前进行的初始化函数 //
/////////////////////////////////////////////////////////////////////////////////////
#include "math.h"
#include "BaseVariable.h"
#define EEPPAGELENGTH 128 //EEP一个扇区的长度
RUN_USET uSubAddress; //通信地址,自检任务写
RUN_USET uPassword; //口令,自检任务写
RUN_USET uPTRate; //PT变比,自检任务写
RUN_USET uCTRate; //CT变比,自检任务写
RUN_USET uSetZone; //地址区号,自检任务写
UNSIGNED uSaveBuffer[1024]; //保存数据缓冲区,自检任务写
UNSIGNED EEP_ErrorFlag; //EEP出错标志,自检任务写
UNSIGNED uRunnigFlag; //运行标志,初始化写
UNSIGNED uSaveSetZone; //将修改后的定值固化到该区,显示任务写
UNSIGNED EEPPage[EEPPAGELENGTH]; //拷贝出EEP一个扇区的内容并修改,然后写回EEP,自检任务写
UNSIGNED Uabcnt,Ubccnt,Ucacnt; //线电压有压计数
REPORT ReportRAM[REPORTRAM]; //RAM中报文队列,多个任务写*****
REPORT *pReportIN = ReportRAM; //指向RAM中报文队列的指针,自检任务写
REPORT *pReportSave = ReportRAM; //指向RAM中报文队列的指针,自检任务写
REPORT *pReportDISP = ReportRAM; //指向RAM中报文队列的指针,显示任务写
REPORT *pReportRVT = ReportRAM; //指向RAM中报文队列的指针,多个任务写
IQDSTRU IQD; //电流突变量启动相关单元,保护任务写
float *CalculatePtr; //本次计算时的采样指针,保护任务写
EEP_REPORT *pEEP_REPORT; //指向EEP报告区的指针,自检任务写
UNSIGNED uReportNum; //报告数,自检任务写
UNSIGNED *pDIN1PORT = (UNSIGNED *)DIN1PORT, *pDIN2PORT = (UNSIGNED *)DIN2PORT; // I/O地址
UNSIGNED *pLCD1PORT = (UNSIGNED *)LCD1PORT, *pDOPORT = (UNSIGNED *)DOPORT; // I/O地址
UNSIGNED *pCTRLPORT = (UNSIGNED *)CTRLPORT, *pKEYPORT = (UNSIGNED *)KEYPORT; // I/O地址
unsigned char *Com_Port1 = (unsigned char *)COM1PORT, *Com_Port2 = (unsigned char *)COM2PORT; // I/O地址
unsigned char *Com_Port3 = (unsigned char *)COM3PORT, *Com_Port4 = (unsigned char *)COM4PORT; // I/O地址
UNSIGNED *pADPORT = (UNSIGNED *)ADPORT, *pDIN3PORT = (UNSIGNED *)DIN3PORT; // I/O地址
extern UNSIGNED CT_backup,PT_backup; //CT变比,PT变比,显示任务写
extern UNSIGNED CtrlOutBuf; //控制口输出缓存
extern EEP_SET uAmendCoeff[CHL_Number]; //模入修正系数,自检任务写
extern EEP_SET uAmendAngle[CHL_Number]; //模入修正角度,自检任务写
#pragma DATA_SECTION(uSubAddressEEP,".NVRAM1"); //保存在EEP中的通信地址,自检任务写
#pragma DATA_SECTION(uPasswordEEP,".NVRAM1"); //保存在EEP中的口令,自检任务写
#pragma DATA_SECTION(uSetZoneEEP,".NVRAM1"); //保存在EEP中的定值区号,自检任务写
#pragma DATA_SECTION(uPTRateEEP,".NVRAM1"); //保存在EEP中的PT变比,自检任务写
#pragma DATA_SECTION(uCTRateEEP,".NVRAM1"); //保存在EEP中的CT变比,自检任务写
#pragma DATA_SECTION(uJumperEEP,".NVRAM1"); //保存在EEP中的压板,自检任务写
#pragma DATA_SECTION(uSettingEEP,".NVRAM2"); //保存在EEP中的定值,自检任务写
#pragma DATA_SECTION(uReportEEP,".NVRAM3"); //保存在EEP中的报告,自检任务写
EEP_SET uSubAddressEEP,uPasswordEEP,uSetZoneEEP;
EEP_SET uPTRateEEP,uCTRateEEP;
UNSIGNED uJumperEEP[20];
UNSIGNED uSettingEEP[SETTINGNUM][256];
EEP_REPORT uReportEEP[EEP_REPORTNUM];
VOID StartSaveToEEP(VOID); //启动保存数据,自检任务用
VOID SaveToEEP(UNSIGNED); //将数据保存到EEP,自检任务用
UNSIGNED LoadUSET(UNSIGNED *pSRC, UNSIGNED *pDST); //从EEP中装入整数,初始化用
VOID SaveUSET(UNSIGNED *pSRC, UNSIGNED *pDST); //往EEP中保存整数,自检任务用
VOID WriteEEP(UNSIGNED*, UNSIGNED*, UNSIGNED); //往EEP中保存指定字节长度的数据,自检任务用
VOID DMAWriteEEP(UNSIGNED*); //启动DMA写数据,自检任务用
VOID Revert(VOID); //复归信号,自检任务用
UNSIGNED ProtectDeclare(VOID); //判断是否运行保护,保护任务用
VOID Base_Varible_Initialize(VOID); //基本变量初始化,初始化用
/***********************************************************************************/
/* 基础变量初始化 */
/* 使用范围:初始化用 */
/***********************************************************************************/
VOID Base_Varible_Initialize(VOID)
{
UNSIGNED l,ByteData[4*PULSENUM];
register UNSIGNED i,j,k,*pByte,*pWord;
register PROTECT *protect;
register SETTING *pSets;
register EEP_REPORT *pEEP1;
register DISTRU *pDI = DIChn;
register CHECK *check;
Switchin_buf = (*pDIN1PORT & 0xFFFF) | ((*pDIN2PORT & 0xFFFF) << 16); //开入稳态值初始化
SoftTime.DI[0] = Switchin_buf; //开入暂态值初始化
for (i = 0, j = 1; i < DI_Number; i++, j <<= 1) //开入结构体状态位初始化
{
if (!(Switchin_buf & j)) pDI->state = 1;
pDI++;
}
*pDOPORT = Switchout_buf; //开出初始化
*pCTRLPORT = CtrlOutBuf; //控制口初始化
//脉冲计数初始化
DS1302BurstRead(0xff, ByteData, 4*PULSENUM); //从DS1302中读出脉冲数
pByte = ByteData;
pWord = PulseCounter;
for (i = 0; i < PULSENUM; i++) //将8位数组合为32位数
{
*pWord++ = (*pByte++ & 0xff) | (*pByte++ & 0xff) << 8 | (*pByte++ & 0xff) << 16
| (*pByte++ & 0xff) << 24;
}
//报告存储地址初始化:序号为0xffff,或序号最小者。
pEEP1 = uReportEEP; //指向报告存储首地址
j = 0xffff; //序号设为最大
for (i = 0; i < EEP_REPORTNUM; i++) //逐个检查报告区
{
k = ((pEEP1->uReportEEPNumH & 0xff) << 8) | (pEEP1->uReportEEPNumL & 0xff);
if (k == 0xffff) //序号为0xffff,说明该区为空,可以使用
{
pEEP_REPORT = pEEP1; //pEEP_REPORT指向可使用区
break;
}
if (j > k) //找到最小序号的区
{
j = k;
pEEP_REPORT = pEEP1; //pEEP_REPORT指向最小序号的区即最老的区
}
pEEP1++;
}
pEEP1 = pEEP_REPORT; //根据上一区的序号定本区的序号
if (--pEEP1 < uReportEEP) pEEP1 = &uReportEEP[EEP_REPORTNUM - 1]; //pEEP1指向上一区
k = ((pEEP1->uReportEEPNumH & 0xff) << 8) | (pEEP1->uReportEEPNumL & 0xff); //读上一区序号
uReportNum = (k == 0xffff ? 0 : k); //k=0xffff,则序号为零,否则为上一次序号
//设置初始化
subAddress_backup = LoadUSET((UNSIGNED *)&uSubAddressEEP,(UNSIGNED *)&uSubAddress);
password_backup = LoadUSET((UNSIGNED *)&uPasswordEEP,(UNSIGNED *)&uPassword);
iLONC_SetZoneNum = LoadUSET((UNSIGNED *)&uSetZoneEEP,(UNSIGNED *)&uSetZone);
CT_backup = LoadUSET((UNSIGNED *)&uCTRateEEP,(UNSIGNED *)&uCTRate);
PT_backup = LoadUSET((UNSIGNED *)&uPTRateEEP,(UNSIGNED *)&uPTRate);
pByte = uJumperEEP; //指向存储压板EEP的指针
protect = PRO_Created_Protect_List;
for (i = 0; i < PRO_Total_Protect; i++, protect = protect->pro_link_next)
{
(protect->pro_jumper)->jum_status = *pByte++ & 0xff;
}
for (j = 0; j < SETTINGNUM; j++) //将全部定值区内的定值读到保护结构体
{
pByte = uSettingEEP[j]; //指向EEP中第j区定值的指针
protect = PRO_Created_Protect_List; //保护列表指针
for (i = 0; i < PRO_Total_Protect; i++, protect = protect->pro_link_next)
{
pSets = protect->pro_setting;
for (k = 0; k < protect->pro_setting_number; k++)
{
l = *pByte++ & 0xff;
l |= (*pByte++ & 0xff) << 8;
l |= (*pByte++ & 0xff) << 16;
l |= (*pByte++ & 0xff) << 24;
pSets->set_value_zone[j] = *((float *)&l);
pSets++;
}
}
}
check = CHK_Created_Check_List; //将全部设置自检一遍
for (i = 0; i < CHK_Total_Check; i++, check = check->chk_link_next)
(*(check->chk_routine_handler))(check);
uRunnigFlag = 1;
}
/***********************************************************************************/
/* 判断是否运行保护程序: 1运行,0不运行 */
/* 如果装置出错:返回0 */
/* 保护已经启动,且已经经过一个周波,返回1 */
/* 使用范围:保护任务用 */
/***********************************************************************************/
UNSIGNED ProtectDeclare(VOID)
{
register UNSIGNED i,j;
register PROTECT *protect;
CalculatePtr = Sample_Ptr;
if (IQD.QDB) //是否启动
{
if (IQD.WaitFlag) //WaitFlag为1,说明电流突变量启动,且启动时间不满一周
{
i = Sample_Ptr - IQD.IqdPtr; //启动后经过的采样点数
if (i >= AD_OneDataSize - 1)
i += AD_OneDataSize - 1;
if (i >= Sample_Point) //是否已启动一个周波
{
Uabcnt = 10;
Ubccnt = 10;
Ucacnt = 10;
IQD.WaitFlag = 0; //启动时间满一周,WaitFlag清0
return(1); //返回1,运行保护程序
}
else
{
return (0); //返回0,不运行保护程序
}
}
else //WaitFlag为0,说明电流突变量启动,且正在运行保护程序
{
if (!DOChn[QDJ].state && (TMD_System_Clock - IQD.Iqdsj) > 100)
IQD.QDB = 0; //电流突变量启动后,启动继电器未动,说明保护未启动,清QDB
return(1);
}
}
else //QDB为0,返回1,运行保护程序,相当于稳态启动判别
{
return(1);
}
}
/**********************************************************/
/* Fill_Report(REPORT *ptr) */
/* 将报告填入RAM区 */
/* 使用范围:多个任务用 */
/**********************************************************/
VOID Fill_Report(REPORT *ptr)
{
UNSIGNED j;
register UNSIGNED *p,i;
register UNSIGNED *p1 = (UNSIGNED *)ptr;
register OPTION old_preempt;
old_preempt = NU_Change_Preemption(NU_NO_PREEMPT); //不再切换任务,避免被其他任务打断,造成误动
p = (UNSIGNED *)pReportIN;
if (++pReportIN > &ReportRAM[REPORTRAM - 1]) pReportIN = ReportRAM; //指向下一区,并判数组越界
for (i = 0; i < sizeof(REPORT); i++) *p++ = *p1++;
NU_Change_Preemption(old_preempt); //可以切换任务
j = SAVE_REPORT;
NU_Send_To_Queue(&SaveQueue,&j,1,NU_SUSPEND);
}
/**********************************************************/
/* JUMPER_Change(JUMPER *ptr) */
/* 填压板改变报告 */
/* 使用范围:多个任务用 */
/**********************************************************/
VOID JUMPER_Change(JUMPER *pJUMPER)
{
static REPORT JumperReport;
register REPORT *pJumperReport;
register SOE *pSOE;
register CHAR *pCHAR1,*pCHAR2;
register JUMPER *ptr = pJUMPER;
register UNSIGNED i;
register OPTION old_preempt;
old_preempt = NU_Change_Preemption(NU_NO_PREEMPT); //不再切换任务,避免被其他任务打断,造成误动
pJumperReport = &JumperReport; //指向压板报告
pSOE = &pJumperReport->pro_report_soe;
pCHAR1 = ptr->pjum_name; //拷贝名称
pCHAR2 = pSOE->SOE_name;
for (i = 0; i < JUMPER_NAME; i++)
{
if (*pCHAR1 != '\0')
*pCHAR2++ = *pCHAR1++;
else
break;
}
if (ptr->jum_status == 1)
{
pCHAR1 = "投入";
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -