📄 main.c
字号:
{
TotleTimeOfMiuns++;
if(TotleTimeOfMiuns>=60)
{
SaveTimeOfMiuns();
}
}
// 如果当前为正向,则强制保存反向累计时间
else
{
SaveTimeOfMiuns();
}
// 刷新费率属性(关中断时间应尽量短)
ptcnt=(unsigned char)((PowerAttribute&ATTRIBUTE_OF_PLUS_MINUS)|temp);
_DINT();
PowerAttribute=(unsigned char)ptcnt;
_EINT();
}
//掉电及低压检测
void BreakOrLowPowerTest(unsigned char tstPin)
{
if(P1IN&tstPin)
{
BreakOrLowPowerFlag&=~(tstPin);
}
else//检测到掉电或低压
{
if(!(BreakOrLowPowerFlag&tstPin))
{
//保存掉电或低压标志
BreakOrLowPowerFlag|=tstPin;
// 如果掉电,则进行数据保存
if(BreakOrLowPowerFlag&BRK_PWR_TST)
{
// 保存RAM中的脉冲数据到Flash
PowerDataStore();
// 保存反向累计时间
SaveTimeOfMiuns();
}
//保存最后一次掉电或低压时间
_save_time_to_e2prom_(ADDRESS_OF_LAST_BREAK_POWER_TIME+(tstPin>>7)*6);
}
if(BreakOrLowPowerFlag&BRK_PWR_TST)
{
// 强制把电流方向转为正向
_DINT();
PowerAttribute=(unsigned char)(PowerAttribute&0x03);
_EINT();
}
}
}
void ProgramEnableTest(void)
{
if(PROG_EN_IN&PROG_EN)
LcdDisplayChoose&=~0x1000;
else
LcdDisplayChoose|=0x1000;
}
void OnUserkey(void)
{
if(P2IN&USERKEY0)
{
if(LcdDispPageUpOrDown>=0x50)
{
LcdDispPageUpOrDown=USERKEY_SELECT;
LcdSelectPage();
}
}
else
{
LcdDispPageUpOrDown=USERKEY_VIEW;
LcdViewPage();
}
}
// 电表基本初始化
void DeviceBasicInit(void)
{
#ifdef _HARDWARE_RTC
unsigned char on_off;
#endif
_DINT();
//WDTCTL=WDTPW+WDTHOLD;
WDTCTL=WDTPW+WDTSSEL+WDTCNTCL;
// Basic Timer初始化相关
IE2|=BTIE; // Enable BT interrupt
FLL_CTL0|=XCAP18PF; // Configure load caps
FLL_CTL1|=FLL_DIV_8;
BTCTL=BT_ADLY_125+BT_fLCD_DIV128;
// Init Port 1
// Including:RS_D(1.0),RS_R(1.1),IR_IN(1.2),BELL(1.3),PROG_EN(1.4),RTC_OUT(P1.5),PWR_F0(P1.6),PWR_F1(P1.7)
P1DIR=(RS485_TX+BELL+RTC_FREQ);
P1SEL|=BIT5;
P1OUT|=(RS485_TX+BELL);
P1IES|=(RS485_RX+IR_RX);
// Init Port 2
// Including:IR_OUT(2.0),POWER_PULSE(2.1),LCD_LIGHT(2.5),USERKEY0(2.2),STA_UP(2.3)
P2DIR=(IR_TX+LCD_LIGHT);
P2OUT|=(IR_TX+LCD_LIGHT);
P2IES=0;
P2IE|=(USERKEY0+POWER_PULSE);
// Init Port 6
// Including:WDT(P6.0),P6_1(6.1),P6_2(6.2),E2PROM_WP(6.3),RS485_EN(6.4),POWER_DIRECTION(6.5),I2C_SDA(6.6),I2C_SCL(6.7)
P6DIR=(P6_1+P6_2+RS485_EN+E2PROM_WP+I2C_SCL+I2C_SDA+WDT);
P6OUT|=(P6_1+P6_2+I2C_SCL+I2C_SDA+E2PROM_WP+RS485_EN);
// 延时几秒钟,等待RTC状态稳定
BellOn();
#ifdef _HARDWARE_RTC
RenewSystemTime();
#endif
DefaultInit();
ReadPPC();
// 电表事件初始化
SetSystemEvent(EVENT_01_SECOND|EVENT_01_MINUTE);
// 读取显示配置信息
ResetLcdDisplay();
#ifdef _SUPPORT_RELAY
// 继电器状态初始化
E2promRead(ADDRESS_OF_RELAY_STATE,&on_off,1);
if((on_off!=RELAY_OPEN)&&(on_off!=RELAY_CLOSE))
{
on_off=RELAY_CLOSE;
}
RelayCtrl(on_off);
#endif
#ifdef _HARDWARE_RTC
// RTC初始化
on_off=0x23;// 24小时进制,秒输出
RealtimeOper(0xE0,&on_off,1);
// Init Pulse Mode,output 1 Hz
on_off=0x20;//掉电电压:2.1V;
RealtimeOper(0xF0,&on_off,1);
#endif
// LCD初始化
LCDCTL=0x5F;
BTCTL|=BTFRFQ1;
P5SEL=0xFC;
}
void main(void)
{
DeviceBasicInit();
_bcd_short_add1_and_write_e2prom_(ADDRESS_OF_CPU_RESET_CNT);
// 强制存储,为了避免复位而引起的校验错误
PowerDataStore();
for(;;)
{
ClrWDT();
if(SystemIndication&EVENT_SERIAL_PORT)
{
if(!Rx_FrameInfo())
{
LCDMEM[LCD_ADDRESS_OF_TONGXIN]|=LCD_OF_TONXIN;
Parse_RxFrame();
}
UartReInit();
ClearSystemEvent(EVENT_SERIAL_PORT);
}
ClrWDT();
if(SystemIndication&EVENT_KEY_DOWN)
{
Delay(6000); // 此延时为了滤波(30ms)
if(!(LcdDispPageUpOrDown&USERKEY_JUST))
{
if(P2IN&USERKEY0)
{
LcdLightOn(15);
TimerCounter[1]=15;
TimerProc[1]=ResetLcdDisplay;
LcdDispPageUpOrDown|=USERKEY_JUST;
}
}
Delay(5000);
ClearSystemEvent(EVENT_KEY_DOWN);
}
ClrWDT();
if(SystemIndication&EVENT_KEY_DETECT)
{
OnUserkey();
ClearSystemEvent(EVENT_KEY_DETECT);
}
ClrWDT();
if(SystemIndication&EVENT_POWERMINUS)
{
// 记录反向起始时间
_save_time_to_e2prom_(ADDRESS_OF_START_TIME_MINUS);
ClearSystemEvent(EVENT_POWERMINUS);
}
ClrWDT();
if(SystemIndication&EVENT_01_SECOND)
{
PowerPulseCalculate();
#ifdef _HARDWARE_RTC
GetSystemTime();
#else
SecondUp();
#endif
ProgramEnableTest();
RedundancyTimerProc();
UartReInit();
ClrWDT();
if(SystemIndication&EVENT_01_MINUTE)
{
BreakOrLowPowerTest(BRK_PWR_TST);
#if _SUPPORT_LOW_POWER_DETECT
BreakOrLowPowerTest(LOW_PWR_TST);
#endif
ExesAttributeDetect();
MonthSpanDetect();
ClearSystemEvent(EVENT_01_MINUTE);
}
DisplayRefresh();
ClearSystemEvent(EVENT_01_SECOND);
}
ClrWDT();
// 剔除无用位
ClearSystemEvent(EVENT_REVERSED);
if(!SystemIndication) _BIS_SR(LPM3_bits);
}
}
#pragma vector=BASICTIMER_VECTOR
__interrupt void BasicTimer(void)
{
SystemTimeTick++;
if(SystemTimeTick>=8)
{
SystemTimeTick=0;
#ifndef _HARDWARE_RTC
g_time[SPACE_OF_SECOND]++;
#endif
SystemIndication|=EVENT_01_SECOND;
_BIC_SR_IRQ(LPM3_bits);
}
if(LcdDispPageUpOrDown&USERKEY_JUST)
{
LcdDispPageUpOrDown+=0x10;
SystemIndication|=EVENT_KEY_DETECT;
_BIC_SR_IRQ(LPM3_bits);
}
if(UartRxByteTime++==2)
{
UartBitCount=0;
UartState=UART_RXD_OVERTIME_ERR;
}
}
#pragma vector=PORT2_VECTOR
__interrupt void Port2(void)
{
if(POWER_PULSE_IFG&POWER_PULSE)
{
_NOP();
_NOP();
if(POWER_PULSE_IN&POWER_PULSE)
{
PowerPulseCounter++;
// 电流方向确认()
if(POWER_DIRECTION_IN&POWER_DIRECTION)
{
// 如果之前电流方向为正向
if(!(PowerAttribute&ATTRIBUTE_OF_PLUS_MINUS))
SystemIndication|=EVENT_POWERMINUS;
// 刷新为反向
PowerAttribute=(unsigned char)((PowerAttribute|ATTRIBUTE_OF_PLUS_MINUS)&0x07);
}
else
{
// 刷新为正向
PowerAttribute=(unsigned char)(PowerAttribute&0x03);
}
}
// 清中断标志
P2IFG=0;
}
else
{
// 置按键事件
SystemIndication|=EVENT_KEY_DOWN;
// 除脉冲中断,其他中断标志全清
P2IFG&=POWER_PULSE;
_BIC_SR_IRQ(LPM3_bits);
}
}
void DefaultInit(void)
{
unsigned char data[8];
E2promRead(ADDRESS_OF_DEVICE_STATUS_MAIN,data,1);
if(data[0]!=DEVICE_OK)
{
// 清零脉冲计数
ClearPowerPulseDataInRam();
//清反向累计时间
//TotleTimeOfMiuns=0;
// 写软件版本号(2004-11-11)
data[4] = 0x04; data[3] = 0x11; data[2] = 0x11;
// 写硬件版本号(2004-09-09)
data[7] = 0x04; data[6] = 0x09; data[5] = 0x09;
// 初始化状态及版本号
data[0]=DEVICE_OK;
E2promWrite(ADDRESS_OF_DEVICE_STATUS_MAIN,data,8);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -