?? 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 + -