📄 dds06aak20090114.c
字号:
/*========================================================================
*甲子科技发展(深圳)有限公司
*DDS06AAK单相有功电子式电能表程序
*220V;10(60)A;60Hz;1600imp/kWh;1级表;LCD显示;反向指示;42壳
*作者:Chaoding XU
*日期:2008.12.23
*MCU:R5G0C514(瑞萨) 计量芯片:AD71056 晶振:4.096M
系统时钟4分频,定时器1是定时器的16分频
========================================================================*/
#include "sfr_38d2.h"
#include <intr740.h>
/*========================================================================
功能描述:各种宏定义和声明
========================================================================*/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define nop() nop_instruction()
void IO_Initialize(void);
void System_Init(void);
void CLear_Meter(void);
uchar Get_Check(uchar senddata);
void Ms_Delay(uchar n);
void Us_delay(uchar PB_delay);
uchar Check_Bcd(uchar* ram_addr,uchar n);
void Bcd_Add_One(uchar* ram_addr,uchar n);
void I2C_SoftReset(void);
void Read_EeprData(uchar *ram_addr,uchar n,uint eepr_addr);
void Write_EeprData(uchar *ram_addr,uchar n,uint eepr_addr);
void Clear_EeprData(uchar n,uint eepr_addr);
void Task_Save_Eep(void);
void Disp_Transfer(void);
void Display_Initialize(void);
void Task_Disp(void);
void Task_Energy(void);
void Disp_Hex(void);
void timer1init(void);
union Un_Long
{
ulong ul;
uchar uc[4];
};
struct Str_Bit
{
uchar b0:1;
uchar b1:1;
uchar b2:1;
uchar b3:1;
uchar b4:1;
uchar b5:1;
uchar b6:1;
uchar b7:1;
};
union Un_char
{
uchar byte;
struct Str_Bit bt;
};
union Un_En
{
ulong ul_en;
uchar uc_en[4];
};
uchar Init_Ram ;
union Un_En kWh_ALL ;
uchar kWh_Pluse_Numble;
uchar kWh_Save_Delay;
uchar Init_Display_Delay;
uchar pulse_Delay;
uchar S05_Int_Delay;
uint S60_Int_Delay;
uchar MS5_Int_Delay;
uchar I2c_Buf[30];
uchar Eep_Timer;
uchar Iic_Check[2];
uchar Iic_Eer_Timer;
#define Eepr_Ctrl_Wr 0x0a0
#define Eepr_Ctrl_Rd 0x0a1
#define P_EeprScl P4_6
#define P_EeprSda P4_5
#define Set_InPut_P_EeprSda P4D&=0XDF;
#define Set_OutPut_P_EeprSda P4D|=0X20;
#define P_EeprScl_High P4_6=1;
#define P_EeprScl_Low P4_6=0;
#define P_EeprSda_High P4_5=1;
#define P_EeprSda_Low P4_5=0;
#define P_EeprWp_High P4_7=1;
#define P_EeprWp_Low P4_7=0;
#define Clear_data P4_3
union Un_Group
{
uchar Temp[16];
uint Tempint[8];
};
union Un_Group GS_Data;
uchar DispData_Buff[8];
uchar kWh_Save_Bank1 ;
uchar kWh_Save_Bank2;
uchar Int_Running;
uchar kWh_Save_H;
uchar Is_Not_Bcd;
#define Char_space 0x00 //没有显示
#define Char_0 0x7D //对液晶资料,0XEB显示0
#define Char_1 0x60 //显示数字1
#define Char_2 0x3E //显示数字2
#define Char_3 0x7A //显示数字3
#define Char_4 0x63 //显示数字4
#define Char_5 0x5B //显示数字5
#define Char_6 0x5F //显示数字6
#define Char_7 0x70 //显示数字7
#define Char_8 0x7F //显示数字8
#define Char_9 0x7B //显示数字9
#define Char_A 0x77 //显示字母“A”
#define Char_b 0x4F //显示小写字母“b”
#define Char_C 0x1D //显示大写字母“C”
#define Char_d 0x6E //显示小写字母“d”
#define Char_E 0x1F //显示大写字母“E”
#define Char_F 0x17 //显示大写字母“F”
#define Dot_2P_Addr 1
#define Dot_2P_Data 0x80//显示第二位的小数点
//LRAM3 = 0x7D;//0
//LRAM4 = 0x60;//1
//LRAM5 = 0x3E;//2
//LRAM6 = 0x7A;//3
//LRAM7 = 0x63;//4
//LRAM8 = 0x5B;//5
//LRAM9 = 0x5F;//6
//LRAM3 = 0x70;//7
//LRAM4 = 0x7F;//8
//LRAM5 = 0x7B;//9
//LRAM6 = 0x77;//A
//LRAM7 = 0x4F;//b
//LRAM8 = 0x1D;//C
//LRAM9 = 0x6E;//d
//LRAM3 = 0x1F;//E
//LRAM4 = 0x17;//F
//LRAM7 = 0x80;//2p
//LRAM8 = 0x80;//3p
uchar Lcd_char_tabl[17]={Char_0,Char_1,Char_2,Char_3,Char_4,Char_5,Char_6,Char_7,Char_8,
Char_9,Char_A,Char_b,Char_C,Char_d,Char_E,Char_F,Char_space};
uchar GACH_Addr_tbl[7]={6,5,4,3,2,1,0};
#define Init_Eep_Word 0X3847
#define Pluse_Init 1
/*************************主存储区************************/
#define Identifier_EeAddr 0x10
#define kWh_ALL_EeAddr Identifier_EeAddr +16
#define kWh_ALL_Dot_EeAddr kWh_ALL_EeAddr +4
/*************************备份区**************************/
#define Identifier_EeAddr1 kWh_ALL_Dot_EeAddr +20
#define kWh_ALL_EeAddr1 Identifier_EeAddr1 +16
#define kWh_ALL_Dot_EeAddr1 kWh_ALL_EeAddr1 +4
/************************延时*****************************/
#define delay5 nop();nop();nop();nop();nop();
#define delay10 nop();nop();nop();nop();nop();\
nop();nop();nop();nop();nop();
/*========================================================================
功能描述:主程序
========================================================================*/
void main(void)
{
nop();nop();nop();nop();
while((CPUM&0x84) != 0x84)
{
nop();
}
IO_Initialize();
Display_Initialize();
if (Clear_data==0)
{
CLear_Meter();
}
Init_Ram=0x5A;
enable_interrupt();
timer1init();
while(1)
{
System_Init();
//if(Int_Running)
//{
// Int_Running=0;
//}
Task_Disp();
if(Int_Running)
{
Int_Running=0;
}
Task_Energy();
if(Int_Running)
{
Int_Running=0;
}
Task_Save_Eep();
}
disable_interrupt();
}
/*========================================================================
功能描述:IO口初始化
========================================================================*/
void IO_Initialize(void)
{
P0=0;
P1=0;
P2=0;
P3=0;
P4= 0x0C8;
P4D = 0x0C0;
P5=0;//int0置为输入口,SCL置为输出口
P5D = 0x00;
}
/*========================================================================
功能描述:总清,把里面数据全部清完
========================================================================*/
void CLear_Meter(void)
{
Clear_EeprData(24,kWh_ALL_EeAddr);
Clear_EeprData(24,kWh_ALL_EeAddr1);
}
/*========================================================================
功能描述:系统初始化
========================================================================*/
void System_Init(void)
{
uchar i,j;
if(Init_Ram==0x5A)
{
kWh_Pluse_Numble=0;
/*********************EEPROM Initialize*******************/
Read_EeprData(GS_Data.Temp,16,Identifier_EeAddr);
for(j=i=0;i<8;i++)
{
if(GS_Data.Tempint[i]==Init_Eep_Word)
j++;
}
if(j<3)
{
Read_EeprData(GS_Data.Temp,16,Identifier_EeAddr1);
for(j=i=0;i<8;i++)
{
if(GS_Data.Tempint[i]==Init_Eep_Word)
j++;
}
if(j<3)
{
CLear_Meter();
}
for(i=0;i<8;i++)
GS_Data.Tempint[i]=Init_Eep_Word;
Write_EeprData(GS_Data.Temp,16,Identifier_EeAddr);
Write_EeprData(GS_Data.Temp,16,Identifier_EeAddr1);
}
/******************RAM Initialize*************************/
Read_EeprData(kWh_ALL.uc_en,4,kWh_ALL_EeAddr);
Check_Bcd(kWh_ALL.uc_en,4);
if(Is_Not_Bcd)
{
Read_EeprData(kWh_ALL.uc_en,4,kWh_ALL_EeAddr1);
Check_Bcd(kWh_ALL.uc_en,4);
if(Is_Not_Bcd)
{
CLear_Meter();
}
}
i=kWh_ALL.uc_en[2]&0x0F;
Read_EeprData(GS_Data.Temp,2,kWh_ALL_Dot_EeAddr+2*i);
kWh_ALL.uc_en[3]=GS_Data.Temp[0];
if(GS_Data.Temp[1]-(uchar)(kWh_ALL.uc_en[0]+kWh_ALL.uc_en[1]+kWh_ALL.uc_en[2]+kWh_ALL.uc_en[3]))
{
i=kWh_ALL.uc_en[2]&0x0F;
Read_EeprData(GS_Data.Temp,2,kWh_ALL_Dot_EeAddr1+2*i);
kWh_ALL.uc_en[3]=GS_Data.Temp[0];
if(GS_Data.Temp[1]-(uchar)(kWh_ALL.uc_en[0]+kWh_ALL.uc_en[1]+kWh_ALL.uc_en[2]+kWh_ALL.uc_en[3]))
{
kWh_ALL.uc_en[3]=0;GS_Data.Temp[0]=0;
GS_Data.Temp[1]=kWh_ALL.uc_en[0]+kWh_ALL.uc_en[1]+kWh_ALL.uc_en[2]+kWh_ALL.uc_en[3];
Write_EeprData(GS_Data.Temp,2,kWh_ALL_Dot_EeAddr+2*i);
Write_EeprData(GS_Data.Temp,2,kWh_ALL_Dot_EeAddr1+2*i);
}
}
/***********************Interupt Initialize***************/
INT0PL=0;//int0下降沿有效
nop();
IR_INT0=0;//INT0中断请求位IR_INT0
IE_INT0=1;//INTO中断允许位INT0PL
Init_Ram=0x00;
nop();
}
}
/*========================================================================
功能描述:定时器1中断
========================================================================*/
void interrupt[20] I_Timer1(void)//每1ms中断一次
{
if(S05_Int_Delay==0)
{
S05_Int_Delay=50;
if(kWh_Save_Delay)
{
kWh_Save_Delay--;
if(kWh_Save_Delay==0)
kWh_Save_Bank2=1;
}
}
else S05_Int_Delay--;
Int_Running=1;
}
/*========================================================================
功能描述:电能中断
========================================================================*/
void interrupt[30] I_Int0(void)
{kWh_Pluse_Numble++;}
/*========================================================================
功能描述:延时n ms (每个机器周期0.976us)
========================================================================*/
void Ms_Delay(uchar n)
{
uchar i,j;
for(i=n;i!=0;i--)
{
for(j=0;j<34;j++)
{ nop();nop();nop();nop();nop();}
}
}
/*========================================================================
功能描述:us延时,一个Us_delay()表示延时10个nop()
========================================================================*/
void Us_delay(uchar PB_delay)
{
uchar i;
for(i=PB_delay;i!=0;i--)
{
nop();nop();nop();nop();nop();
nop();nop();nop();nop();nop();
nop();nop();nop();nop();nop();
nop();nop();nop();nop();nop();
nop();nop();nop();nop();nop();
}
}
/*========================================================================
功能描述:检查数据是不是BCD码,返回1表示不是BCD码,返回0表示是BCD码
========================================================================*/
uchar Check_Bcd(uchar* ram_addr,uchar n)
{
uchar i=0;
Is_Not_Bcd=0;
while(i<n-1)
{
if(*(ram_addr+i)>0x99)
{Is_Not_Bcd=1;return 1;}
if((*(ram_addr+i)&0x0F)>0x9)
{Is_Not_Bcd=1;return 1;}
i++;
}
return 0;
}
/*========================================================================
功能描述:根据脉冲计量电能程序,电能为BCD码
置保存电能标志;
========================================================================*/
void Bcd_Add_One(uchar* ram_addr,uchar n)
{
uchar i,j;
*(ram_addr+n-1)=*(ram_addr+n-1)+1;
i=0;
while(i<n)
{
j=*(ram_addr+n-i-1);
j=j&0x0F;
if(j>0x9)
{
*(ram_addr+n-i-1)+=6;
}
j=*(ram_addr+n-i-1);
j=j&0xf0;
if(j>0x90)
{
*(ram_addr+n-i-1)+=0x60;
i++;
if(i<n) *(ram_addr+n-i-1)+=1;
}
else i=n;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -