📄 main.c
字号:
// 采集器程序更新
// 重新规划存储器管理
// 1、最大管理32只表,未初始化全F
// 2、数量管理,没有记录数的概念,只有表数量
// 3、冻结电量管理。
// 4、抄表间隔:必须是10的倍数,最大60分钟。或者是零(间隔10秒)
// 5、抄读项默认901F。
#include <pic.h>
#include "cjq.h"
#include "function.h"
#include "work.c"
#include "protocol.c"
#include "InOut.c"
#include "public.c"
#ifdef DEBUG
__CONFIG(HS& WDTDIS& PWRTDIS& BORDIS& UNPROTECT& LVPDIS);
#else
__CONFIG(HS& WDTEN& PWRTEN& BOREN& PROTECT);
#endif
//***************************************
// 编译选项,使用PICC 8.05版本
// 1、优化等级关闭
// 2、使能"enable assembler optimization"
//****************************************
//********** 主循环开始 *************
void main(void)
{
di(); //关闭所有中断
sysinit(); //系统初始化,设置相应端口
_Show485 = 1; //指示启动
Delay1msx(200);
_Show485 = 0; //指示启动
Delay1msx(200);
_Show485 = 1; //指示启动
Delay1msx(200);
_Show485 = 0; //指示启动
FMCheck(); //检测EEPROM,初始化相关参数
TimerInit(); //设置时钟芯片
variableInit(); //用户变量初始化
_Show485 = 0; //启动完成
Delay1msx(1500);
TestTask.DI0 = 0;
ei(); //打开中断
while(1) //主循环开始
{
ClrWdt(); //清看门狗
Nop();
RunTimeSet(); //设置各定时标志500ms, 1S, 1min, 60mins
Nop();
upCommCheck(); //上行指令检测,包括载波和红外。指令处理,仅仅组织帧
Nop();
Buff485Rec(); //485数据接收
Nop();
BuffPLCSend(); //载波发送
Nop();
Buff485Send(); //485发送
Nop();
AmrTaskDispose(); //处理485缓冲区的数据,上传,保存,。。。
Nop();
minTaskDispose(); //分钟任务处理, 必须放到抄表任务后!!
Nop();
AmrTaskSet(); //抄表任务定制,仅仅设置485抄读指令
Nop();
OnOffCheck(); //开盖检测
Nop();
sysCheck(); //每分钟一次
}
}
//系统运行时间参数
void RunTimeSet(void)
{
if(v_msCont >= 100u)
{
//1s!
v_msCont -= 100u;
v_ssCont++;
v_DirRetCont++;
if(v_ssCont >= 60u)
{
//1分钟
_SysCheck = 1; //每分钟一次系统检测
v_ssCont -= 60u;
minTaskSet(); //分钟任务设置
}
}
if(v_DirRetCont >= 20u)
{
//20秒,内存实时上传数据无效
lastCommBack[0] = 0;
}
if(BuffPLCMark.Sta == c_RecNow)
{
if(BuffPLCMark.otc >= c_ByteOutT) //c_ByteOutT*10ms 没有通信清载波缓冲区
{
BuffPLCMark.Sta = c_Free;
BuffPLCMark.ptr = BuffPLC;
BuffPLCMark.otc = 0;
BuffPLCMark.len = 0;
}
}
if(Buff485Mark.Sta == c_WaitRec) //等待响应
{
if(Buff485Mark.otc >= c_FrameOutT) //帧超时
{
Buff485Mark.ptr = Buff485;
Buff485Mark.Sta = c_RecOutT; //超时
Buff485Mark.otc = 0;
Buff485Mark.len = 0;
}
}
else if(Buff485Mark.Sta == c_RecNow) //接收中
{
if(Buff485Mark.otc >= c_ByteOutT) //字节超时
{
Buff485Mark.ptr = Buff485;
Buff485Mark.Sta = c_RecOutT; //超时
Buff485Mark.otc = 0;
Buff485Mark.len = 0;
}
}
else
{
if(Buff485Mark.otc >= c_BuffClrT) //2.5秒钟内没有动作
{
Buff485Mark.ptr = Buff485;
Buff485Mark.Sta = c_Free;
Buff485Mark.otc = 0;
Buff485Mark.len = 0;
TestTask.Sta = c_TaskFree;
AmrTask.Sta = c_TaskFree;
RtTask.Sta = c_TaskFree;
}
}
if((Buff485Mark.Sta == c_RecNow) || (Buff485Mark.Sta == c_Send))
{
_Show485 = 1; //指示485通信
}
else
{
_Show485 = 0;
}
}
//**********判断铁电是否初始化
void FMCheck(void)
{
getStrFM(tempBuff1, a_FMMark, l_FMMark); //获取铁电中,特征字
highmemcpypgm2ram(MeterID, RomFMMark, l_FMMark); //固定特征字
if(0x0 == highmemcmp(tempBuff1, MeterID, l_FMMark)) //比较是否一致
{
return; //相等,已初始化
}
//未初始化,初始化铁电
v_ExtRunFlag = c_FMInit;
FMInit();
//32个表地址写入0xff,32*6=192,一次最大写入4*6=24字节
v_ExtRunFlag = c_FMSet;
if(_TRUE != FMSet(a_MeterID, 0xff, 192))
{
Reset();
}
}
//********** 初始化外部存储器
void FMInit(void)
{
v_IntRunFlag = c_FMInit;
safeCheck();
//2.抄表间隔
tempBuff[0] = 0xff;
v_ExtRunFlag = c_putStrFM;
putStrFM(a_AmrSpace, tempBuff, 0x01u);
//3. 设置冻结日时
tempBuff[0] = 0x00u;
tempBuff[1] = c_FreezeData;
v_ExtRunFlag = c_putStrFM;
putStrFM(a_FreezeTime, tempBuff, 0x02u);
//4. EEPROM初始化标志
highmemcpypgm2ram(tempBuff, RomFMMark, l_FMMark);
v_ExtRunFlag = c_putStrFM;
putStrFM(a_FMMark, tempBuff, l_FMMark);
}
//**********设置时钟芯片参数
void TimerInit(void)
{
//关闭所有中断输出,时间格式(12 24),设置复位电平
tempBuff[0] = c_RTCINTAOFF;
tempBuff[1] = c_RTCINTB;
v_ExtRunFlag = c_putStrRTC;
if(_FALSE == putStrRTC(0x0e, tempBuff, 0x02)) //0x0e是设置寄存器地址
{
Reset();
}
}
//********* 初始化用户变量
void variableInit(void)
{
unsigned char temp;
BuffPLCMark.len = 0;
Buff485Mark.len = 0;
BuffPLCMark.ptr = BuffPLC;
Buff485Mark.ptr = Buff485;
BuffPLCMark.Sta = c_Free;
Buff485Mark.Sta = c_Free;
Buff485Mark.goal = c_Free;
BuffPLCMark.RetCont = 0; //透传抄读指令直接上传次数
RtTask.Sta = c_TaskFree; //默认没有实时任务
AmrTask.start = c_TaskAllStart; //上电马上开始自动抄表
AmrTask.serial = 0; //抄表序号 = 0
AmrTask.Sta = c_TaskFree; //目前抄读状态空闲,可以设置电表进行抄读
v_hhTask = 0xff; //小时任务不处理
v_FreezeTask = 0; //冻结任务不处理
lowmemset(lastCommBack, 0, 5);
lowmemset(BuffPLC, 0, c_BuffMax);
highmemset(Buff485, 0, c_BuffMax-6);//485缓冲区比载波少6字节!!
//采集器号
getStrFM(CollectorID, a_CollecterID, 6u);
//获取当前时间
getStrRTC(timerBuff, 0, 7); //ss,mm,hh,WW,DD,MM,YY
highmemcpy(timerBuff+3, timerBuff+4, 3);
v_msCont = 0;
temp = timerBuff[0];
v_ssCont = bytebcdtohex(temp);
temp = timerBuff[1];
v_mmCont = bytebcdtohex(temp);
temp = timerBuff[2];
v_hhTask = bytebcdtohex(temp);
v_FreezeTask= timerBuff[3];
}
//系统初始化相关
void sysinit(void)
{
//bank0
ADCON0 = c_ADcon0;
//bank1
ADCON1 = c_ADcon1;
TRISA = c_TrisA;
TRISB = c_TrisB;
TRISC = c_TrisC;
OPTION = c_Option;
INTCON = c_INTcon;
PIE1 = c_Pie1;
PIE2 = c_Pie2;
PR2 = c_SimBaud;
TXSTA = c_TXsta;
// SPBRG = v_baud485;
//bank0
PIR1 = 0;
PIR2 = 0;
PORTA = 0;
PORTB = 0xff;
PORTC = 0xff;
T1CON = c_T1con;
T2CON = c_T2con9600;
SSPCON = c_SSPcon;
CCP2CON = c_CCP2con;
CCP1CON = c_CCP1con & 0xf0;
CCPR1L = c_CCPR1L;
CCPR1H = 0;
RCSTA = c_RCsta;
if(OERR)
{
CREN = 0;
CREN = 1;
asm("movf _RCREG, w");
asm("movf _RCREG, w");
}
}
//系统检测
void sysCheck(void)
{
if(c_INTcon != (INTCON & c_INTcon))
{
INTCON = c_INTcon;
}
if(PIE1 != c_Pie1)
{
PIE1 = c_Pie1;
}
if(_SysCheck == 0) return;
_SysCheck = 0;
//bank0
ADCON0 = c_ADcon0;
//bank1
ADCON1 = c_ADcon1;
TRISA = c_TrisA;
TRISB = c_TrisB;
TRISC = c_TrisC;
OPTION = c_Option;
if(PIE2 != c_Pie2)
{
PIE2 = c_Pie2;
}
PR2 = c_SimBaud;
//bank0
T1CON = c_T1con;
T2CON = c_T2con9600;
SSPCON = c_SSPcon;
CCP2CON = c_CCP2con;
CCP1CON = c_CCP1con & 0xf0;
CCPR1L = c_CCPR1L;
CCPR1H = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -