【2020年蓝桥杯省赛程序设计题详解】

题目要求:

 

 

 

S16:定义为“加”按键,按下S16,电压参数增加0.5V;增加到5.00后,再次按下S16返回0.00V。

 

 

代码:

#include "STC15F2K60S2.H"
#include "iic.h"
#include "xmf_smg_ca.h"
#include "absacc.h"
unsigned int time = 0;             //用于计时
float  VRb2,comp ;                 //从8591读出的电压值和比较电压值
unsigned int X,Pare;            //X是对VRb2乘100,Pare是对comp乘100,方便传入数码管
unsigned char miao = 0;           //计时变量
unsigned char mode = 0;            //界面切换,为零是初始界面,为一是参数界面,为二是时间记录界面
unsigned int L1_time = 0;              //用来判断L1是否该亮,如果记录电压大于参考电压,那么将点亮L1
unsigned char flaut = 0;             //用来记录无效按键的次数

void init0()                          //定时一毫秒
{
	TMOD = 0XF0;
	TH0 = 0XD4;
	TL0 = 0XCD;
	TR0 = 1;
	
	ET0 = 1;                         //打开中断
	EA = 1;
}
void serviceinit0() interrupt 1   //中断服务函数
{
		time++;L1_time++;
		if(time == 100)
		{
			time = 0;
			miao++;                      //一秒后miao++
			if(miao == 60)
			{
				miao = 0;               //六十秒后计数自动清零
			}
		}
}

//***********************************************************
unsigned char read_pcf8591()            //读出8591中的电阻值,方便后面转换成电压值
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_Ack(0);
	IIC_Stop();
	
	return temp;
}

unsigned char read_24c02()              //读出存入EE2中的电压值
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(0x00);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_Ack(0);
	IIC_Stop();
	
	return temp;
}

void write_24c02(unsigned char date)    //将电压值写入EE2中
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(0x00);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

//****************************************************************

//************************************************************
void date_V()                              //显示电压
{
	smgbit(SMG_ti_shi[0],0);
	smgdelay(100);
	
	smgbit(SMGDot_CA[X/100],5);
	smgdelay(100);
	
	smgbit(SMG_duanma[(X%100)/10],6);
	smgdelay(100);
	
	smgbit(SMG_duanma[X%10],7);
	smgdelay(100);
	
	smgall(0xff);
	smgdelay(100);
}

void date_P()                            //显示参数,比较电压
{
	smgbit(SMG_ti_shi[1],0);
	smgdelay(100);
	
	smgbit(SMGDot_CA[Pare/100],5);
	smgdelay(100);
	
	smgbit(SMG_duanma[(Pare%100)/10],6);
	smgdelay(100);
	
	smgbit(SMG_duanma[Pare%10],7);
	smgdelay(100);
	
	smgall(0xff);
}

void date_m()                                //记录时间
{
	smgbit(SMG_ti_shi[2],0);
	smgdelay(100);
	
	
	smgbit(SMG_duanma[miao/10],6);
	smgdelay(100);
	
	smgbit(SMG_duanma[miao%10],7);
	smgdelay(100);
	
	smgall(0xff);
}

void jie_mian_qie_huan()                 //用于切换数码管界面
{
	if(mode == 0)
	{
		date_V();//显示电压
	}
	if(mode == 1)
	{
		date_P();//显示参数,比较电压
	}
	if(mode == 2)
	{
		date_m();//记录时间
	}
}
//************************************************************8
void keyscan()
{
	P35 = 0;
	P34 = 1;
	if(P33 == 0)//检测S12,并且通过按S12来切换数码管的模式,以便下面三个按键的检测
	{
		smgdelay(100);
		if(P33 == 0)
		{
			flaut = 0;
			if(mode == 0)
			{
				mode = 1;
			}
			else if(mode == 1)
			{
				mode = 2;
			}
			else if(mode == 2)
			{
				mode = 0;
			}
			while(P33 == 0);
		}
		else
		{
			flaut++;
		}
	}
	
	P35 = 0;
	P34 = 1;
	if(P32 == 0)          //检测S13
	{
		smgdelay(100);
		if(P32 == 0)
		{
			flaut = 0;
			if(mode == 2)
			{
				miao = 0;
				while(P32 == 0);
			}
		}
		else
		{
			flaut++;
		}
	}
	
	P35 =1;
	P34 =0;
	if(P33 == 0)  //检测S16
	{
		smgdelay(100);
		if(P33 == 0)
		{
			flaut = 0;
			if(mode == 1)
			{
				comp = comp +0.5;
				if(comp>5)
				{
					comp = 0.0;
				}
			}
			while(P33 == 0)
			{
			
				write_24c02((unsigned char) comp*10);
		    smgdelay(5000);
				
				jie_mian_qie_huan();
			}
		}
		else
		{
			flaut++;
		}
	}
	
	
	P35 =1;
	P34 =0;
	if(P32 == 0)                //检测S17
	{
		smgdelay(100);
		if(P32 == 0)
		{
			flaut = 0;
			if(mode == 1)
			{
				comp = comp -0.5;
				if(comp<0)
				{
					comp = 5.0;
				}
			}
			while(P32 == 0)
			{
				jie_mian_qie_huan();
			}
		}
		else
		{
			flaut++;
		}
	}
	
}

void led_contr()                        //控制灯光
{
	if(X>Pare)
		{
			
			if(L1_time >=500)
			{
				XBYTE[0X8000] = 0XFE;           //L1灯光控制
				smgdelay(100);
				L1_time = 5001;
			}
		}
		else
		{
			L1_time = 0;
			XBYTE[0X8000] = 0XFF;
		}
		
	if((miao%2) == 1)
	{
		XBYTE[0X8000] = 0XFD;              //L2灯光控制
		smgdelay(100);
	}
	else
	{
		XBYTE[0X8000] = 0XFF;
	}
	
	if(flaut >=3)
	{
		XBYTE[0X8000] = 0XFB;              //L3灯光控制
		smgdelay(100);
	}
	else
	{
		XBYTE[0X8000] = 0XFF;
	}
}
void main()
{
		close();
		init0();
	//*****************************将上次掉电后存的数据取出来
		comp = read_24c02()/10.0;
		if(!((comp>=0.0) && (comp<=5.0)))   //如果数据不在参考电压的范围里面那么让参考电压为零
		{
			comp = 0.0;
		}
		//******************************
		while(1)
		{
				VRb2 = read_pcf8591() * 5 /255.0;       //将电阻值转换成电压值
				X = VRb2*100;                   //方便显示在数码管上
				Pare = comp*100.0;
				led_contr();
				keyscan();
				jie_mian_qie_huan();	
		}
}

 IIC.H

#ifndef _IIC_H
#define _IIC_H
void Delay_IIC(unsigned char time);

void IIC_Start(void);
void IIC_Stop(void);

void IIC_Ack(unsigned char ackbit);
bit IIC_WaitAck(void);

void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
#include "STC15F2K60S2.H"
#include "intrins.h"


//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */
void Delay_IIC(unsigned char time)
{
	do{_nop_();}
    while(time--); 
}

void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	Delay_IIC(5);
	SDA = 0;        //在SCL高电平期间,SDA由高变低
	Delay_IIC(5);
	SCL = 0;	
}

void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	Delay_IIC(5);
	SDA = 1;	//在SCL高电平期间,SDA由高变低
	Delay_IIC(5);
}

void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 	
		SDA = 0;	//产生应答信号
	else 
		SDA = 1;	//产生非应答信号
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	        //第9个时钟周期
        SCL = 0;
	SDA = 1; 		//释放SDA线
	Delay_IIC(5);
}

bit IIC_WaitAck(void)
{
	SDA = 1;
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	
 
	if(SDA)    		//在SCL高电平期间,SDA为高电平,从机非应答。
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else 			//在SCL高电平期间,SDA为低电平,从机有应答。
	{ 
		SCL = 0;
		return 1;
	}	
}

void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)		//循环发送8位数据
	{   
		if(byt & 0x80) 		//数据位是高电平
		{	
			SDA = 1;
		}
		else 			//数据位是低电平
		{
			SDA = 0;
		}
 
		Delay_IIC(5);
		SCL = 1;		//SCL高电平期间,SDA的数据要保持稳定
		byt <<= 1;		//发送的数据左移,准备发送下一位
		Delay_IIC(5);		//等待SDA的数据被读取
		SCL = 0;
	}
}

unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		Delay_IIC(5);		//在SCL高电平期间,读取SDA的数据
		da <<= 1;
		if(SDA) 
			da |= 0x01;
		SCL = 0;
		Delay_IIC(5);
	}
	return da;
}

 数码管底层代码

#ifndef _XMF_SMG_BA_H
#define _XMF_SMG_BA_H

unsigned char code SMGDot_CA[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//数字0.到数字9.
unsigned char code SMG_duanma[18]=
		{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
     0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
     0xbf,0x7f};

unsigned char code SMG_ti_shi[3]={0xc1,0x8c,0xc8};//提示符U,P,N
void smgdelay(unsigned int n);
void close();
void smgbit(unsigned char dat,unsigned char pot);
void smgall(unsigned char all);

#endif
#include "absacc.h"
void smgdelay(unsigned int n)
{
	while(n--);
}

void close()        //初始化设备
{
	XBYTE[0XA000] = 0X00;
	XBYTE[0X8000] = 0Xff;
}

void smgbit(unsigned char dat,unsigned char pot)  //数码管段码
{
	XBYTE[0XE000] = 0xff;
	XBYTE[0XC000] = 0X01<<pot;
	XBYTE[0XE000] = dat;
}

void smgall(unsigned char all)  //关闭所有数码管
{
	XBYTE[0XC000] = 0XFF;
	XBYTE[0XE000] = all;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值