蓝桥杯第三届省赛自动售水机

参考学习视频,用比赛给的驱动写的,重新定义了数据的长度,解决水量和计费溢出问题。在用PCF8951(8位AD转换,2^8 即0-255)进行AD转换时,将数据0-255转换0-100
255*0.39=99.45 近似为100 存在转换误差无法绝对精确蓝桥杯CT107D单片机参考电压为5V,所以(1.25V/5V) *100=25。或者直接计算,(1.25/5)*255=63.75 近似为64

对驱动进行的修改
1 在官方驱动加了一个读取数据的函数
2 将官方驱动的somenop扩大8倍,因为官网驱动提供的驱动代码测试环境:12T, 8051, 12MHz
IAP15F2K61S2具有内部振荡器,振荡器频率可在ISP软件中调整使用或调试驱动代码时,选手需根据设定的片内振荡器频率、所使用单片机的机器周期对代码进行调整;

利用官方驱动写的读取函数

uchar IIC_read(uchar add)
{
		uchar temp;
		IIC_Start();
		IIC_SendByte(0x90);//PCF8951地址
		IIC_WaitAck();
		IIC_SendByte(add);//采集AD信息的地址
		IIC_WaitAck();
		IIC_Stop();

		IIC_Start();
		IIC_SendByte(0x91);//进行读操作
		IIC_WaitAck();
		temp=IIC_RecByte();
		IIC_Stop();
		temp=0.39*temp; //0.39*255=99.45 约等于100将数据0-255转换0-100
   	return temp;
}

主函数

#include <STC15F2K60S2.h>
#include "iic.h"
sbit s7=P3^0;
sbit s6=P3^1;
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
//1 2 3 4 5 6 7 8 9 - 灭
uchar code dottab[]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的数字,此程序主要用第二位,第六位 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
uchar yi,er,san,si,wu,liu,qi,ba;
uchar tt=0;//定时器计数
uint ml_10=0;//10毫升
uint money=0;////计费   全部初始化为0,避免内存分配出问题

void Delay1ms(uchar ms);
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void allinit();
void keyscan();
void Timer0Init(void);
void adrun();

void main()
{
	allinit();
	Timer0Init();
	yi=11,er=0,san=5,si=0,wu=0,liu=0,qi=0,ba=0;
	while(1)
	{
		
	 display1( yi, er);
	 display2( san, si);
	 display3( wu, liu);
	 display4( qi, ba);
	 adrun();
	 keyscan();
	}
}

void Delay1ms(uchar ms)		//@12.000MHz
{
	unsigned char i, j;
  uchar k;
	for(k=ms;k>0;k--)
	{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
	
	}

}


void display1(uchar yi,uchar er)
{
	P2=0XC0;
	P0=0X01;
	P2=0XE0;
	P0=tab[yi];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X02;
	P2=0XE0;
	P0=dottab[er];
	Delay1ms(1);
}

void display2(uchar san,uchar si)
{
	P2=0XC0;
	P0=0X04;
	P2=0XE0;
	P0=tab[san];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X08;
	P2=0XE0;
	P0=tab[si];
	Delay1ms(1);

}

void display3(uchar wu,uchar liu)
{
	P2=0XC0;
	P0=0X10;
	P2=0XE0;
	P0=tab[wu];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X20;
	P2=0XE0;
	P0=dottab[liu];
	Delay1ms(1);
}

void display4(uchar qi,uchar ba)
{
	P2=0XC0;
	P0=0X40;
	P2=0XE0;
	P0=tab[qi];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X80;
	P2=0XE0;
	P0=tab[ba];
	Delay1ms(1);

}
void allinit()
{
	P2=0X80;
	P0=0XFF;//关LED
	
	P2=0XC0;
	P0=0XFF;
	P2=0XE0;
	P0=0XFF;//关数码管
	
	P2=0XA0;
	P0=0X00;//关蜂鸣器 继电器	
}

void keyscan()
{
	if(s7==0)
	{
	 Delay1ms(5);
		if(s7==0)
		{
		P2=0XA0;
	    P0=0X10;
		//开始计费
	    wu=0,liu=0,qi=0,ba=0;
		EA=1;ET0=1;	
		}
		while(!s7);
	}
	else if(s6==0)
	{
	 Delay1ms(5);
		if(s6==0)
		{
		EA=0;ET0=0;		//停止计费	
		P2=0XA0;
	    P0=0X00;
		money=ml_10*5;// 49995
		wu=money/10000;
	    liu=money%10000/1000;
		qi=money%1000/100;
		ba=money%100/10;        //显示费用
	    ml_10=0;
		}
		while(!s6);
	}
	
}

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

void timer0() interrupt 1
{
	tt++;
	if(tt==20)
	{
    tt=0;
	ml_10=ml_10+1;//ml_10代表10ml 此时最多计算到9999 防止溢出
	wu=ml_10/1000;
	liu=ml_10%1000/100;
	qi=ml_10%100/10;
	ba=ml_10%10;
	}
	
	if(ml_10>9999)
	{
		EA=0;ET0=0;	
		P2=0XA0;
	    P0=0X00;//断开继电器 L10
		money=ml_10*5;// 49 995
		wu=money/10000;
		liu=money%10000/1000;
		qi=money%1000/100;
		ba=money%100/10;        //显示费用
		ml_10=0;
	
	}

}

void adrun()//读取AD转换结果并判断
{
	uchar num;
	num=IIC_read(0x01);//采集光敏电阻数据
	if(num<25)//  1.25/5 *100=25 小于1.25V L1亮
	{
		P2=0X80;
    P0=0XFE;		
	
	}
	else  //大于1.25V L1亮
   {
     P2=0X80;
     P0=0XFF;
   }

}

/*
  程序说明: 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;
}

uchar IIC_read(uchar add)
{
		uchar temp;
		IIC_Start();
		IIC_SendByte(0x90);//PCF8951地址
		IIC_WaitAck();
		IIC_SendByte(add);//采集AD信息的地址
		IIC_WaitAck();
		IIC_Stop();

		IIC_Start();
		IIC_SendByte(0x91);//进行读操作
		IIC_WaitAck();
		temp=IIC_RecByte();
		IIC_Stop();
		temp=0.39*temp; //0.39*255=99.45 约等于100将数据0-255转换0-100
   	return temp;
}
#ifndef _IIC_H
#define _IIC_H

#include <STC15F2K60S2.h>
#include "intrins.h"
/*将原来的somenop扩大8倍,因为官网驱动提供的驱动代码测试环境:12T, 8051, 12MHz
IAP15F2K61S2具有内部振荡器,振荡器频率可在ISP软件中调整
使用或调试驱动代码时,选手需根据设定的片内振荡器频率、所使用单片机的机器周期对代码进行调整;*/
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
#define uchar unsigned char
#define uint unsigned int
//总线引脚定义
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); 
uchar IIC_read(uchar add);

#endif

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42244181/article/details/86929769