自动售水机
/*********
**自动售水机
**main.c
*********/
#include <stc15f2k60s2.h>
#include <iic.h>
#define uint unsigned int
#define uchar unsigned char
uint shuju,pay,liang;
uchar model,count;
uchar yi,er,san,si,wu,liu,qi,ba;
uchar shuma_dian[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xff};
uchar shuma_duan[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
//函数体的声明
void keyscan();
void display();
//*************************************************
//初始化函数
//*************************************************
void allinit()
{
P2 = 0x80;P0 = 0xff; //关闭所有LED灯。
P2 = 0xa0;P0 = 0x00; //关闭继电器,蜂鸣器。。。
P2 = 0xc0;P0 = 0xff; //打开所有位选
P2 = 0xff;P0 = 0xff; //关闭所有段选
}
//*************************************************
//对延迟函数的定义
//*************************************************
void Delay_Ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=845;y>0;y--);
}
//
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//*************************************************
//主程序入口
//*************************************************
void main()
{
count = 0;
shuju = 0;
model = 0;
allinit(); //初始化单片机
Timer0Init(); //打开定时计数器
while(1)
{
keyscan(); //键盘扫描函数
display();
}
}
//
void exter0() interrupt 1 //5ms 进入一次
{
count++;
}
//
void keyscan()
{
if(model==0) //上电等待状态
{
if(P30==0) {model=1;while(P30==0);} //如果s7被按下,进入出水状态
yi=0;er=0;san=5;si=0;
wu=0;liu=1;qi=0;ba=0;
}
//
else if(model==1) //出水状态
{
EA = 1; //打开中断,计算出水量
ET0 = 1;
P2 = 0xa0;P0 = 0x10; //打开继电器
if(count>=20) {shuju+=1;count=0;} //每0.1秒,加一,一秒出水量加0.1ml
yi=0;er=0;san=5;si=0;
wu=shuju/1000;liu=shuju%1000/100;
qi=shuju%100/10;ba=shuju%10;
if(P31==0 || shuju>=10000) {model=2;while(P31==0);} //如果S6被按下或者出水量达到最大值,停止出水,进入停水状态
}
//
else if(model==2) //停水状态
{
EA = 0; //关闭中断
ET0 = 0;
pay = shuju * 0.5; //10->5 , 1->0.5
P2 = 0xa0;P0 = 0x00; //关闭继电器
yi=0;er=0;san=5;si=0;
wu=pay/1000;liu=pay%1000/100;
qi=pay%100/10;ba=pay%10;
if(P30==0) {model=1;shuju=0;while(P30==0);} //如果s7被按下,进入出水状态。
}
//
liang = iic_read(0x90,0x01)*1.953; //读取模拟亮度,转换为电压。
if(liang<=125) {P2 = 0x80;P0 = 0xfe;} //低于,LED灯亮。
else {P2 = 0x80;P0 = 0xff;} //高于。LED灯灭。
}
//
void display()
{
P2=0xc0;
P0=0x01; //选择第一位。
P2=0xff;
P0=shuma_duan[yi]; //显示yi的值
Delay_Ms(1);
P2=0xc0;
P0=0x02;
P2=0xff;
P0=shuma_dian[er]; //此位显示需要加上一个点。
Delay_Ms(1);
P2=0xc0;
P0=0x04;
P2=0xff;
P0=shuma_duan[san];
Delay_Ms(1);
P2=0xc0;
P0=0x08;
P2=0xff;
P0=shuma_duan[si];
Delay_Ms(1);
P2=0xc0;
P0=0x10;
P2=0xff;
P0=shuma_duan[wu];
Delay_Ms(1);
P2=0xc0;
P0=0x20;
P2=0xff;
P0=shuma_dian[liu]; //此位显示需要加上一个点。
Delay_Ms(1);
P2=0xc0;
P0=0x40;
P2=0xff;
P0=shuma_duan[qi];
Delay_Ms(1);
P2=0xc0;
P0=0x80;
P2=0xff;
P0=shuma_duan[ba];
Delay_Ms(1);
}
#ifndef _IIC_H
#define _IIC_H
#include "stc15f2k60s2.h"
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(unsigned char ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
unsigned char iic_read(unsigned char addr,unsigned char cmd);
#endif
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(12MHz)
日 期: 2011-8-9
*/
#include "iic.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;
}
//*********************************************
//
unsigned char iic_read(unsigned char addr,unsigned char cmd)
{
unsigned char date;
IIC_Start();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(cmd);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(addr+1);
IIC_WaitAck();
date = IIC_RecByte();
IIC_Stop();
return date;
}
个人见解,感谢阅读。