[蓝桥杯单片机] -- 2022第十三届蓝桥杯单片机组省赛赛题

[蓝桥杯单片机] -- 2022第十三届蓝桥杯单片机组省赛赛题,第1张

文章目录
  • Question
  • Code

Question



Code

稀烂的代码

  • Main.c
#include "stc15f2k60s2.h"
#include "ds1302.h"
#include "onewire.h"

#define uchar unsigned char
#define uint unsigned int
	
/*-----------------------------------------------------------------------------*/
uint G_Time = 0;
bit TimeFlag_10ms = 0;
bit TimeFlag_20ms = 0;
bit TimeFlag_200ms = 0;
bit TimeFlag_50ms = 0;
//						0		1	2	3	4	5		6	7	8	9		10	11	12:-
code uchar DispTab[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xC1};//+13  U:22
uchar DispBuf[8] = {10,10,10,10,10,10,10,10};

uchar KeyValue = 0xFF;
bit keyfree = 0;
uchar TempKey = 0xFF;//临时键值

uchar Interface = 0;//0: 温度显示 1: 时间显示 2: 参数设置
bit TimeDisplayMode = 0;
bit Mode = 0;//工作模式 0:温控 1:时间控制

uchar TemperaturePre  = 23;


bit GlobalRelayONBit = 0;

/*-----------------------------------------------------------------------------*/
void ExternalDevice(uchar extdev);
void LEDCtrl(uchar ledctrl);
void Timer1Init(void);
void SegmentDisplay(void);
void KeyScan(void);
void KeyServive(void);
void InterfaceUpdate(void);
void RelayCtrl(void);
void LEDIndicator(void);

/*-----------------------------------------------------------------------------*/
void main(void)
{
	ExternalDevice(0x00);
	LEDCtrl(0x00);
	Timer1Init();
	SetRTC();
	rd_temperature();
	
	while(1)
	{
		if(TimeFlag_10ms)
		{
			TimeFlag_10ms = 0;
			
			KeyScan();
			KeyServive();
			LEDIndicator();
			
			if(TimeFlag_50ms)
			{
				TimeFlag_50ms = 0;
				
				RelayCtrl();
				
				if(TimeFlag_200ms)
				{
					TimeFlag_200ms = 0;
					
					ReadRTC();
					rd_temperature();
					rd_temperature();
					InterfaceUpdate();
				}
			}
		}
	}
}


/*-----------------------------------------------------------------------------*/
void ExternalDevice(uchar extdev)
{
	P2 = (P2&0x1F)|0xA0;
	P0 = extdev;
	P2 &= 0x1F;
}

void LEDCtrl(uchar ledctrl)
{
	P2 = (P2&0x1F)|0x80;
	P0 = ~ledctrl;
	P2 &= 0x1F;
}

void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初值
	TH1 = 0xD1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	
	ET1 = 1;
	EA = 1;
}

void Timer1Sr(void) interrupt 3
{
	G_Time++;
	if(G_Time%10==0)
	{
		TimeFlag_10ms = 1;
		
		if(G_Time%50==0)
		{
			TimeFlag_50ms = 1;
			
		}
		
		if(G_Time%20==0)
		{
			TimeFlag_20ms = 1;
			
			if(G_Time%200==0)
			{
				TimeFlag_200ms = 1;
			}
		}
	}
	
	SegmentDisplay();
}

void SegmentDisplay(void)
{
	static uchar dispcom;
	
	P0 = 0xFF;
	P2 = (P2&0x1F)|0xE0;
	P0 = 0xFF;
	P2 &= 0x1F;
	
	P2 = (P2&0x1F)|0xC0;
	P0 = 0x01<<dispcom;
	P2 &= 0x1F;
	
	P0 = 0xFF;
	P2 = (P2&0x1F)|0xE0;
	P0 = DispTab[DispBuf[dispcom]];
	P2 &= 0x1F;
	
	if(dispcom>7)dispcom = 0;
	else dispcom++;
}

void KeyScan(void)
{
	static uchar S1=0xFF,S2=0xFF;
	static uchar keypress = 0;
	uchar temp = 0xFF;
	
	P3 = 0x0F;P42 = 0;P44 = 0;
	temp = (P3&0x0F);
	
	if(temp!=0x0F)keypress++;
	else keypress = 0;
	
	if(keyfree==0&&keypress==5)
	{
		keyfree = 1;
		keypress =  0;
		
		S1 = temp;
		
		P3 = 0xF0;P42 = 1;P44 = 1;
		temp = (P3&0xF0);
		
		if(P42==0)S2 = 0xB0;
		else if(P44==0)S2 = 0x70;
		else S2 = (temp&0xF0);
		
		switch(S1|S2)
		{
			case 0x77:TempKey = 4;break;
			case 0x7B:TempKey = 5;break;
			case 0x7D:TempKey = 6;break;
			case 0x7E:TempKey = 7;break;
			
			case 0xB7:TempKey = 8;break;
			case 0xBB:TempKey = 9;break;
			case 0xBD:TempKey = 10;break;
			case 0xBE:TempKey = 11;break;
			
			case 0xD7:TempKey = 12;break;
			case 0xDB:TempKey = 13;break;
			case 0xDD:TempKey = 14;break;
			case 0xDE:TempKey = 15;break;
			
			case 0xE7:TempKey = 16;break;
			case 0xEB:TempKey = 17;break;
			case 0xED:TempKey = 18;break;
			case 0xEE:TempKey = 19;break;
		}
	}
	
	if(temp==0x0F&&keyfree==1)
	{
		keyfree = 0;
		KeyValue = TempKey;
	}
	else KeyValue = 0xFF;
}



