|
#include<driver.h>
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar def[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
bit waterflag=0;
uchar keyvalue=0,watercount=0,adcount=0,advalue=255;
uint water10ml=0,allprice=0,waterprice=5; //水的單價0.5元用整數5來代替
void display();
void main()
{
init_close(); //關閉燈,繼電器和數碼管
Timer0Init();
init_pcf8591();
while(1)
{
keyvalue=key_scan(); //按鍵掃描
if((keyvalue==7)&&(!waterflag)) waterflag=1,watercount=0,water10ml=0;//按鍵s7按下時
else if(keyvalue==6) waterflag=0; //按鍵s6按下時,停止出水
if((watercount==100)&&waterflag) //0.1s10ml出水
{
watercount=0;water10ml++;
if(water10ml==9999) waterflag=0; //當出水99.99L時,關閉出水
}
allprice=water10ml*waterprice;//這里本來是還要再除以10的,在顯示再乘以10是一樣的
if(adcount==200) {adcount=0;advalue=adc_pcf8591();} //讀取ad值
def[1]=tab[waterprice/10]&0x7f;def[2]=tab[waterprice%10];def[3]=0xc0; //顯示水費率
// def[1]=tab[advalue/100];def[2]=tab[advalue%100/10]; //測量當前ad值
// def[3]=tab[advalue%100%10];
if(waterflag) //出水時顯示當前正在出水量
{
def[4]=tab[water10ml/1000];def[5]=tab[water10ml%1000/100]&0x7f;
def[6]=tab[water10ml%1000%100/10];def[7]=tab[water10ml%1000%100%10];
}
else //不出水時顯示當前價格
{
def[4]=tab[allprice/10000];def[5]=tab[allprice%10000/1000]&0x7f;
def[6]=tab[allprice%10000%1000/100];
def[7]=tab[allprice%10000%1000%100/10];
}
}
}
void timer0() interrupt 1
{
watercount++;adcount++; //ad計數位和水計時位
if(waterflag) openrelay(); //出水時開繼電器
else closerelay(); //不出水時關繼電器
if(advalue<(125*255/500)) openled1();//光線暗時光敏阻值變大,advalue小,亮led1
else closeled1(); //光線亮時關led1
display();
}
void display()
{
static uchar i=0;
P0=1<<i;P2=0xc0;P2=0x00;
P0=def[i];P2=0xe0;P2=0x00;
if(++i==8) i=0;
}
#include<driver.h>
//總線啟動條件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//總線停止條件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//應答位控制
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待應答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通過I2C總線發送數據
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//從I2C總線上接收數據
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
void operate_delay(uchar t)
{
uchar i;
while(t--) for(i=0;i<112;i++);
}
void init_pcf8591()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
operate_delay(10);
}
uchar adc_pcf8591()
{
uchar da;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
da=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return da;
}
void init_close()
{
P0=0xff;P2=0x80;P2=0x00;
P0=0x00;P2=0xa0;P2=0x00;
P0=0xff;P2=0xe0;P2=0x00;
}
void openrelay()
{
P0=0x10;P2=0xa0;P2=0x00;
}
void closerelay()
{
P0=0x00;P2=0xa0;P2=0x00;
}
void openled1()
{
P0=0xfe;P2=0x80;P2=0x00;
}
void closeled1()
{
P0=0xff;P2=0x80;P2=0x00;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0xCD; //設置定時初值
TH0 = 0xD4; //設置定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
ET0=1;
EA=1;
}
uchar key_scan()
{
static uchar pre=0,keypress=0,i=0;
if((s6==0)||(s7==0)) keypress++;
else keypress=0;
if(keypress==3)
{
pre=1;
if(s6==0) i=6;
else if(s7==0) i=7;
}
if((s6==1)&&(s7==1)&&(pre==1)) {pre=0;return i;}
return 0;
}
|
|