|
#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;
}
|
|