void KeyServive(void)
{
	if(KeyValue!=0xFF)
	{
		switch(KeyValue)
		{
			case 12:
			{
				if(Interface<2)Interface++;
				else Interface = 0;
			}break;
			
			case 13:
			{
				Mode = ~Mode;
				ExternalDevice(0x00);				
			}
			break;
			
			case 16:
			{
				if(Interface==2)
				{
					if(TemperaturePre<99)TemperaturePre++;
					else TemperaturePre = 99;
				}
			}break;
			
			case 17:
			{
				if(Interface==2)
				{
					if(TemperaturePre>10)TemperaturePre--;
					else TemperaturePre = 10;
				}
			}break;
		}
	}
	if(Interface==1)
	{
		if(TempKey==17&&keyfree)TimeDisplayMode = 1;
		else TimeDisplayMode = 0;
	}
}


void InterfaceUpdate(void)
{
	switch(Interface)
	{
		case 0:
		{
			DispBuf[0] = 22;
			DispBuf[1] = 1;
			DispBuf[2] = 10;
			DispBuf[3] = 10;
			DispBuf[4] = 10;
			DispBuf[5] = TempValue/1000%10;
			DispBuf[6] = TempValue/100%10 + 12;
			DispBuf[7] = TempValue/10%10;
		}break;
		
		case 1:
		{
			DispBuf[0] = 22;
			DispBuf[1] = 2;
			DispBuf[2] = 10;
			
			if(TimeDisplayMode)
			{
				DispBuf[3] = ReadRTC_Data[1]/16;
				DispBuf[4] = ReadRTC_Data[1]%16;
				DispBuf[5] = 11;
				DispBuf[6] = ReadRTC_Data[2]/16;
				DispBuf[7] = ReadRTC_Data[2]%16;
			}
			else 
			{
				DispBuf[3] = ReadRTC_Data[0]/16;
				DispBuf[4] = ReadRTC_Data[0]%16;
				DispBuf[5] = 11;
				DispBuf[6] = ReadRTC_Data[1]/16;
				DispBuf[7] = ReadRTC_Data[1]%16;
			}
		}break;
		
		case 2:
		{
			DispBuf[0] = 22;
			DispBuf[1] = 3;
			DispBuf[2] = 10;
			DispBuf[3] = 10;
			DispBuf[4] = 10;
			DispBuf[5] = 10;
			DispBuf[6] = TemperaturePre/10;
			DispBuf[7] = TemperaturePre%10;
		}break;
	}
}


void RelayCtrl(void)
{
	static bit relay_on = 0;
	
	switch((uchar)Mode)
	{
		case 0:
		{
			relay_on = 0;
			if(TempValue/10>TemperaturePre*10)
			{
				GlobalRelayONBit = 1;
				ExternalDevice(0x10);
			}
			else 
			{
				GlobalRelayONBit = 0;
				ExternalDevice(0x00);
			}
		}break;
		
		case 1:
		{
			if(ReadRTC_Data[1]==0x00&&ReadRTC_Data[2]==0x00)relay_on = 1;
			if(relay_on&&ReadRTC_Data[2]>=5)relay_on = 0;
			
			if(relay_on)
			{
				GlobalRelayONBit = 1;
				ExternalDevice(0x10);
			}
			else 
			{
				GlobalRelayONBit = 0;
				ExternalDevice(0x00);
			}
		}break;
	}
	
}

void LEDIndicator(void)
{
	uchar ledctrl = 0x00;
	static bit L1_ON = 0;
	
	if(ReadRTC_Data[1]==0&&ReadRTC_Data[2]==0)L1_ON = 1;
	if(L1_ON&&ReadRTC_Data[2]>=5)L1_ON = 0;
	if(L1_ON)ledctrl |= 0x01;
	else ledctrl &= 0xFE;
	
	if(Mode==0)ledctrl |= 0x02;
	else ledctrl &= 0xFD;
	
	if(GlobalRelayONBit)
	{
		if(G_Time%200==100)ledctrl |= 0x04;
		else if(G_Time%200==0)ledctrl &= 0xFB;
	}
	
	LEDCtrl(ledctrl);
}

  • onewire.c
#include "onewire.h"

unsigned int TempValue = 0;
bit TempSymbol = 0;
unsigned int LastTemp = 0;


//单总线内部延时函数
void Delay_OneWire(unsigned int t) 

//单总线写 *** 作
void Write_DS18B20(unsigned char dat)

//单总线读 *** 作
unsigned char Read_DS18B20(void)

//DS18B20初始化
bit init_ds18b20(void)


void rd_temperature(void)
{
	static unsigned char FirstTrans = 0;
	unsigned int Temp_T;
	float temp = 0;
	unsigned char T_L,T_H;
	
	if(FirstTrans>=5)LastTemp = TempValue;
	
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(20);
	
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);
	
	T_L = Read_DS18B20();
	T_H = Read_DS18B20();
	
	Temp_T = T_H;
	Temp_T <<= 8;
	Temp_T += T_L;
	
	if(T_H&0x80)
	{
		TempSymbol = 1;
		Temp_T = ~Temp_T + 1;
	}
	else 
	{
		TempSymbol = 0;
	}
	
	temp = Temp_T*0.0625;
	if(FirstTrans<6)
	{
		FirstTrans++;
		TempValue = temp*100+0.5;
	}
	else if((LastTemp-TempValue)>1000||(TempValue-LastTemp)>1000)TempValue = LastTemp;
	else TempValue = temp*100+0.5;
}

参考思路,其余代码自行补充

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/584752.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存