/*********************************************************
Hardware : EVB9S08DZ60 Board
Author : WBR
Version : V1.0
Begin Time: 2011.5.30
**********************************************************/
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "1302.h"
//#include "lcd.h"
//#include "mscan.h"
//#include "KEY.h"
/******************************************************
IO說(shuō)明:
1:四路AD輸入通道 ADP19(AD1) ADP11(AD2) ADP3(AD3) ADP4(AD4)
2:485通信 DE (PTE2) TXD1(PTE0) RXD1(PTE1)
3:四路光耦輸入 DI1(PTG2) DI2 (PTE5) DI3 (PTE4) DI4(PTE3)
4:DS1302 SCL(PTF2) SDA (PTF3) RST (PTG4)
5:繼電器控制 PTA6 PTB5 PTA5 PTC4 PTB6
6:按鍵(輸入) PTC0 PTB0 PTC1 PTA0 PTC2(SW1~SW5)
7:CAN TX(PTE6) RX(PTE7)
8:LCD RW(PTG3) RS(PTF0) E(PTF1) RST(PTF7) 背光(PTG5) DATA(PTD0~PTD7)
************************************************************/
#define DI1 PTGD_PTGD2 //外觸發(fā)1----->PG2
#define DI2 PTED_PTED5 //外觸發(fā)2----->PE5
#define DI3 PTED_PTED4 //外觸發(fā)3----->PE4
#define DI4 PTED_PTED3 //外觸發(fā)4----->PE3
//********以上為輸入IO********//
#define JDQ1 PTCD_PTCD4 //繼電器1----->PC4
#define JDQ2 PTAD_PTAD5 //繼電器2----->PA5
#define JDQ3 PTBD_PTBD5 //繼電器3----->PB5
#define JDQ4 PTAD_PTAD6 //繼電器4----->PA6
#define JDQ5 PTBD_PTBD6 //繼電器5----->PB6
#define DE485 PTED_PTED2 //485 T R切換----->PE2
//#define ID_TX 0x0001 //自定義的CAN發(fā)送標(biāo)識(shí)符
//#define ID_RX 0x0002 //自定義的CAN接收標(biāo)識(shí)符
//Bool can_send_enable = FALSE; //CAN發(fā)送標(biāo)志位,暫定RTC0.5秒發(fā)送一次
#define Baud 19200 //串口波特率9600
#define N 51
#define T 1800 //運(yùn)算電量的時(shí)間單位1800是半個(gè)小時(shí)(1800秒)
extern byte time_buf1[8]; //1302時(shí)鐘寄存器
byte ReadTimeFlag = 0; //定時(shí)器每0.5秒讀1302時(shí)間的標(biāo)志位
byte ADSET = 0; //發(fā)送電流電壓功率等數(shù)值到顯示屏標(biāo)志位
/*********************變量和函數(shù)定義****************************/
word ADCbuffer1[N] = 0; //AD轉(zhuǎn)換緩沖
word ADC1,ADC2,ADC3,ADC4; //AD轉(zhuǎn)換緩沖
byte ADC1L,ADC1H,ADC2L,ADC2H,ADC3L,ADC3H,ADC4L,ADC4H;
byte MW4L,MW4H,MW5L,MW5H,MW6L,MW6H,MW7L,MW7H,MW8L,MW8H,MW9L,MW9H;
byte MW21L,MW21H,MW22L,MW22H,MW25L,MW25H,MW26L,MW26H; //歷史充電電量記錄
byte MW29L,MW29H,MW30L,MW30H,MW33L,MW33H,MW34L,MW34H; //歷史放電電量記錄
byte Buffer[15]; //串口接收緩沖
byte ADch_s; //AD通道選擇
byte ADcount;
//byte Key_value=0; //按鍵
//byte CANbuffer[8]; //接收到的CAN內(nèi)容緩沖區(qū)數(shù)組
word sum=0;
long P,P1,P2,P3,Premain,Pup,Pdown,Psum; //實(shí)時(shí)充電功率,實(shí)時(shí)放電功率,歷史充電功率,歷史放電記錄
word PL,PH; //拆分P
byte P0L,P0H,P1L,P1H; //拆分PH,PL
byte RR = 1; //RR = 1;讀屏的19號(hào)地址;RR = 2讀屏的20號(hào)地址開始的時(shí)間;
byte PAGE8; //進(jìn)入設(shè)置時(shí)間頁(yè)面和電量頁(yè)面設(shè)置計(jì)數(shù);
byte T20 =0;
word TENT;
byte *p;
//================================
//中值濾波程序
//================================
void filter()
{
static byte count,i,j;
word value_buf[N];
word temp;
sum=0;
for(count=0;count<N;count++)
{
value_buf[count] = ADCbuffer1[count];;
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(count=1;count<N-1;count++)
sum += value_buf[count];
}
//===================================
//函數(shù)名:MCU_INIT
//作用: 初始化MCU時(shí)鐘 晶振16M總線頻率8M
//====================================
void MCU_INIT(void)
{
MCGC1=0x04; //選擇內(nèi)部時(shí)鐘
MCGC2=0x40; //時(shí)鐘源二分頻
MCGTRM=0xa8;//內(nèi)部時(shí)鐘微調(diào)
}
//===================================
//函數(shù)名: IO_INIT
//作用: 初始化IO 輸入輸出
//====================================
void IO_INIT(void)
{
PTADD = 0xe6; //數(shù)據(jù)方向 1為輸出,0為輸入
PTBDD = 0x76;
PTCDD = 0xb0;
//PTDDD = 0xff;
PTEDD = 0x45;
PTFDD = 0xff;
PTGDD = 0x38;
PTAD = 0 ; //初始狀態(tài)IO全為0
PTBD = 0;
PTCD = 0;
PTDD = 0;
PTED = 0;
PTFD = 0;
PTGD = 0;
}
//===================================
//函數(shù)名: ADC_INIT
//作用: 初始化ADC 總線時(shí)鐘8M
//===================================
void ADC_INIT(void)
{
ADCCFG = 0xf9; //低功耗模式,10位精度,ADCK=總線頻率/8/2=500K
ADCSC2 = 0x00; //0x00:軟件觸發(fā),比較功能禁止
APCTL1 = 0x14; //通道引腳使能: 使用通道為AD19 AD11 AD3 AD4
APCTL2 = 0x08;
APCTL3 = 0x08;
ADch_s = 19; //選擇19通道開始
ADCSC1 = 0x73; //0x53:中斷使能,單次轉(zhuǎn)換,選擇19通道啟動(dòng)轉(zhuǎn)換.
}
//===================================
//函數(shù)名:SCI_INIT
//作用: 初始化SCI1
//====================================
void SCI_INIT(void)
{
SCI1BD = 8000000/16/Baud;
SCI1C1 = 0x00;
SCI1C2 = 0x2c; //使能接受中斷
}
//===================================
//串口發(fā)送
//===================================
void SCI1send (byte x)
{
while(SCI1S1_TDRE==0);
SCI1D = x;
}
//===================================
//定時(shí)器1初始化
//===================================
void TPM1_Init(void) //定時(shí)器1初始化
{
TPM1MODH=0x3d; //
TPM1MODL=0x09; //250MS
TPM1SC=0x4F; //TPM1時(shí)鐘源為總線時(shí)鐘;分頻系數(shù)為128;溢出中斷使能
}
//===================================
//延時(shí)
//===================================
void Delay(Word time)
{
Word i,j;
for(i=0;i<time;i++) {
__RESET_WATCHDOG();
for(j=0;j<500;j++);
}
}
void WEEP()
{
FCMD=0x20;
FSTAT_FCBEF=1;
asm{
NOP
NOP
NOP
NOP
}
while(FSTAT_FCCF==0);
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
}
/*********************主函數(shù)************************************/
void main(void)
{
static byte MonthF1,DateF1,MonthF2,DateF2,MonthF3,DateF3,MonthC1,DateC1,MonthC2,DateC2,MonthC3,DateC3; //充電放電歷史記錄的兩次時(shí)間變量及緩存變量
static byte FBETW0L,FBETW0H,FBETW1L,FBETW1H,CBETW0L,CBETW0H,CBETW1L,CBETW1H;
static word PupCount,PdownCount;
byte Pchange = 0 ; //充電0XFF 放電0X00轉(zhuǎn)換標(biāo)志
byte Failure; //故障信息指示MW17.0 = 1過(guò)壓 MW17.1 = 1過(guò)流
word BetweenH,BetweenL;
long a,b;
byte SendSum;
MCU_INIT();
IO_INIT();
Ds1302_Init();
ADC_INIT();
TPM1_Init();
SCI_INIT();
DE485 = 1; //485發(fā)送使能;
PTED_PTED6 = 1;
Ds1302_Read_Time(); //先讀取一次時(shí)間用于判斷歷史時(shí)間
if(!DI1) //DI1 = 0
{
Pchange = 0x01; //充電
}
if(!DI2) //DI2 = 0
{ //放電
Pchange = 0x02;
}
if(DI1&&DI2) //DI1,DI2都 為高電平
{
Pchange = 0;
}
FCDIV = 39; //設(shè)置FLASH分頻 8M總線時(shí)鐘分頻數(shù)39;FLASH讀寫200KH
asm(nop);
//**************讀取記錄的充電的歷史記錄************************
//************前1次的前1次得充電記錄
p=(byte *)(0x1401); //
MonthC1= *p;
p=(byte *)(0x1402); //時(shí)間
DateC1= *p;
p=(byte *)(0x1403); //電量的最低位
MW21L= *p;
p=(byte *)(0x1404); //
MW21H= *p;
p=(byte *)(0x1405); //
MW22L= *p;
p=(byte *)(0x1406); //
MW22H= *p;
if(MonthC1>12)
{
MonthC1 = 0;
DateC1= 0;
MW21L = 0;
MW21H = 0;
MW22L = 0;
MW22H = 0;
}
//*************前1次的充電記錄*********************************
p=(byte *)(0x1411); //
MonthC2= *p;
p=(byte *)(0x1412); //時(shí)間
DateC2= *p;
p=(byte *)(0x1413); //電量的最低位
MW25L= *p;
p=(byte *)(0x1414); //
MW25H= *p;
p=(byte *)(0x1415); //
MW26L= *p;
p=(byte *)(0x1416); //
MW26H= *p; //
if(MonthC2>12) //如果日期錯(cuò)誤,清零
{
MonthC2 = 0;
DateC2= 0;
MW25L = 0;
MW25H = 0;
MW26L = 0;
MW26H = 0;
}
//***************緩存的充電記錄,用于比較計(jì)算******************
p=(byte *)(0x1421); //
MonthC3= *p;
p=(byte *)(0x1422); //時(shí)間
DateC3= *p;
p=(byte *)(0x1423); //電量的最低位
CBETW0L= *p;
p=(byte *)(0x1424); //
CBETW0H= *p;
p=(byte *)(0x1425); //
CBETW1L= *p;
p=(byte *)(0x1426); //
CBETW1H= *p;
if(MonthC3>12) //
{
MonthC3 = 0;
DateC3= 0;
CBETW0L = 0;
CBETW0H = 0;
CBETW1L = 0;
CBETW1H = 0;
}
//**************讀取記錄的放電的歷史記錄**************************
//************前1次的前1次的放電記錄
p=(byte *)(0x1501); //
MonthF1= *p;
p=(byte *)(0x1502); //時(shí)間
DateF1= *p;
p=(byte *)(0x1503); //電量的最低位
MW29L= *p;
p=(byte *)(0x1504); //
MW29H= *p;
p=(byte *)(0x1505); //
MW30L= *p;
p=(byte *)(0x1506); //
MW30H= *p;
if(MonthF1>12)
{
MonthF1 = 0;
DateF1= 0;
MW29L = 0;
MW29H = 0;
MW30L = 0;
MW30H = 0;
}
//*************前1次的放電記錄*********************************
p=(byte *)(0x1511); //
MonthF2= *p;
p=(byte *)(0x1512); //時(shí)間
DateF2= *p;
p=(byte *)(0x1513); //電量的最低位
MW33L= *p;
p=(byte *)(0x1514); //
MW33H= *p;
p=(byte *)(0x1515); //
MW34L= *p;
p=(byte *)(0x1516); //
MW34H= *p;
if(MonthF2>12) //
{
MonthF2 = 0;
DateF2= 0;
MW33L = 0;
MW33H = 0;
MW34L = 0;
MW34H = 0;
}
//***************緩存的放電記錄,用于比較計(jì)算******************
p=(byte *)(0x1521); //
MonthF3= *p;
p=(byte *)(0x1522); //時(shí)間
DateF3= *p;
p=(byte *)(0x1523); //電量的最低位
FBETW0L= *p;
p=(byte *)(0x1524); //
FBETW0H= *p;
p=(byte *)(0x1525); //
FBETW1L= *p;
p=(byte *)(0x1526); //
FBETW1H= *p;
if(MonthF3>12) //
{
MonthF3 = 0;
DateF3= 0;
FBETW0L = 0;
FBETW0H = 0;
FBETW1L = 0;
FBETW1H = 0;
}
p=(byte *)(0x1601); //
MW8L= *p;
p=(byte *)(0x1602); //時(shí)間
MW8H= *p;
p=(byte *)(0x1603); //電量的最低位
MW9L= *p;
p=(byte *)(0x1604); //
MW9H= *p;
if((MW8L==0xff)&&(MW8H==0xff)&&(MW9L==0xff)&&(MW9H==0xff)) //第一次上電
{
MW8L = 0;
MW8H = 0;
MW9L = 0;
MW9H = 0;
P2 = 0;
}
else{
Premain = MW9L+(MW9H<<8);
P2= (Premain<<16)+ (MW8L+(MW8H<<8));
P2 = P2*3600*1000;
}
if(Pchange==0x01) //充電時(shí)比較
{
if((time_buf1[2] == MonthC3)&& (time_buf1[3] == DateC3))
{
MW4L = CBETW0L;
MW4H = CBETW0H;
MW5L = CBETW1L;
MW5H = CBETW1H;
Premain = MW5L+(MW5H<<8);
P3= (Premain<<16)+ (MW4L+(MW4H<<8));
P3 = P3*3600;
}
else
{
MW4L = 0;
MW4H = 0;
MW5L = 0;
MW5H = 0;
P3 = 0;
}
}
if(Pchange==0x02) //放電時(shí)比較
{
if((time_buf1[2] == MonthF3)&& (time_buf1[3] == DateF3))
{
MW6L = FBETW0L;
MW6H = FBETW0H;
MW7L = FBETW1L;
MW7H = FBETW1H;
Premain = MW7L+(MW7H<<8);
P1= (Premain<<16)+ (MW6L+(MW6H<<8));
P1 = P1*3600;
}
else
{
MW6L = 0;
MW6H = 0;
MW7L = 0;
MW7H = 0;
P1 = 0;
}
}
EnableInterrupts; //開中斷
for(;;)
{
__RESET_WATCHDOG(); //喂內(nèi)部看門狗
if(!DI1)
{ //充電
Pchange = 0x01;
} //放電
if(!DI2)
{
Pchange = 0x02;
}
if(DI1&&DI2)
{
Pchange = 0; //停機(jī)狀態(tài)
}
if(Pchange==0x02)
{
if((time_buf1[2] != MonthF3)|| (time_buf1[3] != DateF3)) //只要是 時(shí)間不等,就要把當(dāng)前記錄寫入EEPROM,開始新的計(jì)算
{
p=( unsigned char *)(0x1500); //指定地址 緩存的時(shí)間寫入前1天,前一天的時(shí)間寫入前1天前1天
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1500); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1501);
*p = MonthF2;
WEEP();
p=(byte *)(0x1502);
*p = DateF2;
WEEP();
p=(byte *)(0x1503);
*p = MW33L;
WEEP();
p=(byte *)(0x1504);
*p = MW33H;
WEEP();
p=(byte *)(0x1505);
*p = MW34L;
WEEP();
p=(byte *)(0x1506);
*p = MW34H;
WEEP();
p=( unsigned char *)(0x1510); //指定地址 //緩存的時(shí)間寫入前1天,前一天的時(shí)間寫入前1天前1天
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1510); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1511); //如果時(shí)間變了,原緩存存入前一天的內(nèi)存
*p = MonthF3;
WEEP();
p=(byte *)(0x1512);
*p = DateF3;
WEEP();
p=(byte *)(0x1513);
*p = FBETW0L;
WEEP();
p=(byte *)(0x1514);
*p = FBETW0H;
WEEP();
p=(byte *)(0x1515);
*p = FBETW1L;
WEEP();
p=(byte *)(0x1516);
*p = FBETW1H;
WEEP();
P1 = 0;
MW29L = MW33L;
MW29H = MW33H;
MW30L = MW34L;
MW30H = MW34H;
MonthF1 = MonthF2;
DateF1 = DateF2;
MW33L = FBETW0L;
MW33H = FBETW0H;
MW34L = FBETW1L;
MW34H = FBETW1H;
MonthF2 = MonthF3;
DateF2 = DateF3;
asm(nop);
MonthF3 =time_buf1[2]; //當(dāng)前時(shí)間送入緩存
DateF3= time_buf1[3];
//MonthF3 = time_buf1[2];
//DateF3 = time_buf1[3];
FBETW0L = MW6L;
FBETW0H = MW6H;
FBETW1L = MW7L;
FBETW1H = MW7H;
p=( unsigned char *)(0x1520); //指定地址
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1520); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1521);
*p = time_buf1[2];
WEEP();
p=(byte *)(0x1522);
*p = time_buf1[3];
WEEP();
p=(byte *)(0x1523);
*p = MW6L;
WEEP();
p=(byte *)(0x1524);
*p = MW6H;
WEEP();
p=(byte *)(0x1525);
*p = MW7L;
WEEP();
p=(byte *)(0x1526);
*p = MW7H;
WEEP();
}
}
if(Pchange == 0x01) //充電的時(shí)候
{
if((time_buf1[2] != MonthC3)|| (time_buf1[3] != DateC3)) //只要時(shí)間不等,開始新的計(jì)算
{
p=( unsigned char *)(0x1400); //指定地址 緩存的時(shí)間寫入前1天,前一天的時(shí)間寫入前1天前1天
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1400); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1401);
*p = MonthC2;
WEEP();
p=(byte *)(0x1402);
*p = DateC2;
WEEP();
p=(byte *)(0x1403);
*p = MW25L;
WEEP();
p=(byte *)(0x1404);
*p = MW25H;
WEEP();
p=(byte *)(0x1405);
*p = MW26L;
WEEP();
p=(byte *)(0x1406);
*p = MW26H;
WEEP();
p=( unsigned char *)(0x1410); //指定地址 緩存的時(shí)間寫入前1天,前一天的時(shí)間寫入前1天前1天
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1410); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1411);
*p = MonthC3;
WEEP();
p=(byte *)(0x1412);
*p = DateC3;
WEEP();
p=(byte *)(0x1413);
*p = CBETW0L;
WEEP();
p=(byte *)(0x1414);
*p = CBETW0H;
WEEP();
p=(byte *)(0x1415);
*p = CBETW1L;
WEEP();
p=(byte *)(0x1416);
*p = CBETW1H;
WEEP();
MW21L = MW25L;
MW21H = MW25H;
MW22L = MW26L;
MW22H = MW26H;
MonthC1 = MonthC2;
DateC1 = DateC2;
MW25L = CBETW0L;
MW25H = CBETW0H;
MW26L = CBETW1L;
MW26H = CBETW1H;
MonthC2 = MonthC3;
DateC2 = DateC3;
P3 = 0;
MonthC3 =time_buf1[2]; //當(dāng)前時(shí)間送入緩存
DateC3= time_buf1[3];
//MonthC3 = time_buf1[2];
//DateC3 = time_buf1[3];
CBETW0L = MW4L;
CBETW0H = MW4H;
CBETW1L = MW5L;
CBETW1H = MW5H;
p=( unsigned char *)(0x1420); //指定地址
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1420); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1421);
*p = time_buf1[2];
WEEP();
p=(byte *)(0x1422);
*p = time_buf1[3];
WEEP();
p=(byte *)(0x1423);
*p = MW4L;
WEEP();
p=(byte *)(0x1424);
*p = MW4H;
WEEP();
p=(byte *)(0x1425);
*p = MW5L;
WEEP();
p=(byte *)(0x1426);
*p = MW5H;
WEEP();
}
}
if(!RR)
{
Ds1302_Write_Time();
Delay(10);
T20 = 1;
}
if(T20) //切換到2界面
{
T20 = 0;
TENT = 0;
DE485 = 1; //保證切換到發(fā)射
Delay(200);
SCI1send (0x01); //站號(hào)
SCI1send (0x57); //寫命令
SCI1send (0x12); //18號(hào)地址跳轉(zhuǎn)頁(yè)面指令,跳轉(zhuǎn)到1界面
SCI1send (0x01); //1個(gè)長(zhǎng)度
SCI1send (0x00); //18號(hào)地址
SCI1send (0x01);
SCI1send (0x6c);
Delay(100); //需加一段長(zhǎng)延時(shí)
SCI1send (0x01); //站號(hào)
SCI1send (0x57); //寫命令
SCI1send (0x12); //18號(hào)地址跳轉(zhuǎn)頁(yè)面指令,跳轉(zhuǎn)到2界面
SCI1send (0x01); //1個(gè)長(zhǎng)度
SCI1send (0x00); //18號(hào)地址
SCI1send (0x02);
SCI1send (0x6d);
Delay(200); //必須加段延時(shí)確保數(shù)據(jù)發(fā)送出去
RR = 1; //1分鐘內(nèi)ENT沒有按下,轉(zhuǎn)回正常模式
asm(nop);
}
if(ADSET) //處理AD;
{
ADSET = 0;
if(ADcount == 1)
{
filter();
ADC1= (sum/(N-2));
if(ADC1<7){ ADC1 = 0; //屏蔽掉待機(jī)狀態(tài)時(shí)的不干凈的初值
}
if (ADC1>163)
{
Failure = Failure|0x01; //置過(guò)壓標(biāo)志
}
else Failure = Failure&0xfe; //清過(guò)壓標(biāo)志
//b = 750*50;
//b = b/255;
b = (long)7500*ADC1; //放大10倍,為了送顯示
//ADC1 = b*ADC1;
//ADC1 = ADC1/5;
ADC1 = b>>10; //除以1024
ADC1H = ADC1>>8;
ADC1L = ADC1&255;
ADch_s = 11;
ADCSC1=0x6b;
}
if(ADcount == 2)
{
filter();
ADC2= (sum/(N-2));
if(ADC2<7) { ADC2 = 0;
}
if (ADC2>191) //過(guò)流
{
Failure = Failure|0x02; //置過(guò)流標(biāo)志
}
else Failure = Failure&0xfd; //清過(guò)流標(biāo)志
//a= 400*50;
//a= a/255;
a = (long)4000*ADC2;
//ADC2 = a*ADC2; //轉(zhuǎn)換成電壓值 ,取小數(shù)點(diǎn)后一位,所以先擴(kuò)大50倍
//ADC2 = ADC2/5; //10倍電流送顯示,用于顯示小數(shù)點(diǎn)
ADC2 = a>>10;
ADC2H = ADC2>>8;
ADC2L = ADC2&255;
ADC1 = ADC1/10;
ADC2 = ADC2/10;
P =(long)ADC1*ADC2;
PH = P>>16;
PL = P&0xffff;
P1H = PH>>8;
P1L = PH&255;
P0H = PL>>8;
P0L = PL&255;
if(Pchange==0x02) //如果放電
{
PdownCount++; //秒累加
P2 = P2+P; //一直累積的放電電量
Psum=(long)(P2/3600/1000);
BetweenH = Psum>>16;
BetweenL = Psum&0xffff;
MW9H = BetweenH>>8;
MW9L = BetweenH&255;
MW8H = BetweenL>>8;
MW8L = BetweenL&255;
P1 = P1+P; //秒功率累加
Pdown = (long)P1/3600; //實(shí)際放電功率,按小時(shí)計(jì)算
BetweenH = Pdown>>16;
BetweenL = Pdown&0xffff;
MW7H = BetweenH>>8;
MW7L = BetweenH&255;
MW6H = BetweenL>>8;
MW6L = BetweenL&255;
if(PdownCount > T) //超過(guò)半個(gè)小時(shí)開始寫入EEPROM
{
PdownCount = 0;
p=( unsigned char *)(0x1600); //指定地址
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1600); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1601); //總放電量寫入EEPROM
*p = MW8L;
WEEP();
p=(byte *)(0x1602);
*p = MW8H;
WEEP();
p=(byte *)(0x1603);
*p = MW9L;
WEEP();
p=(byte *)(0x1604);
*p = MW9H;
WEEP();
asm(nop);
if((time_buf1[2] == MonthF3)&& (time_buf1[3] == DateF3)) //當(dāng)前時(shí)間等于緩存時(shí)間,繼續(xù)寫入緩存
{
MonthF3 = time_buf1[2];
DateF3 = time_buf1[3];
FBETW0L = MW6L;
FBETW0H = MW6H;
FBETW1L = MW7L;
FBETW1H = MW7H;
p=( unsigned char *)(0x1520); //指定地址
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1520); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1521);
*p = time_buf1[2];
WEEP();
p=(byte *)(0x1522);
*p = time_buf1[3];
WEEP();
p=(byte *)(0x1523);
*p = MW6L;
WEEP();
p=(byte *)(0x1524);
*p = MW6H;
WEEP();
p=(byte *)(0x1525);
*p = MW7L;
WEEP();
p=(byte *)(0x1526);
*p = MW7H;
WEEP();
}
}
}
if(Pchange == 0x01) //如果充電
{
PupCount++; //秒累加
P3 =P3+P; //秒功率累加
Pup = (long)P3/3600; //實(shí)際放電功率,按小時(shí)計(jì)算
BetweenH = Pup>>16;
BetweenL = Pup&0xffff;
MW5H = BetweenH>>8;
MW5L = BetweenH&255;
MW4H = BetweenL>>8;
MW4L = BetweenL&255;
if(PupCount >T)
{
PupCount = 0; //超過(guò)半個(gè)小時(shí)開始寫入EEPROM
if((time_buf1[2] == MonthC3)&& (time_buf1[3] == DateC3)) //當(dāng)前時(shí)間等于緩存時(shí)間,繼續(xù)寫入緩存
{
MonthC3 = time_buf1[2];
DateC3 = time_buf1[3];
CBETW0L = MW4L;
CBETW0H = MW4H;
CBETW1L = MW5L;
CBETW1H = MW5H;
p=( unsigned char *)(0x1420); //指定地址
*p=0x01;
FCMD=0x40; //擦除命令
FSTAT_FCBEF=1; //啟動(dòng)命令
Delay(1);
while(FSTAT_FCCF==0); //等待完成
if(FSTAT_FACCERR==1)
FSTAT_FACCERR=1;
p=(byte *)(0x1420); //指定地址
*p = 0x01;
WEEP();
p=(byte *)(0x1421);
*p = time_buf1[2];
WEEP();
p=(byte *)(0x1422);
*p = time_buf1[3];
WEEP();
p=(byte *)(0x1423);
*p = MW4L;
WEEP();
p=(byte *)(0x1424);
*p = MW4H;
WEEP();
p=(byte *)(0x1425);
*p = MW5L;
WEEP();
p=(byte *)(0x1426);
*p = MW5H;
WEEP(); //如果相等則認(rèn)為是當(dāng)前時(shí)間,繼續(xù)
}
}
}
asm(nop);
ADch_s = 3;
ADCSC1=0x63;
}
if(ADcount == 3)
{
filter();
ADC3= (sum/(N-2));
ADC3H = (sum/(N-2))>>8;
ADC3L = (sum/(N-2))&255;
ADch_s = 4;
ADCSC1=0x64;
}
if(ADcount == 4)
{
filter();
ADC4= (sum/(N-2));
ADC4H = (sum/(N-2))>>8;
ADC4L = (sum/(N-2))&255;
ADch_s = 19;
ADCSC1=0x73;
}
if(RR ==2)
{
DE485 = 1;
Delay(2);
SCI1send (0x01); //站號(hào)
SCI1send (0x52); //讀命令
SCI1send (0x14); //20號(hào)地址判斷ENT鍵狀態(tài)
SCI1send (0x01); //1個(gè)地址
SCI1send (0x68);
Delay(1); //必須加段延時(shí)確保數(shù)據(jù)發(fā)送出去
DE485 = 0; //485切換到接收狀態(tài)
asm(nop);
}
if(RR ==3)
{
DE485 = 1;
Delay(2);
SCI1send (0x01); //站號(hào)
SCI1send (0x57); //寫命令
SCI1send (0x14); //20號(hào)地址清零
SCI1send (0x01); //1個(gè)長(zhǎng)度
SCI1send (0x00); //18號(hào)地址
SCI1send (0x00);
SCI1send (0x6D);
Delay(50);
RR =4;
}
if(RR ==4) //讀時(shí)間
{
DE485 = 1;
Delay(5);
SCI1send (0x01); //站號(hào)
SCI1send (0x52); //讀命令
SCI1send (0x0B); //11號(hào)地址
SCI1send (0x06); //6個(gè)地址
SCI1send (0x64);
Delay(1); //必須加段延時(shí)確保數(shù)據(jù)發(fā)送出去
DE485 = 0; //485切換到接收狀態(tài)
//asm(nop);
}
}
if(ReadTimeFlag)
{
ReadTimeFlag = 0;
if(RR ==1)
{
Delay(10);
DE485 = 1;
Ds1302_Read_Time();
asm(nop);
SendSum = (0x6a+Pchange+Failure+ADC1L+ADC1H+ADC2L+ADC2H+P0H+P0L+P1H+P1L+
time_buf1[1]+time_buf1[2]+time_buf1[3]+time_buf1[4]+time_buf1[5]+time_buf1[6]+
MW4L+MW4H+MW5L+MW5H+MW6L+MW6H+MW7L+MW7H+MW8L+MW8H+MW9L+MW9H); //累加和
SCI1send (0x01); //站號(hào)
SCI1send (0x57); //寫命令
SCI1send (0x00); //首地址
SCI1send (0x12); //18個(gè)地址
SCI1send (ADC1H); //MW0高位 電壓
SCI1send (ADC1L); //MW0低位
SCI1send (ADC2H); //MW1 電流
SCI1send (ADC2L);
SCI1send (P0H); //MW2 實(shí)時(shí)功率
SCI1send (P0L);
SCI1send (P1H); //MW3
SCI1send (P1L);
SCI1send (MW4H); //MW4
SCI1send (MW4L);
SCI1send (MW5H); //MW5 當(dāng)前充電電量(一天累計(jì))
SCI1send (MW5L);
SCI1send (MW6H); //MW6
SCI1send (MW6L);
SCI1send (MW7H); //MW7 當(dāng)前放電電量(一次累計(jì))
SCI1send (MW7L);
SCI1send (MW8H); //MW8 當(dāng)前放電電量(一次累計(jì))
SCI1send (MW8L);
SCI1send (MW9H); //MW9 當(dāng)前放電電量(一次累計(jì))
SCI1send (MW9L);
SCI1send (0x00); //MW10 充放電指示00:放電;FF:充電
SCI1send (Pchange);
SCI1send (0x00); //MW11開始為時(shí)間
SCI1send (time_buf1[1]);
SCI1send (0x00);
SCI1send (time_buf1[2]);
SCI1send (0x00);
SCI1send (time_buf1[3]);
SCI1send (0x00);
SCI1send (time_buf1[4]);
SCI1send (0x00);
SCI1send (time_buf1[5]);
SCI1send (0x00);
SCI1send (time_buf1[6]);
SCI1send (0x00); //MW17 過(guò)壓過(guò)流指示
SCI1send (Failure);
SCI1send (SendSum);
asm(nop);
Delay(100);
SendSum = 0x7d+MW21H+MW21L+MW22H+MW22L+MonthC1+DateC1+MW25H+MW25L+MW26L+MW26H+MonthC2+DateC2
+MW29H+MW29L+MW30H+MW30L+MonthF1+DateF1+MW33L+MW33H+MW34H+MW34L+MonthF2+DateF2;
SCI1send (0x01); //站號(hào)
SCI1send (0x57); //寫命令
SCI1send (0x15); //21號(hào)地址
SCI1send (0x10); //16個(gè)地址
SCI1send (MW21H); //MW21高位
SCI1send (MW21L); //MW21低位
SCI1send (MW22H); //MW22
SCI1send (MW22L);
SCI1send (0x00); //月 MW23
SCI1send (MonthC1);
SCI1send (0x00); //日 MW24
SCI1send (DateC1);
SCI1send (MW25H); //MW25
SCI1send (MW25L);
SCI1send (MW26H); //MW26
SCI1send (MW26L);
SCI1send (0x00); //MW27
SCI1send (MonthC2);
SCI1send (0x00); //MW28
SCI1send (DateC2);
SCI1send (MW29H); //MW29
SCI1send (MW29L);
SCI1send (MW30H); //MW30
SCI1send (MW30L);
SCI1send (0x00); //MW31
SCI1send (MonthF1);
SCI1send (0x00); //MW32
SCI1send (DateF1);
SCI1send (MW33H); //MW33
SCI1send (MW33L);
SCI1send (MW34H); //MW34
SCI1send (MW34L);
SCI1send (0x00); //MW35
SCI1send (MonthF2);
SCI1send (0x00); //MW36
SCI1send (DateF2);
SCI1send (SendSum); //累加和
asm(nop);
Delay(10);
SCI1send (0x01); //站號(hào)
SCI1send (0x52); //讀命令
SCI1send (0x13); //19號(hào)地址判斷在哪個(gè)頁(yè)面
SCI1send (0x01); //1個(gè)地址
SCI1send (0x67);
Delay(1); //必須加段延時(shí)確保數(shù)據(jù)發(fā)送出去
DE485 = 0; //485切換到接收狀態(tài)
asm(nop);
}
}
}
}
//==========================================
//定時(shí)器1中斷函數(shù) 中斷向量號(hào)11 250毫秒定時(shí)
//==========================================
void interrupt 11 TPM1_ISR(void)
{
static byte i,j,k;
if((TPM1SC & 0x80)==0x80)
{
TPM1SC_TOF=0;
ADSET = 1;
}
i++;
if(!PAGE8) //
{
j = 0;
}
else
{
j++;
if(j>PAGE8) //大于5秒
{
j = 0;
RR = 2; //轉(zhuǎn)判斷ENT鍵是否按下程序
PAGE8 = 0;
}
}
if(!TENT)
{
k = 0;
}
else
{
k++;
if(k>TENT)
{
k = 0;
T20 = 1; //如果ENT鍵1分鐘內(nèi)沒有按下則跳轉(zhuǎn)到2界面(顯示電壓,電流)
TENT = 0;
}
}
if(i>3)
{
i = 0;
ReadTimeFlag = 1;
}
}
//==========================================
//串口接收中斷 VectorNumber_Vsci1rx 中斷向量號(hào)17
//==========================================
interrupt VectorNumber_Vsci1rx void SCI_RE(void)
{
static byte j;
static byte i;
byte Rcv;
if(SCI1S1_RDRF) //串口接收中斷標(biāo)志位
{ //清標(biāo)志位
SCI1S1_RDRF = 0; //接收數(shù)據(jù)送緩存
Rcv = SCI1D;
//*********************讀頁(yè)面數(shù)值*****************************
if(RR == 1)
{
if(Rcv == 0x13)
{
j = 1;
Buffer[0]=Rcv;
}
else
{
if(j < 5) //5個(gè)字節(jié)
{
Buffer[j] = Rcv;
j++;
}
}
if((Buffer[3]==0x08)&&(Buffer[4]==0x1d)) //如果檢測(cè)到是第8頁(yè)面則處理數(shù)據(jù)
{
PAGE8 =20; //如果停在8頁(yè)面設(shè)置一個(gè)計(jì)數(shù)器,5秒時(shí)間內(nèi)如果還在則認(rèn)為在修改時(shí)間
TENT = 240; //2分鐘內(nèi)ENT鍵沒有按下,則跳轉(zhuǎn)到2頁(yè)面;
}
if(Buffer[3]!=0x08) //如果跳轉(zhuǎn)到別的界面,馬上清零
{
PAGE8 = 0;
TENT = 0;
RR = 1; //回到正常狀態(tài)
}
}
//****************判斷ENT鍵按下與否******************************* ENT鍵按下的話20站號(hào)變成1
if(RR ==2)
{
if(Rcv == 0x14)
{
j = 1;
Buffer[0]=Rcv;
}
else
{
if(j < 5) //5個(gè)字節(jié)
{
Buffer[j] = Rcv;
j++;
}
}
if((Buffer[3]==0x01)&&(Buffer[4]==0x17)) //ENT鍵已經(jīng)按下
{
RR = 3;
}
}
//******************************讀取要修改的時(shí)間*******************************
if(RR ==4) //此時(shí)ENT已經(jīng)清零
{
Buffer[j]=Rcv;
if(!i)
{
if(Buffer[j]== 0x0b) //接收到11
{
Buffer[0] =0x0b;
j=1; //才開始類加
}
if(Buffer[1]== 0x06)
{
i = 1;
}
}
if(i)
{
if(j< 15)
{
Buffer[j] = Rcv;
j++;
}
}
if(j==15)
{
i = 0;
}
if(Buffer[14]==(Buffer[3]+Buffer[5]+Buffer[7]+Buffer[9]+Buffer[11]+Buffer[13]+0x12))
{
RR = 0;
time_buf1[1] = Buffer[3] ; //年
time_buf1[2] = Buffer[5] ; //月
time_buf1[3] = Buffer[7] ; //日
time_buf1[4] = Buffer[9] ; //時(shí)
time_buf1[5] = Buffer[11]; //分
time_buf1[6] = Buffer[13]; //秒
}
}
}
}
//==========================================
//ADC轉(zhuǎn)換完成中斷服務(wù)程序 VectorNumber_Vadc中斷向量號(hào)23
//==========================================
interrupt VectorNumber_Vadc void ADC_ISR(void)
{
static byte count;
switch(ADch_s)
{
case 19:
ADCbuffer1[count]=ADCR;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 1;
}
break;
case 11:
ADCbuffer1[count]=ADCR;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 2;
}
break;
case 3:
ADCbuffer1[count]=ADCR;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 3;
}
break;
case 4:
ADCbuffer1[count]=ADCR;
count++;
if (count > N-1){
count = 0;
ADCSC1=0x00;
ADcount = 4;
}
break;
default:break;
}
asm(nop); //在此設(shè)置一個(gè)斷點(diǎn),觀測(cè)ad_h和ad_l的變化
}