蓝桥杯-自动售水机

博客分享了关于自动售水机的个人见解,虽内容简短,但聚焦自动售水机这一主题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自动售水机

 


/*********

**自动售水机

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

个人见解,感谢阅读。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值