//------------------------------------------------------------------------------------
// Main.c
//------------------------------------------------------------------------------------
// Copyright (C) 2011 Shenyang 213.
// Wbr
// Tool chain: KEIL Full 'c'
//
//#pragma CD OE DB SB // Compilation directives
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include "C8051F340.h"
#include "1302.h"
#include "lcd.h"
#include
#define SYSCLK 12000000 // SYSCLK frequency in Hz
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define uint unsigned int
#define uchar unsigned char
#define T 1800 //运算电量的时间单位1800是半个小时(1800秒)
#define N 11
sfr16 TMR2 = 0xCC; //定义成16位地址
sfr16 ADC0 = 0xBD;
uint xdata ADCbuffer1[N];
uint count;
uint sum = 0;
uchar ADcount = 0;
uchar ADsend;
uchar Page = 1,direction = 1;
uchar set = 0,ent = 0,Tset;
uchar TH,TL,TT1,TT2,TT3; //用来拆分送显示的变量
uchar keybuffer[6];
uchar BGset=0; //BGset背光关,开控制量,如果没有键按下超过1分钟,关闭背光!有键按下立刻开背光
bit Disptime,PDD;
sbit DI1 = P0^0 ;
sbit DI2 = P0^1 ;
sbit DE = P0^6 ;
sbit BLK = P0^7 ; //LCD背光
sbit JC1 = P2^7 ;
sbit JC2 = P3^1 ;
sbit JC3 = P3^2 ;
sbit JC4 = P3^3 ;
sbit DI3 = P3^6 ;
sbit DI4 = P3^7 ;
uchar code CPT_c[20] _at_ 0x8000; //7k的地址左右//充电时间要存入的FLASH地址,保存3天的时间和功率
uchar xdata CPT_x[20] _at_ 0x8000;
uchar code FPT_c[20] _at_ 0x8200; //7k的地址左右//放电时间要存入的FLASH地址,保存3天的时间和功率
uchar xdata FPT_x[20] _at_ 0x8200;
uchar xdata Between[20]; //0~11时间12~19存功率
////////////////////////////////////
extern void Init_Device(void);
extern uchar time_buf1[8] ;
uchar code tab1[]={
"实时电压:"
};
uchar code tab2[]={
"实时电流:"
};
uchar code tab3[]={
"实时功率:"
};
uchar code tab4[]={
"运行状态:"
};
uchar code tab5[]={
"历史充电记录"
};
uchar code tab6[]={
"历史放电记录"
};
uchar code tab7[]={
"当前时间"
};
uchar code tab8[]={
"修改时间"
};
uchar code tab9[]={
"暂无记录"
};
uchar code run1[]={
"停机"
};
uchar code run2[]={
"充电"
};
uchar code run3[]={
"放电"
};
uchar code run4[]={
"故障"
};
//uchar code run5[]={
//"系统故障信息"
//};
uchar code run5[]={
"感谢您的使用"
};
uchar code run6[]={
"本日累计充电"
};
uchar code run7[]={
"本日累计放电"
};
uchar code run8[]={
"版本号:V1.0"
};
uchar xdata TAB[11]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20};//数字0~9及显示空白0x20
//----------------------------------------
// Function PROTOTYPES
//----------------------------------------
void delayms(uint ms)
{
uint Temp;
while(ms--)
{
Temp=1000;
while(Temp--);
{
//PCA0CPH2 = 1;
}
}
}
/*void Timer2_Init(int count2s)
{
TMR2CN = 0x00;
TMR2L = -count2s;
TMR2 = 0xffff;
ET2 = 1;
TR2 = 1;
}*/
//================================
//中值滤波程序
//================================
void filter()
{
static uchar count,i,j;
uint value_buf[N];
uint temp;
sum=0;
for(count=0;count
{
value_buf[count] = ADCbuffer1[count];;
}
for (j=0;j
{
for (i=0;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
关键字:C8051F UART0 TIME3
引用地址:基于C8051F的AD UART0 KEY FLASH TIME3程序
sum += value_buf[count];
}
void Uart0_SendData(uchar dat0)
{
SBUF0=dat0; //写SBUF0,开始发送
while(TI0==0); //等待发送
TI0=0; //清发送标志位
}
void Flash_Erase_CTP() //flash擦除充电时间和功率
{
EA =0;
VDM0CN = 0x80; // 使能VDD监视器
RSTSRC = 0x02; // 上电复位VDD监视器复位标志
FLSCL=0X80; // 使能FLASH单稳态定时器,FLASH读时间SYSCLK<=25MHz
FLKEY = 0xA5; // 写入关键字
FLKEY = 0xF1; // 写入关键字
PSCTL |= 0x03; //允许擦,允许写
CPT_x[0] = 0;
PSCTL &= ~0x03; //禁止写,禁止擦
//EA = 1;
}
void Flash_Program_CTP() //flash写入充电时间时间和功率
{
uchar j;
EA =0;
//Flash_Erase_CTP();
VDM0CN = 0x80; //使能VDD监视器
RSTSRC = 0x02; //上电复位/VDD监视器复位标志
FLSCL=0X80; //使能FLASH单稳态定时器,FLASH读时间SYSCLK<=25MHz
PSCTL |= 0x01; //write enable
for(j =0;j<20;j++)
{
FLKEY = 0xa5;
FLKEY = 0xf1;
CPT_x[j] = Between[j];
//delayms(30);
}
PSCTL &= ~0x01; //禁止写
EA = 1;
}
//***********************************
void Flash_Erase_FTP() //flash擦除放电时间和功率
{
EA =0;
VDM0CN = 0x80; // 使能VDD监视器
RSTSRC = 0x02; // 上电复位VDD监视器复位标志
FLSCL=0X80; // 使能FLASH单稳态定时器,FLASH读时间SYSCLK<=25MHz
FLKEY = 0xA5; // 写入关键字
FLKEY = 0xF1; // 写入关键字
PSCTL |= 0x03; //允许擦,允许写
FPT_x[0] = 0;
PSCTL &= ~0x03; //禁止写,禁止擦
//EA = 1;
}
void Flash_Program_FTP() //flash写入放电时间和功率
{
uchar j;
//Flash_Erase_FTP();
EA = 0;
VDM0CN = 0x80; //使能VDD监视器
RSTSRC = 0x02; //上电复位/VDD监视器复位标志
FLSCL=0X80; //使能FLASH单稳态定时器,FLASH读时间SYSCLK<=25MHz
PSCTL|=0x01; //write enable
for(j =0;j<20;j++)
{
FLKEY = 0xa5;
FLKEY = 0xf1;
FPT_x[j] = Between[j];
}
PSCTL &= ~0x01; //禁止写
EA = 1;
}
/*void Flash_Read()
{
static uchar j;
for(j=0;j<3;j++)
{
timer[j]=Ftime_c[j];
}
}*/[page]
//**********************************************
//按键处理程序
//**********************************************
void key_scan()
{
static uchar i,k;
uchar Mkey=P4;
if(BGset<2)
{
if((Mkey&0xFE)!= 0XFE) //有键按下先开启背光
{
delayms(200);
if((Mkey&0xFE)!= 0XFE)
{
BGset++;
if(BGset>1)
{
BGset = 2;
}
}
}
}
if(BGset ==2 )
{
if(!(Mkey&0x80)) //SW1按下吗?ALM
{
delayms(200); //消抖
if(!(Mkey&0x80)) //再判断
{
BGset =2; //开背光
if(k<1) {Page = 0;} //页面0:显示故障状态}
k++;
if(k>1) {k =0;Page = 1; } //再按后退出
set = 0;
}
}
if(!set)
{
if(!(Mkey&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(Mkey&0x40))
{
if(Page !=0)
{
Page++;
BGset =2;
if(Page>6) //如果超过5界面回到1画面
{
Page = 1;
}
}
}
}
if(!(Mkey&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(Mkey&0x20))
{
if(Page !=0)
{
Page--;
BGset =2;
if(Page<1) //小于1画面后不显示0画面,显示6画面
{
Page = 6;
}
}
}
}
}
if(Page ==6) //修改时间界面
{
if(!(Mkey&0x04)) //SW6按下吗?设定SET只在6画面设置时间
{
delayms(200);
if(!(Mkey&0x04))
{
BGset =2;
set = 1; //如果按下SET键表示开始设置时间,置设置标志位;
}
}
if(set)
{
if(!(Mkey&0x10)) //SW4按下吗?左移<- 只在6画面修改时间
{
delayms(200);
if(!(Mkey&0x10))
{
BGset =2;
direction--;
if(direction < 1)
{
direction = 6;
}
}
}
if(!(Mkey&0x08)) //SW5按下吗?右移->只在6画面修改时间
{
delayms(200);
if(!(Mkey&0x08))
{
BGset =2;
direction++;
if(direction > 6)
{
direction = 1;
}
}
}
switch(direction)
{
case 1:
{
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset =2;
keybuffer[0]++;
if(keybuffer[0]>99) //年设置,不超过100年
{
keybuffer[0] = 11;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset =2;
keybuffer[0]--;
if(keybuffer[0]<11) //小于1画面后不显示0画面,显示6画面
{
keybuffer[0] = 11;
}
}
}
if(Tset < 4)
{
TH = keybuffer[0]/10;
TL = keybuffer[0]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (1,0,0x91,1,0x20,0x20);
}
}break;
case 2:
{
TH = keybuffer[0]/10;
TL = keybuffer[0]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset =2;
keybuffer[1]++;
if(keybuffer[1]>12) //月设置,不超过12月
{
keybuffer[1] = 1;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset =2;
keybuffer[1]--;
if(keybuffer[1]<1) //小于1 显示12月
{
keybuffer[1] = 12;
}
}
}
if(Tset < 4)
{
TH = keybuffer[1]/10;
TL = keybuffer[1]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (1,0,0x93,1,0x20,0x20);
}
}break;
case 3:
{
TH = keybuffer[1]/10;
TL = keybuffer[1]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset =2;
keybuffer[2]++;
if(keybuffer[2]>31) //日设置,不超过31日
{
keybuffer[2] = 1;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset =2;
keybuffer[2]--;
if(keybuffer[2]<1) //小于1,显示31日
{
keybuffer[2] = 31;
}
}
}
if(Tset<4)
{
TH = keybuffer[2]/10;
TL = keybuffer[2]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (1,0,0x95,1,0x20,0x20);
}
}break;
case 4:
{
TH = keybuffer[2]/10;
TL = keybuffer[2]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset =2;
keybuffer[3]++;
if(keybuffer[3]>23) //时设置,不超过24
{
keybuffer[3] = 0;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset =2;
keybuffer[3]--;
if(keybuffer[3]<=0) //小于1,显示23
{
keybuffer[3] = 23;
}
}
}
if(Tset < 4)
{
TH = keybuffer[3]/10;
TL = keybuffer[3]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (0,1,0x85,1,0x20,0x20);
}
}break;
case 5:
{
TH = keybuffer[3]/10;
TL = keybuffer[3]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]);
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset =2;
keybuffer[4]++;
if(keybuffer[4]>59) //分设置,不超过59
{
keybuffer[4] = 0;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset =2;
keybuffer[4]--;
if(keybuffer[4]<=0) //小于1,显示59
{
keybuffer[4] = 59;
}
}
}
if(Tset < 4)
{
TH = keybuffer[4]/10;
TL = keybuffer[4]%10;
number_disp (0,1,0x87,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (0,1,0x87,1,0x20,0x20);
}
}break;
case 6:
{
TH = keybuffer[4]/10;
TL = keybuffer[4]%10;
number_disp (0,1,0x87,1,TAB[TH],TAB[TL]);
if(!(P4&0x40)) //SW2按下吗?下翻
{
delayms(200);
if(!(P4&0x40))
{
BGset = 2;
keybuffer[5]++;
if(keybuffer[5]>59) //时设置,不超过24
{
keybuffer[5] = 0;
}
}
}
if(!(P4&0x20)) //SW3按下吗?上翻
{
delayms(200);
if(!(P4&0x20))
{
BGset = 2;
keybuffer[5]--;
if(keybuffer[5]<=0) //小于1,显示23
{
keybuffer[5] = 59;
}
}
}
if(Tset < 4)
{
TH = keybuffer[5]/10;
TL = keybuffer[5]%10;
number_disp (0,1,0x89,1,TAB[TH],TAB[TL]);
}
if(Tset>4)
{
number_disp (0,1,0x89,1,0x20,0x20);
}
}break;
default:break;
}
if(!(Mkey&0x02)) //SW7按下吗?确认ENT 只在6画面设定时间
{
delayms(200);
if(!(Mkey&0x02))
{
BGset =2;
for(i=0;i<6;i++)
{
time_buf1[i+1] = keybuffer[i];
}
Ds1302_Write_Time(); //写DS1302
set = 0;
Page = 1; //退出到1画面
}
}
}
}
}
} [page]
void Pchange(uint PW)
{
TH = PW/10000; //放电万位
TL = (PW-TH*10000)/1000; //千位
TT1 = (PW-TH*10000-TL*1000)/100;
TT2 = (PW-TH*10000-TL*1000-TT1*100)/10;
TT3 = (PW-TH*10000-TL*1000-TT1*100)%10;
if(!TH)
{
TH = 10;
if(!TL)
{
TL = 10;
if(!TT1)
{
TT1 = 10;
}
}
}
}
//-----------------------------------------------------------------------------
// Main 年:0xC4EA 月:0xD4C2 日:0xC8D5 时:0xCAB1: 分0xB7D6: 秒:0xC3EB 的汉字内码
//-----------------------------------------------------------------------------
void main(void)
{
uchar Page1,j;
uchar Runstate ; //Runstate为运行状态指示:DI1=1;DI2=1停机;DI1=0;DI2=1充电;DI1=1;DI2=0放电;DI1=1;DI2=1故障
uint VT,AT,PT,PC1,PF1,PDIS,PdownCount; //电压电流功率功率计数变量
uint ADC1,ADC2,ADC3,ADC4; //四路AD通道变量
long a,PT1,PT2; //P1,P2充放电累计功率
//P0 = 0;
//P1 = 0;
P4 =0xfe;
P2 = 0;
P3 = 0;
Init_Device();
PCA0MD &= ~0x40;
EA = 0;
//BLK = 1;
delayms(1000);
Ds1302_Init();
init_lcd ();
clrram ();
ADC0CF = ((SYSCLK/3000000)-1)<<3; // set SAR clock to 3MHz
ADC0CN |=0x10; //写ADC0BUSY位启动转换
TMR3CN = 0x04; //启动TM3
//Timer2_Init(SYSCLK/12/50); //20ms
EA = 1;
DE = 1;
TR1 = 1;
Ds1302_Read_Time();
while(1)
{
//PCA0CPH2 = 1; //喂狗
key_scan();
if(BGset)
{
BLK = 1;
}
if(!BGset)
{
BLK = 0;
} //按键扫描
if((DI1==1)&&(DI2==1)) Runstate = 0xa6; //停机
if((DI1==0)&&(DI2==1)) Runstate = 0xb7; //充电
if((DI1==1)&&(DI2==0)) Runstate = 0xc8; //放电
if((DI1==0)&&(DI2==0)) Runstate = 0xd9; //故障
//if(Runstate == 0xb7) //充电的FLASH存储处理
if(!set)
{
if((time_buf1[2] != CPT_c[10])|| (time_buf1[3] != CPT_c[11])) //读取的当前时间与缓存不等的时候,所有内容依次前移
{
Between[0]=CPT_c[3]; //依次前移
Between[1]=CPT_c[4];
Between[2]=CPT_c[5];
Between[3]=CPT_c[6];//年
Between[4]=CPT_c[7];//月
Between[5]=CPT_c[8];//日
Between[6]=CPT_c[9];
Between[7]=CPT_c[10];
Between[8]=CPT_c[11];
Between[9]=time_buf1[1];
Between[10]=time_buf1[2];
Between[11]=time_buf1[3];
Between[12]=CPT_c[14];
Between[13]=CPT_c[15];
Between[14]=CPT_c[16];
Between[15]=CPT_c[17];
Between[16]=CPT_c[18];
Between[17]=CPT_c[19];
Between[18] = PC1>>8;
Between[19] = PC1&255;
Flash_Erase_CTP();
Flash_Program_CTP(); //保存至FLASH
}
}
//if(Runstate == 0xc8) //放电时FLASH存储处理
if(!set)
{
if((time_buf1[2] != FPT_c[10])|| (time_buf1[3] != FPT_c[11]))
{
Between[0]=FPT_c[3]; //依次前移
Between[1]=FPT_c[4];
Between[2]=FPT_c[5];
Between[3]=FPT_c[6];//年
Between[4]=FPT_c[7];//月
Between[5]=FPT_c[8];//日
Between[6]=FPT_c[9];
Between[7]=FPT_c[10];
Between[8]=FPT_c[11];
Between[9]=time_buf1[1];
Between[10]=time_buf1[2];
Between[11]=time_buf1[3];
Between[12]=FPT_c[14];
Between[13]=FPT_c[15];
Between[14]=FPT_c[16];
Between[15]=FPT_c[17];
Between[16]=FPT_c[18];
Between[17]=FPT_c[19];
Between[18] = PF1>>8;
Between[19] = PF1&255;
Flash_Erase_FTP();
Flash_Program_FTP(); //保存至FLASH
}
}
if(PDD)
{
PDD = 0;
if(Runstate == 0xb7) //如果充电
{
PdownCount++; //秒累加
PT1 = PT1+PT; //秒累计的功率,
PC1 = PT1/3600; //实际充电功率,按小时计算,注意此时累计电量为实际的10倍,为了送小数显示
if(PdownCount > T) //超过半个小时开始写入EEPROM
{
PdownCount = 0;
for(j=0;j<20;j++) //先读出FLASH里的时间
{
Between[j]=CPT_c[j];
}
if((time_buf1[2] == Between[10])&& (time_buf1[3] == Between[11])) //当前时间等于缓存时间,继续写入缓存
{
Between[18] = PC1>>8;
Between[19] = PC1&255;
Flash_Program_CTP(); //写功率和时间到FLASH
}
}
}
if(Runstate == 0xc8) //如果放电
{
PdownCount++; //秒累加
PT2 = PT2+PT; //秒累计的功率
PF1 = PT2/3600; //实际放电功率,按小时计算,,注意此时累计电量为实际的10倍,为了送小数显示
if(PdownCount > T) //超过半个小时开始写入EEPROM
{
PdownCount = 0;
for(j=0;j<20;j++) //先读出FLASH里的时间
{
Between[j]=FPT_c[j];
}
if((time_buf1[2] == Between[10])&& (time_buf1[3] == Between[11])) //当前时间等于缓存时间,继续写入缓存
{
Between[18] = PF1>>8;
Between[19] = PF1&255;
Flash_Program_FTP(); //写功率和时间到FLASH
}
}
}
}
if(Disptime)
{
Disptime = 0;
Ds1302_Read_Time();
if(Page!=Page1)
{
clrram (); //如果页面变化,需要清屏;
}
switch(Page)
{
case 1: //画面1:显示当前电压电流
{
string_disp (1,0,0x80,10,tab1); //显示电压
string_disp (1,0,0x90,10,tab2); //显示电流
string_disp (0,1,0x80,10,tab3); //显示功率
string_disp (0,1,0x90,10,tab4);
if(Runstate == 0xa6)string_disp (0,1,0x96,4,run1); //显示停机
if(Runstate == 0xb7)string_disp (0,1,0x96,4,run2); //显示充电
if(Runstate == 0xc8)string_disp (0,1,0x96,4,run3); //显示放电
if(Runstate == 0xd9)string_disp (0,1,0x96,4,run4); //显示故障
TH= VT/1000; //拆分送显示千位
TL = (VT%1000)/100; //拆分送显示百位
TT1 = ((VT%1000)%100)/10; //拆分送显示十位
TT2 = ((VT%1000)%100)%10; //拆分送显示个位
if(!TH)
{
TH = 10;
if(!TL)
{
TL = 10;
}
}
number_disp (1,0,0x85,1,TAB[TH],TAB[TL]); //电压送显示
number_disp (1,0,0x86,1,TAB[TT1],0x2E);
number_disp (1,0,0x87,1,TAB[TT2],0x20);
number_disp (1,0,0x88,1,0x56,0x20);
TH= AT/1000; //拆分送显示千位
TL = (AT%1000)/100; //拆分送显示百位
TT1 = ((AT%1000)%100)/10; //拆分送显示十位
TT2 = ((AT%1000)%100)%10; //拆分送显示个位
if(!TH) //高位为零,灭零处理
{
TH = 10;
if(!TL)
{
TL = 10;
}
}
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]); //电流送显示
number_disp (1,0,0x96,1,TAB[TT1],0x2E);
number_disp (1,0,0x97,1,TAB[TT2],0x20);
number_disp (1,0,0x98,1,0x41,0x20);
TH= PT/1000; //拆分送显示千位
TL = (PT%1000)/100; //拆分送显示百位
TT1 = ((PT%1000)%100)/10; //拆分送显示十位
TT2 = ((PT%1000)%100)%10; //拆分送显示个位
if(!TH) //高位为零,灭零处理
{
TH = 10;
if(!TL)
{
TL = 10;
}
}
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]); //功率送显示
number_disp (0,1,0x86,1,TAB[TT1],0x2E);
number_disp (0,1,0x87,1,TAB[TT2],0x4B);
number_disp (0,1,0x88,1,0x57,0x20);
Page1=Page; //保存当前页面值
}break;
case 2:
{
string_disp (1,0,0x80,12,run6);
string_disp (0,1,0x80,12,run7);
Pchange(PC1);
number_disp (1,0,0x94,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x95,1,TAB[TT1],TAB[TT2]);
number_disp (1,0,0x96,1,0x2e,TAB[TT3]);
number_disp (1,0,0x97,1,0x4b,0x57);
Pchange(PF1);
number_disp (0,1,0x94,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x95,1,TAB[TT1],TAB[TT2]);
number_disp (0,1,0x96,1,0x2e,TAB[TT3]);
number_disp (0,1,0x97,1,0x4b,0x57);
Page1=Page;
}break;
case 3: //显示历史充电记录
{
string_disp (1,0,0x80,12,tab5); //
//第1条信息
if((CPT_c[0]>99)||(CPT_c[1]>12)||(CPT_c[2]>31))
{
string_disp (1,0,0x90,8,tab9);
} //如果读取时间不对,显示“暂无记录”
else
{
number_disp (1,0,0x90,1,0x32,0x30); //0送显示
TH = CPT_c[0]/10;
TL = CPT_c[0]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x92,1,0xc4,0xea); //年
TH = CPT_c[1]/10;
TL = CPT_c[1]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x94,1,0xd4,0xc2); //月
TH = CPT_c[2]/10;
TL = CPT_c[2]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x96,1,0xc8,0xd5); //日
PDIS = CPT_c[12];
PDIS = PDIS<<8 + CPT_c[13];
Pchange(PDIS);
number_disp (1,0,0x98,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x99,1,TAB[TT1],TAB[TT2]);
number_disp (1,0,0x9A,1,0x2e,TAB[TT3]);
number_disp (1,0,0x9B,1,0x4b,0x57);
}
//第2条信息
if((CPT_c[3]>99)||(CPT_c[4]>12)||(CPT_c[5]>31))
{
string_disp (0,1,0x80,8,tab9);
} //如果读取时间不对,显示“暂无记录”
else
{
number_disp (0,1,0x80,1,0x32,0x30); //0送显示
TH = CPT_c[3]/10;
TL = CPT_c[3]%10;
number_disp (0,1,0x81,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x82,1,0xc4,0xea); //年
TH = CPT_c[4]/10;
TL = CPT_c[4]%10;
number_disp (0,1,0x83,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x84,1,0xd4,0xc2); //月
TH = CPT_c[5]/10;
TL = CPT_c[5]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x86,1,0xc8,0xd5); //日
PDIS = CPT_c[14];
PDIS = PDIS<<8 + CPT_c[15];
Pchange(PDIS);
number_disp (0,1,0x88,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x89,1,TAB[TT1],TAB[TT2]);
number_disp (0,1,0x8A,1,0x2e,TAB[TT3]);
number_disp (0,1,0x8B,1,0x4b,0x57);
}
//第3条信息
if((CPT_c[6]>99)||(CPT_c[7]>12)||(CPT_c[8]>31))
{
string_disp (0,1,0x90,8,tab9); //如果读取时间不对,显示“暂无记录”
}
else
{
number_disp (0,1,0x90,1,0x32,0x30); //0送显示
TH = CPT_c[6]/10;
TL = CPT_c[6]%10;
number_disp (0,1,0x91,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x92,1,0xc4,0xea); //年
TH = CPT_c[7]/10;
TL = CPT_c[7]%10;
number_disp (0,1,0x93,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x94,1,0xd4,0xc2); //月
TH = CPT_c[8]/10;
TL = CPT_c[8]%10;
number_disp (0,1,0x95,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x96,1,0xc8,0xd5); //日
PDIS = CPT_c[16];
PDIS = PDIS<<8 + CPT_c[17];
Pchange(PDIS);
number_disp (0,1,0x98,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x99,1,TAB[TT1],TAB[TT2]);
number_disp (0,1,0x9A,1,0x2e,TAB[TT3]);
number_disp (0,1,0x9B,1,0x4b,0x57);
}
Page1=Page;
}break;
case 4: //显示历史放电记录
{
string_disp (1,0,0x80,12,tab6); //
//第1条信息
if((FPT_c[0]>99)||(FPT_c[1]>12)||(FPT_c[2]>31)) //如果读取时间不对,显示“暂无记录”
{
string_disp (1,0,0x90,8,tab9);
}
else
{
number_disp (1,0,0x90,1,0x32,0x30); //0送显示
TH = FPT_c[0]/10;
TL = FPT_c[0]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x92,1,0xc4,0xea); //年
TH = FPT_c[1]/10;
TL = FPT_c[1]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x94,1,0xd4,0xc2); //月
TH = FPT_c[2]/10;
TL = FPT_c[2]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x96,1,0xc8,0xd5); //日
PDIS = FPT_c[12];
PDIS = PDIS<<8 + FPT_c[13];
Pchange(PDIS);
number_disp (1,0,0x98,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x99,1,TAB[TT1],TAB[TT2]);
number_disp (1,0,0x9A,1,0x2e,TAB[TT3]);
number_disp (1,0,0x9B,1,0x4b,0x57);
}
//第2条信息
if((FPT_c[3]>99)||(FPT_c[4]>12)||(FPT_c[5]>31))
{
string_disp (0,1,0x80,8,tab9); //如果读取时间不对,显示“暂无记录”
}
else
{
number_disp (0,1,0x80,1,0x32,0x30); //0送显示
TH = FPT_c[3]/10;
TL = FPT_c[3]%10;
number_disp (0,1,0x81,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x82,1,0xc4,0xea); //年
TH = FPT_c[4]/10;
TL = FPT_c[4]%10;
number_disp (0,1,0x83,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x84,1,0xd4,0xc2); //月
TH = FPT_c[5]/10;
TL = FPT_c[5]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x86,1,0xc8,0xd5); //日
PDIS = FPT_c[14];
PDIS = PDIS<<8 + FPT_c[15];
Pchange(PDIS);
number_disp (0,1,0x88,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x89,1,TAB[TT1],TAB[TT2]);
number_disp (0,1,0x8A,1,0x2e,TAB[TT3]);
number_disp (0,1,0x8B,1,0x4b,0x57);
}
//第3条信息
if((FPT_c[6]>99)||(FPT_c[7]>12)||(FPT_c[8]>31))
{
string_disp (0,1,0x90,8,tab9);
}
else
{
number_disp (0,1,0x90,1,0x32,0x30); //0送显示
TH = FPT_c[6]/10;
TL = FPT_c[6]%10;
number_disp (0,1,0x91,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x92,1,0xc4,0xea); //年
TH = FPT_c[7]/10;
TL = FPT_c[7]%10;
number_disp (0,1,0x93,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x94,1,0xd4,0xc2); //月
TH = FPT_c[8]/10;
TL = FPT_c[8]%10;
number_disp (0,1,0x95,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x96,1,0xc8,0xd5);
PDIS = FPT_c[16];
PDIS = PDIS<<8 + FPT_c[17];
Pchange(PDIS);
number_disp (0,1,0x98,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x99,1,TAB[TT1],TAB[TT2]);
number_disp (0,1,0x9A,1,0x2e,TAB[TT3]);
number_disp (0,1,0x9B,1,0x4b,0x57);
}
Page1=Page;
}break;
case 5: //显示当前时间
{
string_disp (1,0,0x80,10,tab7);
number_disp (1,0,0x90,1,0x32,0x30); //0送显示
TH = time_buf1[1]/10;
TL = time_buf1[1]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x92,1,0xc4,0xea); //年
TH = time_buf1[2]/10;
TL = time_buf1[2]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x94,1,0xd4,0xc2); //月
TH = time_buf1[3]/10;
TL = time_buf1[3]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x96,1,0xc8,0xd5); //日
TH = time_buf1[4]/10;
TL = time_buf1[4]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]); //
number_disp (0,1,0x86,1,0xca,0xb1); //时
TH = time_buf1[5]/10;
TL = time_buf1[5]%10;
number_disp (0,1,0x87,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x88,1,0xb7,0xd6); //分
TH = time_buf1[6]/10;
TL = time_buf1[6]%10;
number_disp (0,1,0x89,1,TAB[TH],TAB[TL]); //
number_disp (0,1,0x8a,1,0xc3,0xeb); //秒
Page1=Page;
}break;
case 6: //修改时间
{
if(!set) //没有按SET键
{
string_disp (1,0,0x80,10,tab8);
number_disp (1,0,0x90,1,0x32,0x30); //0送显示
TH = time_buf1[1]/10;
TL = time_buf1[1]%10;
number_disp (1,0,0x91,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x92,1,0xc4,0xea); //年
TH = time_buf1[2]/10;
TL = time_buf1[2]%10;
number_disp (1,0,0x93,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x94,1,0xd4,0xc2); //月
TH = time_buf1[3]/10;
TL = time_buf1[3]%10;
number_disp (1,0,0x95,1,TAB[TH],TAB[TL]);
number_disp (1,0,0x96,1,0xc8,0xd5); //日
TH = time_buf1[4]/10;
TL = time_buf1[4]%10;
number_disp (0,1,0x85,1,TAB[TH],TAB[TL]); //
number_disp (0,1,0x86,1,0xca,0xb1); //时
TH = time_buf1[5]/10;
TL = time_buf1[5]%10;
number_disp (0,1,0x87,1,TAB[TH],TAB[TL]);
number_disp (0,1,0x88,1,0xb7,0xd6); //分
TH = time_buf1[6]/10;
TL = time_buf1[6]%10;
number_disp (0,1,0x89,1,TAB[TH],TAB[TL]); //
number_disp (0,1,0x8a,1,0xc3,0xeb); //秒
for (j = 0;j<6;j++)
{
keybuffer[j] = time_buf1[j+1];
}
}
Page1=Page; //保存当前页面值
}break;
case 0: //显示故障状态
{
string_disp (1,0,0x90,12,run5);
string_disp (0,1,0x85,12,run8);
Page1=Page; //保存当前页面值
}break;
default:break;
}
}
if(ADsend)
{
ADsend = 0;
if(ADcount == 1)
{
filter();
ADC1= (sum/(N-2));
if(ADC1<5)
{
ADC1 = 0;
}
a = (long)7500*ADC1/1021; //放大10倍,为了送显示小数点
VT = a; //
ADC0CN |=0x10; //写ADC0BUSY位启动转换
AMX0P = 0x06; //下一个转换通道P30
AD0EN = 1;
}
if(ADcount == 2)
{
filter();
ADC2= (sum/(N-2));
a = (long)4000*ADC2/1021; //放大10倍,为了送显示
AT = a;
a =(long)VT*AT/10000; //放大10倍的功率,单位KW
PT = a;
ADC0CN |=0x10; //写ADC0BUSY位启动转换
AMX0P = 0x08; //下一个转换通道P26
AD0EN = 1;
}
if(ADcount == 3)
{
filter();
ADC3= (sum/(N-2));
ADC0CN |=0x10; //写ADC0BUSY位启动转换
AMX0P = 0x09; //下一个转换通道P34
AD0EN = 1;
}
if(ADcount == 4)
{
filter();
ADC4= (sum/(N-2));
ADC0CN |=0x10; //写ADC0BUSY位启动转换
AMX0P = 0x05; //下一个转换通道P35
AD0EN = 1;
}
}
}
}
void UART0_ISR(void) interrupt 4
{
static uchar Rcv;
if(RI0)
{
Rcv = SBUF0;
RI0 =0;
}
/*if(Rcv == 0x7E) //
{
i = 1;
buffer[0] = Rcv;
}
else
{
if(i < 13) //12个字节
{
buffer[i] = Rcv;
i++;
}
} */
}
/*void TIME2_ISR (void) interrupt 5
{
TF2H = 0; //清标志位
count1++;
if(count1 ==5)
{
count1 = 0;
}
} */
void ADC0_ISR (void) interrupt 10
{
static uchar count; // Loop counter
AD0INT = 0; //清中断标志位
switch( AMX0P ) //通道转换
{
case 0x05: //P2.6
ADCbuffer1[count]=ADC0;
count++;
ADC0CN |=0x10; //写ADC0BUSY位启动转换
if (count > N-1){
count = 0;
AD0EN = 0; //禁止转换
ADcount = 1;
}
break;
case 0x06: //P3.0
ADCbuffer1[count]=ADC0;
count++;
ADC0CN |=0x10; //写ADC0BUSY位启动转换
if (count > N-1){
count = 0;
AD0EN = 0;
ADcount = 2;
}
break;
case 0x08: //P3.4
ADCbuffer1[count]=ADC0;
count++;
ADC0CN |=0x10; //写ADC0BUSY位启动转换
if (count > N-1){
count = 0;
AD0EN = 0;
ADcount = 3;
}
break;
case 0x09: //P3.5
ADCbuffer1[count]=ADC0;
count++;
ADC0CN |=0x10; //写ADC0BUSY位启动转换
if (count > N-1){
count = 0;
AD0EN = 0;
ADcount = 4;
}
break;
default:break;
}
}
//-----------------------------------------------------------------------------
//TIMER3中断
//-----------------------------------------------------------------------------
void Timer3_ISR(void) interrupt 14
{
static uchar i,j,k;
TMR3CN &=~(0x80); //清标志位
count++;
i++;
j++;
if(count == 8) //200ms
{
count = 0;
ADsend = 1; //开始进行AD处理标志
Tset++;
if(Tset>5)
{
Tset = 0;
}
}
if(i==20)
{
i = 0;
Disptime = 1;
}
if(j==39) //1秒误差累积;正常是40
{
j = 0;
PDD = 1; //一秒时间到,开始计算功率
if(BGset)
{
k++;
if(k>240) //4分钟关背光
{
k=0;
BGset = 0;
}
}
}
}
上一篇:基于C8051F的18B20程序
下一篇:单片机智能家居之-窗帘控制器(上电自动识别位置)
推荐阅读最新更新时间:2024-03-16 14:02
低电压放大器AD8517
1 AD8517的主要特点
AD8517是AD公司生产的低电压放大器,它可在低至1.8V的电源电压下工作,由于它能在大多数普通电池的放电电压终止的情况下工作,所以这种放大器对于那些用电池供电的应用场合是很理想的。
AD8517在电源电压低于1.8V的情况下具有非凡的轨至轨输入和输出特性,在放大器的电源范围定到1.8V时,如果把共模电压定到1.8Vp-p,就能使输出摆到电源的上下轨迹上而不会出现削波现象。
AD8517可以在给定的从1.8V到5V的全部电源电压范围内获得良好的轨至轨特性。AD8517低电压放大器还具有很低的总谐波失真,这使得该放大器在音频应用方面也很理想。在同相组态下,当增益为1时,对于Vs 3V的情况,
[应用]
基于McBSP的高速串行数据采集系统设计
1. 序言 本文介绍了基于TI公司的新一代DSP芯片TMS320C6711和AD公司的串行模数转换芯片AD974的嵌入式数据采集系统的设计方法。 TMS320C6711是32bit浮点信号处理器,核心电压1.8V,工作频率100-150MHz,2级Cache,运算速度 900MFLOPS。其多通道缓冲串口(Multi-channel Buffered Serial Port,McBSP)可直接与AD974进行串口连接,为系统提供高性能的A/D转换和数据处理能力。 AD974是美国模拟器件公司生产的一个200kSPS、4通道、16位数据采集系统。具有高通过率、低功耗、高精度等特性,此外,该器件还集成了外围器件,并采用串行通
[单片机]
AD数据采集的“数字滤波”:10个“软件滤波程序”
在AD采集中经常要用到数字滤波,而不同情况下又有不同的滤波需求,下面是10种经典的软件滤波方法的程序和优缺点分析: 1、限幅滤波法(又称程序判断滤波法) 2、中位值滤波法 3、算术平均滤波法 4、递推平均滤波法(又称滑动平均滤波法) 5、中位值平均滤波法(又称防脉冲干扰平均滤波法) 6、限幅平均滤波法 7、一阶滞后滤波法 8、加权递推平均滤波法 9、消抖滤波法 10、限幅消抖滤波法 1、限副滤波 A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A),每次检测到新值时判断: 如果本次值与上次值之差 =A,则本次值有效 如果本次值与上次值之差 A,则本次值无效,放弃本次值,用上次值代替本次值 B
[单片机]
ADμC812的数据采集子系统及其ISP技术
摘要:主要介绍AD公司推出的在系统可编程微转换器ADμC812的ADC采集子系统的组成、结构和控制特性;对片内Flash存储器的在系统编程技术和程序调试方式;举例说明如何采用中断方式定时进行AD数据采集和数字滤波的过程。
关键词:数据采集 Flash存储器 ISP 数字滤波
在单片机应用如火口荼的今天,一个真正的单片在系统可编程全智能数据采集系统终于出现了。它就是AD公司最新推出的嵌入式Flash MCU微转换器ADμC812。
ADμC812在单个芯片内集成了8路12位ADC采集系统、2路12位DAC、80C52MCU内核、8KB的闪速/电可擦除程序存储器、640字节的闪速/电可擦除数据存储器、看门狗定时器、640字节的
[单片机]
基于AD630实现蓄电池内阻在线测量
引 言 蓄电池内阻是体现电池性能的重要参数之一,通过研究发现,蓄电池容量和健康状态与内阻有着密切的关系,因此通过内阻的变化,实现对蓄电池的在线监测是目前公认的蓄电池维护的最佳方案之一。蓄电池的内阻一般都很小,只有几十毫欧甚至几毫欧,用直流放电法测量内阻速度慢,且不能实现在线测量,用交流注入法测量的信号很微弱,被充电器以及环境中的噪声所淹没,因此如何有效地抑制噪声也就成了蓄电池内阻在线测量的关键技术。运用锁相放大器可以实现电池内阻在线测量,但是,锁相放大器价格昂贵,使用复杂,用来测量蓄电池内阻,计算过程比较繁琐,一般很难掌握。本文利用AD630 实现了锁相放大,设计、开发了一套电池内阻在线测量系统,并在国家级物理实验教学示范中心建设
[测试测量]
采用单片机AT89C2051和AD7416芯片实现多路温湿度循环检测系统的设计
1、引言 AD7416器件结构 AD7416采用节省空间的SO-8和小型SOIC封装。 2 、系统软硬件设计 2.1 硬件设计 用单片机AT89C2051来实现对AD7416的信号采集和输出控制,硬件设计简单可靠,系统温度节点可扩展性强。为确保系统不受电源波动的干扰,采用电源电压监视器TL7705A作系统复位控制器。如果AD7416要装在离电源较远处,AD7416必须用一个0.1μF的陶瓷电容接在+VS和地之间去耦。 如所有的I2C兼容器件一样,AD7416有一个7位串行地址。这个地址的高4位设定为1001,而低3位可由用户通过将A2~A0脚连接到无论是+VS或GND来设置。通过它们不同的设定地址,可将多达8个AD741
[单片机]
PIC单片机AD转换LED显示程序
;* 单片机 模拟量进行模/数转换,并用 LED 显示出来我们可以看到转换 ;* 结果,0位AD当做8位来用了,利用 单片机 片内硬件资源TMR0和预 分频器 , ;* 为ADC提供定时启动信号, A/D 转换的时钟源选用了系统 周期 的8倍,选 ;* 用了 电源 电压 VDD和VSS作为基准电压,软件方式查询其中断标志位ADIF. ;************************************************************ LIST P=16F877 ;列表伪指令 INCLUDE P16F877.INC ;把包含文件含入源程序 ;******
[单片机]
基于CPLD芯片和C8051F020实现声探测系统数字电路的设计
被动声源探测定位技术是一种利用声学传声器阵列和电子装置接收运动目标的辐射噪声,以确定目标所处位置的技术。 本文正是基于声探测技术原理和成熟的微电子技术, 采用TI公司的32位浮点DSP芯片TMS320VC33-150来实现声源目标的探测定位算法,并辅之以ADC、CPLD、单片机等器件来实现声源信号的采集、系统逻辑控制以及通信功能。对于数字电路的逻辑控制功能,本文选用了Altera公司的CPLD芯片EPM7128AETC100-10来实现。该芯片功耗低、资源丰富、内部延时固定,有助于时序逻辑电路的设计。本系统主要分为两部分:声探测系统数字电路的硬件实现和DSP软件设计。系统现已完成调试,运行稳定,探测效果较好。 系统功能 声
[单片机]
小广播
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐
最新单片机文章
更多热门文章
更多每日新闻
更多往期活动
厂商技术中心