【蓝桥杯第十二届省赛】

文章目录[隐藏]

【蓝桥杯第十二届省赛】

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include "reg52.h"
#include "onewire.h"
#include "iic.h"


/*============================================
第十二届蓝桥杯单片机
Date:2022.2.4
Author:小殷同学
Version:1.0
=============================================*/
sfr  P4 = 0xc0;
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;

sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;

unsigned char Temperature = 25;
unsigned char Temperature_Param = 25;//温度参数设置
unsigned int voltage = 325; //电压	扩大100倍方便计算显示
unsigned char interface_mode  = 0,work_mode = 1; //界面切换 工作模式
unsigned char Temperature_start = 0,DAC_start = 0,count = 0;// 温度 DAC刷新标志  计时
unsigned char code SMG_duama[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};//数码管段码不带小数点
unsigned char code SMG_DOT[10] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//数码管段码带小数点

//------------------------------简单延时-------------------------
void Delay(unsigned int t)
{
	while(t--);
}
//-------------------------74HC138初始化-------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 0:P2 = (P2 & 0x1f) | 0x00;break;
		case 4:P2 = (P2 & 0x1f) | 0x80;break;
		case 5:P2 = (P2 & 0x1f) | 0xa0;break;
		case 6:P2 = (P2 & 0x1f) | 0xc0;break;
		case 7:P2 = (P2 & 0x1f) | 0xe0;break;
	}
}
//---------------------------系统初始化--------------------------
void Init_System(void)
{
 	Init_74HC138(4);
	P0 = 0xff;
	Init_74HC138(5);
	P0 = 0x00;
	Init_74HC138(0);
}
//--------------------------------数码管安位显示-----------------
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
 	Init_74HC138(6);
	P0 = (0x01 << pos);
	Init_74HC138(7);
	P0 = dat;
}
//------------------------------数码管显示----------------------
void SMG_Close(void)
{
 	Init_74HC138(6);
	P0 = 0xff;
	Init_74HC138(7);
	P0 = 0xff;
}
void SMG_Display_Volate(void)
{
	SMG_DisplayBit(0,SMG_duama[10]);
	Delay(200);	
	SMG_DisplayBit(1,0xff);
	Delay(200);	
	SMG_DisplayBit(2,0xff);
	Delay(200);
	SMG_DisplayBit(3,0xff);
	Delay(200);
	SMG_DisplayBit(4,0xff);
	Delay(200);
	SMG_DisplayBit(5,SMG_DOT[voltage/100]);
	Delay(200);
	SMG_DisplayBit(6,SMG_duama[voltage/10%10]);
	Delay(200);
	SMG_DisplayBit(7,SMG_duama[voltage%10]);			          
	Delay(200);	
	SMG_Close();
	Delay(200);
}
void SMG_Display_Temperature(void)
{
	SMG_DisplayBit(0,SMG_duama[12]);
	Delay(200);	
	SMG_DisplayBit(1,0xff);
	Delay(200);	
	SMG_DisplayBit(2,0xff);
	Delay(200);
	SMG_DisplayBit(3,0xff);
	Delay(200);
	SMG_DisplayBit(4,SMG_duama[Temperature*100/1000]);
	Delay(200);
	SMG_DisplayBit(5,SMG_DOT[Temperature*100/100%10]);
	Delay(200);
	SMG_DisplayBit(6,SMG_duama[Temperature*100/10%10]);
	Delay(200);
	SMG_DisplayBit(7,SMG_duama[Temperature*100/10%10]);
	Delay(200);	
	SMG_Close();
	Delay(200);
}

void SMG_Set_Temperature(void)
{
	//P 0011 0001 0X8C
	SMG_DisplayBit(0,0X8c);
	Delay(200);	
	SMG_DisplayBit(1,0xff);
	Delay(200);	
	SMG_DisplayBit(2,0xff);
	Delay(200);
	SMG_DisplayBit(3,0xff);
	Delay(200);
	SMG_DisplayBit(4,0xff);
	Delay(200);
	SMG_DisplayBit(5,0xff);
	Delay(200);
	SMG_DisplayBit(6,SMG_duama[Temperature_Param/10]);
	Delay(200);
	SMG_DisplayBit(7,SMG_duama[Temperature_Param%10]);
	Delay(200);	
	SMG_Close();
	Delay(200);
}
//--------------------------------DS18B20------------------------
void Read_Temperature(void)
{
 	unsigned char LSB,MSB;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay(500);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);

	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();

	Temperature = (MSB << 8) | LSB;
	if(Temperature & 0xf800 == 0x0000)
	{
	 	Temperature	= Temperature >> 4;
		Temperature *= 10;
		Temperature = Temperature + (LSB & 0x0f)*0.625;
	}
}
//---------------------------------PCF8591----------------------
void Read_Rd2_DAC(float dat)
{
 	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//----------------------------------矩阵键盘--------------------
void Matrix_Key(void)
{
 	H3 = 0;
	H1 = H2 = H4 = 1;
	L1 = L2 = L3 = L4 = 1;
	//s9 在参数界面下按下S9按键,温度参数加1
	if(L3 == 0)
	{
	 	Delay(20);
		if(L3 == 0)
		{
			while(L3 == 0)
			{
					SMG_Set_Temperature(); //温度设置界面	
			}
			if(interface_mode == 1)	 //在温度界面下进行温度加一
			{
			 	Temperature_Param++;
			}
		}
	}
	//S5 定义为“模式”切换按键。 
	/*
	 模式1:DAC输出电压与温度相关。 
	 通过DS18B20采集到的实时温度小于温度参数时,DAC输出0V,
	 否则,DAC输出5V。 模式2:DAC按照图7给出的关系输出电压。 
	*/
	if(L4 == 0)
	{
		Delay(20);
		if(L4 == 0)
		{
				while(L4 == 0)
				{
					SMG_Display_Volate();
				}
				if(work_mode == 1)
				{
					if(Temperature < Temperature_Param)
					{
						Read_Rd2_DAC(0);	//实时温度小于温度参数时,DAC输出0V,
						voltage = 0;
					}
					else
					{
					 	Read_Rd2_DAC(255); //DAC输出5V
						voltage = 500; //5v 扩大100 倍 方便计算
					}
					work_mode = 2;
				}
				else if(work_mode == 2)
				{
				 	work_mode = 0;
					if(Temperature <= 20)
					{
						 //5/255 = 1/x x->255/5  
						 Read_Rd2_DAC(51);
						 voltage = 100; //1v
					}
					else if(Temperature > 40)
					{
					//5/255 = 4/x x-> 204
						Read_Rd2_DAC(204);
						voltage = 400; //4v
					}
					//关系式输出
					else if(Temperature > 20 && Temperature < 40)
					{
						 Read_Rd2_DAC((0.15*Temperature-2)*51.0);
						 voltage = (0.15*Temperature-2)*100; //扩大100倍方便计算
					}
					work_mode = 1; 
				}
		}	
	}
	H4 = 0;
	H1 = H2 = H3 = 1;
	L1 = L2 = L3 = L4 = 1;
	//s8 定义为“减”按键 参数界面下按下S8按键,温度参数减1
	if(L3 == 0)
	{
	 	Delay(20);
		if(L3 == 0)
		{
			while(L3 == 0)
			{
				SMG_Set_Temperature(); //温度设置界面	
			}
			if(interface_mode == 1)		 //在温度界面下进行温度减一
			{
			 	Temperature_Param--;
			}
		}	
	}
	//S4 定义为“界面”按键,按下S4按键,切换温度显示界面、参数设置界面和DAC输出界面,
	if(L4 == 0)
	{
	 	Delay(20);
		if(L4 == 0)
		{
			 while(L4 == 0)
			 {
						if(interface_mode == 0)
						{
						 	interface_mode = 1;
							SMG_Display_Temperature(); //温度显示界面				
						}
						else if(interface_mode == 1)
						{
						 	interface_mode = 2;
							SMG_Set_Temperature(); //温度设置界面						
						}
						else if(interface_mode == 2)
						{
						 	interface_mode = 0;
							SMG_Display_Volate(); //电压显示界面			
						}
			 }
		}
	}
}

//--------------------------------LED功能处理-------------------
void Led_Running(void)
{
//当前处于模式1状态,指示灯L1点亮,否则熄灭
 Init_74HC138(4);
 if(work_mode == 1)
 {
		P0 = 0x7f; //0111 1111
 }
 switch(interface_mode)
 {
		case 0:P0 = 0xfd;break;//当前处于温度显示界面,指示灯L2点亮,否则熄灭
		case 1:P0 = 0xfb;break;//当前处于参数设置界面,指示灯L3点亮,否则熄灭。
		case 2:P0 = 0xf7;break; //当前处于DAC输出界面,指示灯L4点亮,否则熄灭
 }
 /*
 if(interface_mode == 0)
 {
	 P0 = 0xfd;  //1011 1111
 }
 //当前处于参数设置界面,指示灯L3点亮,否则熄灭。 
 if(interface_mode == 1)
 {
	 P0  = 0xfb; //1101 1111
 }
 //当前处于DAC输出界面,指示灯L4点亮,否则熄灭
 if(interface_mode == 2)
 {
	 P0 = 0xf7; //1110 1111
 }
 */
 
}
//--------------------------------定时器初始化-------------------
void Init_Timer(void)
{
 	TMOD = 0x01;
	TH0  = (65535-50000)/256; //50MS
	TL0  = (65535-50000)%256;
	ET0  = 1;
	TR0  = 1;
	EA   = 1;
}
//----------------------------主函数-----------------------------
void main(void)
{
	Init_System();
	Init_Timer();
 	while(1)
	{
	  	Matrix_Key();	
			Read_Temperature();																		                                  
		 switch(interface_mode)
		 {
			case 0:SMG_Display_Temperature();break;
			case 1:SMG_Set_Temperature();break;
			case 2:SMG_Display_Volate(); break;
		 }
		 Led_Running();
	}
}
//----------------------------------中断服务函数----------------
//温度数据刷新时间:≤1秒。 
//DAC输出电压刷新时间:≤0.5秒
void Server_Timer0() interrupt 1
{
 	TH0 = (65535-50000)/256;
	TL0 = (65535-50000)%256;
	count++;
	if(count == 10) //0.5s
	{
	 	if(DAC_start == 0 )//DAC刷新标志
		{
		 	DAC_start = 1;
		}
		else if(DAC_start == 1)
		{
		 	DAC_start = 0;
		}
	}
	if(count == 20)// 1s
	{
	 	if(Temperature_start == 0) //温度刷新标志
		{
		 	Temperature_start = 1;
		}
		else if(Temperature_start == 1)
		{
		 	Temperature_start = 0;
		}
		count = 0;
	}

}

版权声明:本文为CSDN博主「奋斗的小殷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boybs/article/details/122790306

生成海报
点赞 0

奋斗的小殷

我还没有学会写个人说明!

暂无评论

相关推荐

蓝桥杯单片机第十二届省赛

如果有用请点赞,还会继续更新的 题目: 思路: 还是千篇一律的定时器中断,简直就是yyds。这届和第十一届的题可以说是有很多相似的地方,我感觉难点可能还是LED的那个部分