📄 dds18838104.c
字号:
/***********************************************************************/
/* */
/* FILE :DDS18838104.c */
/* DATE :Wed, Jul 20, 2005 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :H8/38104F */
/* */
/* This file is generated by Renesas Project Generator (Ver.3.1). */
/* */
/***********************************************************************/
/* 宁波三星科技有限公司 */
/* 文件名:DDS18838104.C */
/* 说明1: 该程序是根据广东单相电子表(液晶显示)的技术特点而开发 */
/* 说明2: 该程序是基于HD64F38104基础上而设计 */
/* 作者: 叶孟军 */
/* 开始日期:2005年7月22日 */
/****************************************************************/
#include <machine.h>
#include <stdio.h>
#include "data.h"
#include "union.h"
#include "iodefine.h"
#include "edit.h"
void Power_Lvi(void);
void main(void);
void Rtc_Judge(void);
/********************************************************************************/
#define Re_Te (IO.PDR4.BIT.B0) //控制RS485发送/接收
#define Key_Int (IO.PDRB.BIT.B2)
#define Power_Io_Data (IO.PDR5.BIT.B0)
#define NOP {nop();nop();}
#define Revp_Curr (IO.PDRB.BIT.B1)
#define Revp_Led (IO.PDR9.BIT.B2)
/********************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
void abort(void);
#ifdef __cplusplus
}
#endif
/****************************************************************************/
//以下为38104各寄存器单元置初值
/****************************************************************************/
void Tma_Define(void) //定时器A定义,1s定时
{
CKSTPR1.BYTE |= 0x01;
TMRA.TMA.BYTE = 0x18;
}
/****************************************************************************/
void Tmf_Define(void) //定时器F定义,定时器FH定时频率为1/1200,定时器FL定时频率为1/600
{
CKSTPR1.BYTE |= 0x04;
TMRF.TCRF.BYTE = 0x45; //定时器FH内部时钟为φ/16,定时器FL内部时钟为φ32
TMRF.OCRFH = 0xFF;
TMRF.OCRFL = 0xFF;
TMRF.TCSRF.BYTE = 0x11; //采用溢出中断
TMRF.TCFH = 0x00;
TMRF.TCFL = 0x00;
}
/****************************************************************************/
void Int_Define(void) //中断定义
{
IEGR.BYTE &= 0xFC; //IRQ1 与 IRQ0 采用下降沿触发中断
IENR1.BYTE = 0xC3; //定时器A、键盘中断、IRQ1、IRQ0允许中断
IENR2.BYTE = 0x0C; //定时器FH、定时器FL中断开启
}
/****************************************************************************/
void Sci_Define(void) //SCI 定义
{
unsigned char i;
CKSTPR1.BYTE |= 0x20; //开启SCI
SCI3.SMR.BYTE = 0x20; //SCI模式设置为异步、1bit起始位、8bit数据位、1为偶校验位、1位停止位,SCI时钟源采用φ/16
SCI3.BRR = 0x7F; //1200bit/s通讯速率
SCI3.SCR3.BYTE = 0x50; //接收中断使能
SPCR.BYTE = 0x20; //TXD32使能
i = SCI3.SSR.BYTE;
SCI3.TDR = 0xff;
SCI3.SSR.BYTE = 0x00;
Re_Te = 1; //RS485处于接收状态
}
/****************************************************************************/
void Pwm_Define(void) //PWM定义
{
PWM1.PWCR.BYTE = 0x00; //PWM选用时钟源为φ/512
PWM1.PWDRL = 0x04;
PWM1.PWDRU = 0xFE;
CKSTPR2.BYTE &= 0xED; //PWM1、PWM2关闭
}
/****************************************************************************/
void Lcd_Define(void) //LCD定义
{
CKSTPR2.BYTE |= 0x01; //LCD模块开启
LCD.LPCR.BYTE = 0xC9; //设定LCD工作方式: DTS1 DTS0 CMX - SGS3 SGS2 SGS1 SGS0
LCD.LCR.BYTE = 0x30; //LCD模块电源模式设定为外部电源模式
LCD.LCR2.BYTE = 0x00;
}
/****************************************************************************/
void WatchDog_Define(void) //WATCHDOG定义
{
CKSTPR2.BYTE |= 0x04; //WATCHDOG模块开启
IO.PMR2.BYTE &= 0xFB; //WATCHDOG时钟源采用TMW
WDT.TCSRW.BYTE = 0x7F;
TMW.BYTE = 0xF0; //watchdog time = 200ms -400ms
WDT.TCW = 0x01;
}
void WatchDog_Set(void) //喂狗
{
WDT.TCW = 0x01;
}
/****************************************************************************/
void Ad_Define(void) //AD模块定义
{
CKSTPR1.BYTE |= 0x10;
AD.AMR.BYTE = 0x34; //AN0
// AD.ADSR.BYTE = 0x80;
}
/****************************************************************************/
void Io_Define(void) //I/O定义
{
IO.PUCR3.BYTE = 0xC6; //SCL、SDA、WP、IRTXD需内部上拉
IO.PCR3 = 0xC6; //SCL、SDA、WP、IRTXD为输出
IO.PMR3.BYTE = 0x00;
IO.PMR2.BYTE = 0x01; //P43作为IRQ0功能使用
IO.PCR4 = 0x05; //P40、P42作为输出功能
SPCR.BYTE = 0x20; //P42作为TXD口使用
IO.PCR5 = 0xfE; //POWER作为输入、WP1、SCL1、SDA1作为输出
IO.PUCR5.BYTE = 0x0E; //WP1、SCL1、SDA1需内部上拉
IO.PDR5.BYTE = 0xff;
IO.PMR5.BYTE = 0x01; //打开键盘中断0
IO.PMR9.BYTE = 0x01; //PWM1使用
IO.PMRB.BYTE = 0x08; //IRQ1使用
IO.PDR9.BYTE = 0x2e; //LED1、LED2、CF_TEST置高
}
/*****************************************************************************/
void Io_initial(void) //I/O置初值
{
IO.PMR3.BYTE = 0x00;
IO.PMR2.BYTE = 0x00;
IO.PMR5.BYTE = 0x00;
IO.PMR9.BYTE = 0x00;
IO.PMRB.BYTE = 0x00;
IO.PUCR3.BYTE = 0x00;
IO.PCR3 = 0x00;
IO.PCR4 = 0x00;
IO.PUCR5.BYTE = 0x00;
IO.PCR5 = 0x00;
IO.PMR9.BYTE = 0xf8;
IO.PDR9.BYTE = 0x2e;
}
void SubActive_Define(void)
{
SYSCR1.BYTE = 0x8f;
SYSCR2.BYTE = 0xE8;
}
void Active_Mode(void)
{
Tma_Define();
set_imask_ccr(0);
IENR1.BYTE = 0x80;
SYSCR1.BYTE = 0x87;
SYSCR2.BYTE = 0xE8;
NOP;
sleep();
NOP;
IENR1.BYTE &= 0x7F;
set_imask_ccr(1);
}
void PowerLvi_Define(void)
{
CKSTPR1.BYTE = 0x00;
CKSTPR2.BYTE = 0x00;
IENR1.BYTE = 0x00;
IENR2.BYTE = 0x00;
Tma_Define();
IENR1.BYTE |= 0x80;
IRR1.BYTE = 0x00;
IRR2.BYTE = 0x00;
Lcd_Define();
RShftDspTm_Dtr[0] = 0x02;
RStpDspTm_Dtr[0] = 0x03;
Io_initial();
LCD.LCR.BYTE |= 0x40; //LCD模块电源模式设定为内部部电源模式
set_imask_ccr(0); //开中断
}
/****************************************************************************/
void Ram_Define(void) //ram区定义
{
unsigned char i;
BufferHead_Comm = BufferInOut_Comm;
BufferTail_Comm = BufferInOut_Comm;
Cf_Star=0x00; //脉冲成立标志清零
// Led_Cnt = 0x40; //脉冲指示计数器值 >48
DlStar_Reg = 0x00; //0.01kWh电量产生标志清零
system_timer_in_13ms=0x00;
TxRxTime_Comm = system_timer_in_13ms;
for(i=0;i<BufferInOutMax_Comm;i++)
{
BufferInOut_Comm[i]=0x00;
}
Power_Flg.BYTE = 0x02; //系统认为上电信号生成
TimDef_Reg.BYTE = 0x00;
Flag_Comm.BYTE = 0x00; //通讯置为接收状态
Rx_Command_Flg.BYTE = 0x00;
Txrx_state.BYTE = 0x00;
TxData_state.BYTE = 0x00;
Cf_int_reg.BYTE = 0x00;
Trig_Byte=0x01;
Disp_WORD = 0x0000;
Other_Byte = 0x00;
AccdntRcd_Byte = 0x00;
Cf_Flg.BYTE = 0x00;
Sys_Reg.BYTE = 0x00;
CoutSign_Len=0x00;
Key_Cnt=0x00;
RMtWd_Dtr[0] = 0x00; //电表信息字清零
RttPnter_Disp = 0x10;
KeyPnter_Disp = 0x00;
NghtCtDown_Disp = 0x00;
Progrm_DispCnt = 0x00;
CtDown_Disp = 0x00;
TmSctNo_Disp=0x09;
NewComDisp_Tm = 0;
CoutSign_Len=0x00;
DI1DI0_Comm=0x0000;
DlStar_Reg = 0;
DispAllOn_Flg = 0x38;
Hello_Flg = 0x00;
End_Flg = 0x00;
Error_Flg = 0x00;
Txd_Fe_Cnt = 0;
Tmfh_Cnt = 0x00;
CrntRStr_Flg[0] = 0x00; //反向标志清除
Cf_Alt_TmCnt = 0; //脉冲间隔时间计数清零
for(i=0;i<4;i++)
{
REnger_Clr[i] = 0x00;
}
}
/****************************************************************************/
//Cf_Judge程序完成电量计量、储存功能
void Cf_Add(unsigned char *addr)
{
unsigned char i;
for(i=0;i<4;i++)
{
*(addr+i) += 0x01;
if((*(addr+i) & 0x0f) > 0x09)
{
*(addr+i) +=0x06;
if(*(addr+i) > 0x99)
{
*(addr+i) = 0x00;
}
else
{
break;
}
}
else
{
break;
}
}
}
void Cf_Judge(void) //脉冲电量累计
{
unsigned char EngerSave_Flg = 0x00;
if(Cf_Star==0x68)
{
++CF_CUNT;
if(CF_CUNT >= Bcd_hex(RMtCt_Dtr[1])) //当脉冲计数大于(电表常数/100)
{
CF_CUNT = 0x00; //清脉冲计数
DlStar_Reg = 0x01; //0.01kWh电量产生
EngerSave_Flg = 0x01;
Cf_Add(RPPwrTtl_Dtr); ////当前有功总电量累加
if(Revp_Flg) //当电表处于反向状态时
{
Cf_Add(RNPwrTtl_Dtr); ////当前有功反向总电量累加
}
if((RPPwrTtl_Dtr[0] == 0x00) && (EngerSave_Flg ==0x01)) //当前有功电量产生1kWh,须进行E2P备份
{
EngerSave_Flg = 0x00;
F_BlckWrt_Eeprm(EPPwrTtl_Dtr,RPPwrTtl_Dtr,0x04); //当前电量保存到E2P电量数据区中,20bytes
F_BlckWrt_Eeprm(EPPwrTtl_BKUP,RPPwrTtl_Dtr,0x04); //当前电量保存到E2P电量备份区中,20bytes
F_BlckWrt_Eeprm(ENPwrTtl_Dtr,RNPwrTtl_Dtr,0x04); //当前反向电量保存到E2P电量数据区中,20bytes
F_BlckWrt_Eeprm(ENPwrTtl_BKUP,RNPwrTtl_Dtr,0x04); //当前反向电量保存到E2P电量数据区中,20bytes
}
}
Cf_Star=0x00; //脉冲标志清除
}
}
/*****************************************************************************/
void Dianl_ZcJudge(void)
{
F_BlckRead_Eeprm(HstryEngy_Pter,Databuf,0x01); //读取历史电量地址指针
if(Databuf[0] >0x00)
{
Databuf[0]--;
}
else
{
Databuf[0]= 0x0b;
}
F_BlckWrt_Eeprm(HstryEngy_Pter,Databuf,0x01); //历史电量地址刷新
F_BlckWrt_Eeprm((ELPPwrTtl_Dtr+Databuf[0]*4),RPPwrTtl_Dtr,0x04); //本月电量转存到上月电量中
}
void AutDate_Judge(void)
{
F_BlckRead_Eeprm(PowDwn_Reg,Databuf,0x01); //读取掉电事件完成寄存器
if((Databuf[0] == 0xe8) && (PowerUp_Flg)) //表示已有一次下电及上电事件生成
{
PowerUp_Flg=0;
Databuf[0] = 0x00; //清除掉电事件完成标志
F_BlckWrt_Eeprm(PowDwn_Reg,Databuf,0x01);
F_BlckRead_Eeprm(PowDwn_Tm,Databuf,0x0a); //读取停电事件1起始时间、结束时间
if(Databuf[3] != Databuf[8]) //停电时间月不等于上电时间月
{
if(Databuf[8] > Databuf[3]) //上电时间月大于停电时间月
{
if((Bcd_hex(Databuf[8])-Bcd_hex(Databuf[3]))>=2) //上电时间与掉电时间月差2个月以上
{
Dianl_ZcJudge();
}
else
{
if(((Databuf[2] < RAUtRdTm_Dtr[1]) || ((Databuf[2] == RAUtRdTm_Dtr[1]) && (Databuf[1] < RAUtRdTm_Dtr[0]))) //掉电时间在自动抄表日之前而上电时间在自动抄表日之后
|| (((Databuf[7] == RAUtRdTm_Dtr[1]) && (Databuf[6] >= RAUtRdTm_Dtr[0])) || (Databuf[7] > RAUtRdTm_Dtr[1])))
{
Dianl_ZcJudge();
}
}
}
else
{
if((12+(Bcd_hex(Databuf[8])-Bcd_hex(Databuf[3]))) >= 2)
{
Dianl_ZcJudge();
}
else
{
if(((Databuf[2] < RAUtRdTm_Dtr[1]) || ((Databuf[2] == RAUtRdTm_Dtr[1]) && (Databuf[1] < RAUtRdTm_Dtr[0]))) //掉电时间在自动抄表日之前而上电时间在自动抄表日之后
|| (((Databuf[7] == RAUtRdTm_Dtr[1]) && (Databuf[6] >= RAUtRdTm_Dtr[0])) || (Databuf[7]>RAUtRdTm_Dtr[1])))
{
Dianl_ZcJudge();
}
}
}
}
else //停电时间月等于上电时间月
{
if(((Databuf[2] < RAUtRdTm_Dtr[1]) || ((Databuf[2] == RAUtRdTm_Dtr[1]) && (Databuf[1] < RAUtRdTm_Dtr[0]))) //掉电时间在自动抄表日之前而上电时间在自动抄表日之后
&& (((Databuf[7] == RAUtRdTm_Dtr[1]) && (Databuf[6] >= RAUtRdTm_Dtr[0])) || (Databuf[7]>RAUtRdTm_Dtr[1])))
{
Dianl_ZcJudge();
}
}
}
if((RDtWk_Dtr[1] == RAUtRdTm_Dtr[1]) && (RTm_Dtr[2] == RAUtRdTm_Dtr[0]) && (RTm_Dtr[1] == 0x00) && (RTm_Dtr[0] == 0x00)) //系统正常情况下过自动抄表日判断
{
if(!Dl_ZcFlg)
{
Dianl_ZcJudge();
Dl_ZcFlg=1; //本次过自动抄表日历史电量已转存标志成立,该标志清除在1分钟后
}
}
}
void Dianl_Day_Judge(void) //本程序完成前60天电量是否需刷新
{
if((RTm_Dtr[2] == 00) && (RTm_Dtr[1] == 0x00) && (RTm_Dtr[0] == 0x00))
{
F_BlckWrt_Eeprm(ELDay_PPwrTtl_Dtr,RPPwrTtl_Dtr,0x04); //当前电量转存到上1天电量中
}
}
void Dianl_Save(void)
{
if((RTm_Dtr[2] == 0x23) && (RTm_Dtr[1] == 0x00) && (RTm_Dtr[0] == 0x00)) //当前时间等于23:00
{
F_BlckWrt_Eeprm2(EPPwrTtl_BKUP1,RPPwrTtl_Dtr,0x04); //当前电量转存到备份E2P中
F_BlckWrt_Eeprm2(ENPwrTtl_BKUP1,RNPwrTtl_Dtr,0x04); //当前反向电量转存到备份E2P中
}
}
void Dianl_Judge(void)
{
AutDate_Judge();
Dianl_Day_Judge();
Dianl_Save();
}
/*****************************************************************************/
void Read_Ad(void) //电池A/D检测
{
unsigned char i;
// if((AD.ADSR.BYTE & 0x80) == 0x80)
{
AD.ADSR.BYTE |= 0x80;
i = AD.ADRRH;
if(i< 0x40)
{
RMtWd_Dtr[0] |= 0x08;
LcdBuf_Disp[8] |=0x02;
}
else
{
RMtWd_Dtr[0] &= 0xf7;
LcdBuf_Disp[8] &=0xfd;
}
}
}
/****************************************************************************/
void Key_Judge(void)
{
if(Time1s_Flg1)
{
Time1s_Flg1 = 0;
if(!Key_Int)
{
++Key_Cnt;
}
else
{
Key_Cnt = 0x00;
}
if(Key_Cnt > 0x01) //3s
{
Progrm_Disp = 1;
}
if(Progrm_Disp) //编程状态成立
{
++Progrm_DispCnt;
}
if(Progrm_DispCnt > 240) //编程时间大于4分钟,编程状态不成立
{
Progrm_Disp = 0;
Progrm_DispCnt = 0x00;
}
}
if(Progrm_Disp )
{
LcdBuf_Disp[8] |=0x08;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -