难点:1显示出水量:总出水量有小数点所以让总出水量*100,计算总出水量中断是以一毫秒为周期的,出水速度为100ml/秒,数码管显示:出水总量以升为单位,0.01升=10ml,所以每过100ms让总出水量加一。
if(water_flag==1)
{
water_count++;
if(water_count>=100)
{
water_count=0;
water=water+1;
}
}
2显示总价:价格还是让价格*100显示;因为价格为0.5元/升,所以直接让总出水量除以2得到价格
main.c
#include <STC15F2K60S2.H>
#include <IIC.H>
unsigned char display_mode=1;//数码管显示界面
unsigned int water;//总出水量
unsigned int cost;//价格
unsigned int dianya;//电压
unsigned char ad(unsigned char add)//ad函数
{
unsigned char date;
IIC_Start();
IIC_SendByte(0X90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0X91);
IIC_WaitAck();
date=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return date;
}
unsigned int ad_count;
void da_process()//用于读取采集电压
{
if(ad_count>5)
{
ad_count=0;
dianya=ad(0x01);
dianya=dianya/51;
}
}
void Device_ctrl(unsigned char p2date,unsigned char p0date)
{
P0=p0date;
P2=P2&0x1f|p2date;
P2&=0x1f;
}
unsigned char trig_btn;
unsigned char cont_btn;
unsigned int key_count;
bit water_flag;
void key_btn()//按键函数
{
unsigned char readdate=P3^0xff;
trig_btn=readdate&(cont_btn^readdate);
cont_btn=readdate;
}
void key_process()//按键处理函数
{
if(key_count>=5)
{
key_count=0;
key_btn();
if(trig_btn==0x08)//s4
{
}
if(trig_btn==0x04)//s5
{
}
if(trig_btn==0x02)//s6
{
display_mode=0;
water_flag=0;
cost=0.5*water;
Device_ctrl(0xa0,0x00);
}
if(trig_btn==0x01)//s7
{
display_mode=1;
water_flag=1;
Device_ctrl(0xa0,0x30);
}
}
}
unsigned char smg_display[8];
unsigned int smg_count;
unsigned char smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void smg_show()//数码管函数
{
unsigned int i;
Device_ctrl(0xc0,0);
Device_ctrl(0xe0,~smg_display[i]);
Device_ctrl(0xc0,0x01<<i);
i=(i+1)%8;
}
void smg_process()//数码管界面显示
{
if(smg_count>=3)
{
smg_count=0;
if(display_mode)
{
smg_display[0]=0x00;
smg_display[1]=smg_du[0]|0x80;
smg_display[2]=smg_du[5];
smg_display[3]=smg_du[0];
smg_display[4]=smg_du[water/1000];
smg_display[5]=smg_du[water/100%10]|0x80;
smg_display[6]=smg_du[water/10%10];
smg_display[7]=smg_du[water%10];
}
else
{
smg_display[0]=0x00;
smg_display[1]=smg_du[0]|0x80;
smg_display[2]=smg_du[5];
smg_display[3]=smg_du[0];
smg_display[4]=smg_du[cost/1000];
smg_display[5]=smg_du[cost/100%10]|0x80;
smg_display[6]=smg_du[cost/10%10];
smg_display[7]=smg_du[cost%10];
}
}
}
unsigned int led_count;
void led_process()//LED函数
{
if(led_count>5)
{
led_count=0;
if(dianya<1.25)
{
Device_ctrl(0x80,~0x01);
}
else
{
Device_ctrl(0x80,0xff);
}
}
}
void Timer2Init() //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初值
T2H = 0xD1; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2|=0X04;
EA=1;
}
void main()
{
Timer2Init();
Device_ctrl(0x80,0xff);
Device_ctrl(0xa0,0x00);
while(1)
{
smg_process();
key_process();
da_process();
led_process();
}
}
unsigned int water_count;
void water_process()
{
if(water_flag==1)
{
water_count++;
if(water_count>=100)
{
water_count=0;
water=water+1;
}
}
}
void timer2service() interrupt 12
{
smg_count++;
smg_show();
ad_count++;
water_process();
key_count++;
led_count++;
}
iic.c
#include "iic.h"
#define DELAY_TIME 5
//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//I2C总线启动信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//I2C总线停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
iic.h
#ifndef __IIC_H
#define __IIC_H
#include <STC15F2K60S2.H>
#include "intrins.h"
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif