蓝桥杯单片机竞赛第四届(自动售水机项目)

工程文件
链接:https://pan.baidu.com/s/1Lz3zGF5hL65guvoBPcFYLQ
提取码:5qu8
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

main.c

#include "main.h"



unsigned char code wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位码
unsigned char code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0xc8,0x8c,0xc1,0xbf,0xff,0x7f,0x00};//段码
unsigned char duan_buff[]={0,0,23,22,0,0,0,0};
unsigned char display_date_zongliang[]={0,0,0,0};//后四位段码
unsigned char display_date_danjia[]={0,0,0,0};//前四位段码
unsigned char display_date_jia[]={0,0,0,0};
unsigned int time1_flag=0;//定时器1标志
float shuiliang=0;//总水量
float zongjia=0;//总价
extern unsigned int key_number;//矩阵键盘按键号码
extern unsigned int key_flag;//按键按下标志
unsigned char dianya=0;
unsigned int shuiliang_temp;
unsigned int zongjia_temp;
void main(void)
{
	Timer1Init();
	Timer0Init();
	close();
	while(1)
	{
/*************************************************************
对于光敏电阻,0~255对应于0~5,所以1.25相当于64
************************************************************/
			dianya=PCF8591_adc(1);
		if(dianya<64)
		{
			Y4;
			P0=0xfe;
			P2&=0X1F;
		}
		else
		{
			Y4;
			P0=0xff;
			P2&=0X1F;
		}
		shuiliang_temp=(shuiliang*100+0.5)/100;//精确到小数点后两位
		zongjia_temp=(zongjia*1000+0.5)/100;//精确到小数点后两位
			if(key_number==0)//s7
		{
			Y5;
			P0=0X10;
			P2&=0X1F;
			key_flag=0;
			zongliang(shuiliang_temp/10);
			danjia(50);
			led_segment_display();
			if(shuiliang>=99.99)
			{
			danjia(50);
			zongliang(zongjia_temp);
			led_segment_display();
			}
			if(ET1==0)
			{
				shuiliang=0;
			}
			ET1=1;//打开定时器1
		}
		else if(key_number==4)//s6
		{
			Y5;
			P0=0X00;
			P2&=0X1F;
			key_flag=0;
			
			danjia(50);
			zongliang(zongjia_temp);
			led_segment_display();
			ET1=0;//关闭定时器1
		}
		else
		{
			key_flag=0;
		}
		
		
		
	}
}








/*************************************************************
数码管显示
************************************************************/
void led_segment_display(void)
{
	unsigned char num=0;
		for(num=0;num<4;num++)
	{
		Y6;
		P0=wei[num];
		P2&=0X1F;
		Y7;
		P0=display_date_danjia[num];
		Delay1ms();
		P0=0xff;
		P2&=0X1F;		
	}
		for(num=4;num<8;num++)
	{
		Y6;
		P0=wei[num];
		P2&=0X1F;
		Y7;
		P0=display_date_zongliang[num];
		Delay1ms();
		P0=0xff;
		P2&=0X1F;		
	}
	
	
	num=0;
}








/*************************************************************
后四位段码
************************************************************/
void zongliang(unsigned int number)
{
	display_date_zongliang[4]=duan[number/1000];
	display_date_zongliang[5]=(duan[number/100%10]&(0x7f));//小数点
	display_date_zongliang[6]=duan[number/10%10];
	display_date_zongliang[7]=duan[number%10];	
}
/*************************************************************
前四位段码
************************************************************/
void danjia(unsigned int number)
{
	display_date_danjia[0]=duan[22];
	display_date_danjia[1]=(duan[number/100]&(0x7f));//小数点
	display_date_danjia[2]=duan[number/10%10];
	display_date_danjia[3]=duan[number%10];	
}


/*************************************************************
定时器0初始化
************************************************************/
void Timer1Init(void)		//5毫秒@11.0592MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x00;		//设置定时初值
	TH1 = 0x28;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;
//	ET1=1;
}
/*************************************************************
定时器1中断服务函数
************************************************************/
void time1(void) interrupt 3
{

		
		shuiliang+=0.5;//每毫秒0.1
		zongjia=shuiliang*0.005;//一毫升0.005元

}









}

main.h

#ifndef _MAIN_H
#define _MAIN_H


#include "inter.h"

#include "common.h"

#include "iic.h"
void led_segment_display(void);
void zongliang(unsigned int number);
void danjia(unsigned int number);
void time1(void);
void Timer1Init(void)	;
#endif

common.c

#include "common.h"


/*************************************************************
关闭外设
************************************************************/
void close(void)
{
	Y5;P0=0X00;
	P2&=0X1F;
	Y4;P0=0xff;
	P2&=0X1F;
}
/*************************************************************
数码管显示延时函数
************************************************************/
void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}

common.h

#ifndef _COMMON_H
#define _COMMON_H

#include "STC15F2K60S2.H"
#include "intrins.h"
/*************************************************************
对于锁存器的定义
************************************************************/
#define Y4 P2=(P2&0X1F)|0X80
#define Y5 P2=(P2&0X1F)|0Xa0
#define Y6 P2=(P2&0X1F)|0Xc0
#define Y7 P2=(P2&0X1F)|0Xe0
void close(void);

void Delay1ms()	;

#endif

inter.c

#include "inter.h"



/*************************************************************
定时器0初始化
************************************************************/
void Timer0Init(void)		//5毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;
	ET0=1;
	
}

/*************************************************************
定时器0中断服务函数
************************************************************/
void time0(void) interrupt 1
{
	key_scany();
}

unsigned int key_flag=0;
unsigned int key_number=10;


/*************************************************************
矩阵键盘扫描
************************************************************/
void key_scany(void)
{
	unsigned int key_x,key_y;
	key_x=0;key_y=0;
	if(key_flag==0)
	{
		P3=0X0F;P42=0;P44=0;
		if(!P30|!P31|!P32|!P33)
		{
			if(P30==0) key_y=1;
			if(P31==0) key_y=2;
			if(P32==0) key_y=3;
			if(P33==0) key_y=4;
		}
		P3=0XF0;P42=1;P44=1;
		if(!P34|!P35|!P42|!P44)
		{
			if(P34==0) key_x=4;
			if(P35==0) key_x=3;
			if(P42==0) key_x=2;
			if(P44==0) key_x=1;
		}		
		if(key_x&&key_y)
		{
			key_number=4*key_y+key_x-5;
			key_flag=1;
			while(!P34|!P35|!P42|!P44);
		}
		else
			key_flag=0;
	}
}





inter.h

#ifndef _INTER_H_
#define _INTER_H_


void Timer0Init(void)	;

void key_scany(void);

#include "common.h"


#endif

iic.c

#include "iic.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}    


#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */


//总线启动条件
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(bit 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  PCF8591_adc(unsigned char address)//有四个引脚//AIN0-3,Rb2是AIN3所以地址是3
{
unsigned char date;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(address);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	date=IIC_RecByte();
	IIC_Ack(0);//就应答了
	IIC_Stop();

	return date;
	
}


///*******************************************************************
//模拟转数字
//********************************************************************/
//void PCF8591_dac(unsigned char date)
//{

//	IIC_Start();
//	IIC_SendByte(0x90);
//	IIC_WaitAck();
//	IIC_SendByte(0x40);//告诉芯片现在是dac模式
//	IIC_WaitAck();

//	IIC_SendByte(date);
//	IIC_WaitAck();
//	IIC_Ack(0);//就应答了
//	IIC_Stop();
//}

///*******************************************************************
//e2prom存储,读数据
//********************************************************************/
//unsigned char e2prom_read(unsigned char address)
//{
//	unsigned char date;
//	IIC_Start();
//	IIC_SendByte(0xa0);
//	IIC_WaitAck();
//	IIC_SendByte(address);
//	IIC_WaitAck();
//	IIC_Stop();
//	
//	IIC_Start();
//	IIC_SendByte(0xa1);
//	IIC_WaitAck();
//	date=IIC_RecByte();
//	IIC_Ack(0);//就应答了
//	IIC_Stop();
//	return date;
//	
//	
//}



///*******************************************************************
//e2prom存储,写数据
//********************************************************************/

//void e2prom_write(unsigned char address,unsigned char date )
//{
//	IIC_Start();
//	IIC_SendByte(0xa0);
//	IIC_WaitAck();
//	IIC_SendByte(address);
//	IIC_WaitAck();
//	IIC_SendByte(date);
//	IIC_Stop();
//}






iic.h

#ifndef _IIC_H
#define _IIC_H

#include "common.h"
unsigned char PCF8591_adc(unsigned char address);

//void PCF8591_dac(unsigned char date);

//unsigned char e2prom_read(unsigned char address);

//void e2prom_write(unsigned char address,unsigned char date );






#endif
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要不掉毛的程序羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值