14届蓝桥杯省赛

#include <STC15F2K60S2.H>
#include "Init.h"
#include <Key.H>
#include <Seg.H>
#include <Led.H>
#include "onewire.h"
#include "ds1302.h" 
#include "iic.h"

//参数变量
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
unsigned char Key_Slow_Down;							//按键减速变量
unsigned int Seg_Slow_Down;								//数码管减速变量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};   //数码管位变量
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};			//数码管小数点显示变量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};				//led位选
unsigned char Seg_Pos;									//数码管扫描变量
//界面显示
unsigned char Seg_Slow_Mode;   		//0-时间显示界面,1-回显显示界面,2-参数设置界面
unsigned char Read_Mode;	  		//0-温度回显,1-湿度回显,2-时间回显
unsigned char ucRtc[3] = {13,3,5};  //时间显示

//温度参数
unsigned char Temp_Ctrol = 30;		//温度参数变量

unsigned char Temp_Mix = 0;   		//最高温度
unsigned char Temp_Ave = 0;   		//平均温度
//湿度参数
unsigned char Humidity_Max = 0;     //最大湿度
unsigned char Humidity_Ave = 0; 	//平均湿度

unsigned char trigger_count = 0;	//触发次数
unsigned char trigger_time[3];  	//触发时间
unsigned int freq;  				//频率

unsigned int Temp_temperature;  	//温湿度温度
unsigned int Temp_humitity;     	//湿度数据

//时间参数
unsigned int Time_1s;
unsigned int Time_2s;
unsigned int Time_3s;
unsigned char Time_100ms;
//标志位
unsigned int old_light_value;//上一次光强参数
bit trigger_flag = 1;		//触发采集标志
bit long_press_flag;	//长按标志
bit wring_flag;			//温度超过参数报警
bit Led_light_flag; 	//Led闪烁
bit error_humidity_flag;//湿度是否有效,无效为1
bit dada_up;			//温湿度都升高
//频率转化为湿度
float Read_humitity()
{
	float Humitity_Value;
	if(freq < 200 || freq > 2000)
		return 0;
	Humitity_Value = (freq - 200) * 2 / 45 + 10;
	return Humitity_Value;
}
//清除数据
void Clean_Data()
{
	unsigned char i;
	Temp_Mix = 0;
	Temp_Ave = 0;
	Humidity_Max = 0;
	Humidity_Ave = 0;
	trigger_count = 0;
	for(i = 0;i < 3;i++)
		trigger_time[i] = 0;
}
//数码管复位
void Seg_Reset()
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{
		Seg_Buf[i] = 10;
		Seg_Point[i] = 0;
	}
}
void Key_Proc()
{
	if(Key_Slow_Down) return;
	Key_Slow_Down = 1;
	Key_Val = Key_Read();
	Key_Down = Key_Val & (Key_Val ^ Key_Old);
	Key_Up = ~Key_Val & (Key_Val ^ Key_Old);
	Key_Old = Key_Val;
	
	if(Key_Down == 4)//时间界面
	{
		Seg_Reset();
		Seg_Slow_Mode = (++Seg_Slow_Mode) % 3;
		Read_Mode = 0;
	}
	if(Key_Down == 5 && Seg_Slow_Mode == 1)//回显界面 且按下P5
	{
		Seg_Reset();
		Read_Mode = (++Read_Mode) % 3;
	}
	if(Seg_Slow_Mode == 2)//参数界面
		if(Key_Down == 8)//参数界面下 按P8增加温度参数
		{
			if(++Temp_Ctrol > 99)
				Temp_Ctrol = 99;
			else
				Temp_Ctrol++;
		}
		else if(Key_Down == 9)//参数界面下 按P9减少温度参数
		{
			if(--Temp_Ctrol < 0)
				Temp_Ctrol = 0;
			else
				Temp_Ctrol--;
		}
	if(Seg_Slow_Mode == 1 && Read_Mode == 2)//时间回显界面下 
	{
		if(Key_Down == 9)//判断P9是否按下
			long_press_flag = 1;//长按标志
		if(Key_Up == 9)//判断P9是否松开
		{
			if(Time_2s >= 2000)//超过2s清除所有数据
				Clean_Data();
			long_press_flag = 0;
		}
	}
}

void Seg_Proc()
{
	unsigned int old_Temp_humitity;     //上一次湿度数据
	unsigned int old_Temp_temperature;  //上一次温度温度
	unsigned int Temp_light;			//此次光照参数

	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	Temp_light = Ad_Read(0x01);//读取光敏电阻
	
	//避免重复触发 光->暗 且
	if((old_light_value > 50) && (Temp_light < 50) && (trigger_flag == 0))//判断光是否从亮到暗并且没有触发采集标志
	{
		trigger_flag = 1;//触发采集标志
		if(++trigger_count == 100)
			trigger_count = 99;//采集次数增加
	}
	//触发采集标志且达到3s,返回回显界面
	else if(trigger_flag == 1 && Time_3s >= 3000)
		trigger_flag = 0;
	old_light_value = Temp_light;//当前光亮赋给上一次光亮,以便下次对比光亮
	
	if(trigger_flag == 1)//当触发采集时
	{			
		Temp_temperature = rd_temperature() * 10;//读取温度
		Temp_humitity = Read_humitity() * 10;//读取湿度
		Seg_Buf[0] = 16;
		Seg_Point[6] = 0;
		Seg_Buf[1] = Seg_Buf[2] = 10;
		Seg_Buf[3] = Temp_temperature / 100 % 10;
		Seg_Buf[4] = Temp_temperature / 10 % 10;
		Seg_Buf[5] = 11;
		//无效数据
		if(Temp_humitity == 0)
		{
			trigger_count--;
			error_humidity_flag = 1;
			Seg_Buf[6] = 17;
			Seg_Buf[7] = 17;
		}
		//有效数据
		else
		{
			error_humidity_flag = 0;
			wring_flag = (Temp_temperature > Temp_Ctrol * 10);
			if((trigger_count >= 2) && (Temp_temperature > old_Temp_temperature) && (Temp_humitity > old_Temp_humitity))
				dada_up = 1;
			else
				dada_up = 0;
			old_Temp_temperature = Temp_temperature;
			old_Temp_humitity = Temp_humitity;
			Seg_Buf[6] = Temp_humitity / 100 % 10;
			Seg_Buf[7] = Temp_humitity / 10 % 10;
			if(Temp_Mix < Temp_temperature)
				Temp_Mix = Temp_temperature;
			if(Humidity_Max < Temp_humitity)
				Humidity_Max = Temp_humitity;
			Temp_Ave = (Temp_Ave * (trigger_count - 1) + Temp_temperature) / trigger_count;
			Humidity_Ave = (Humidity_Ave * (trigger_count - 1) + Temp_humitity) / trigger_count;
		}
	}
	else
	{
		switch(Seg_Slow_Mode)
		{
			case 0://时间
				Read_Rtc(ucRtc);
				Seg_Buf[0] = ucRtc[0] / 10 % 10;
				Seg_Buf[1] = ucRtc[0] % 10;
				Seg_Buf[2] = Seg_Buf[5] = 11;
				Seg_Buf[3] = ucRtc[1] / 10 % 10;
				Seg_Buf[4] = ucRtc[1] % 10;
				Seg_Buf[6] = ucRtc[2] / 10 % 10;
				Seg_Buf[7] = ucRtc[2] % 10;
				break;
			case 1://回显
				switch(Read_Mode)
				{
					case 0://温度回显
						Seg_Buf[0] = 12;
						Seg_Buf[1] = 10;
						if(trigger_count != 0)
						{
							Seg_Buf[2] = Temp_Mix / 10 % 10;
							Seg_Buf[3] = Temp_Mix % 10;
							Seg_Buf[4] = 11;
							Seg_Buf[5] = Temp_Ave / 100 % 10;
							Seg_Buf[6] = Temp_Ave / 10 % 10;
							Seg_Buf[7] = Temp_Ave * 10 % 10;
							Seg_Point[6] = 1;
						}
						break;
					case 1://湿度回显
						Seg_Buf[0] = 13;
						Seg_Buf[1] = 10;
						if(trigger_count != 0)
						{
							Seg_Buf[2] = Humidity_Max / 10 % 10;
							Seg_Buf[3] = Humidity_Max % 10;
							Seg_Buf[4] = 11;
							Seg_Buf[5] = Humidity_Ave / 100 % 10;
							Seg_Buf[6] = Humidity_Ave / 10 % 10;
							Seg_Buf[7] = Humidity_Ave % 10;
							Seg_Point[6] = 1;
						}
						break;
					case 2://时间回显
						Seg_Buf[0] = 14;
						Seg_Buf[1] = trigger_count / 10 % 10;
						Seg_Buf[2] = trigger_count % 10;
						if(trigger_count != 0)
						{
							Seg_Buf[3] = trigger_time[0] / 10 % 10;
							Seg_Buf[4] = trigger_time[0] % 10;
							Seg_Buf[5] = 11;
							Seg_Buf[6] = trigger_time[1] / 10 % 10;
							Seg_Buf[7] = trigger_time[1] % 10;
							Seg_Point[6] = 0;
						}
						break;
				}
				break;
			case 2://参数
				Seg_Buf[0] = 15;
				Seg_Buf[1] = Seg_Buf[2] = Seg_Buf[3] = Seg_Buf[4] = Seg_Buf[5] = 10;
				Seg_Buf[6] = Temp_Ctrol / 10 % 10;
				Seg_Buf[7] = Temp_Ctrol % 10;
				break; 
		}
	}
}
void Led_Proc()
{
	//界面指示灯
	ucLed[0] = (Seg_Slow_Mode == 0);
	ucLed[1] = (Seg_Slow_Mode == 1);
	ucLed[2] = (Seg_Slow_Mode == 2);
	//报警指示灯
	ucLed[3] = (wring_flag) ? Led_light_flag : 0;
	ucLed[4] = error_humidity_flag;
	ucLed[5] = dada_up;
}
//定时器0中断初始化函数
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x05; // 设置定时器模式
	TL0 = 0;		//设置定时初值
	TH0 = 0;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
//定时器1中断初始化函数
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0xBF;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
	EA = 1;
}
//定时器1服务中断函数
void Timer1Server() interrupt 3
{
	if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
	if(++Seg_Slow_Down == 200) Seg_Slow_Down = 0;
	if(++Seg_Pos == 8) Seg_Pos = 0;
	if(++Time_1s == 1000)
	{
		Time_1s = 0;
        freq = TH0 << 8 | TL0;
        TH0 = 0;
        TL0 = 0;
	}
	if(trigger_flag)
	{
		if(++Time_3s >= 3000)
			Time_3s = 3001;
	}
	else
		Time_3s = 0;
	if(long_press_flag)
	{
		if(++Time_2s >= 2000)
			Time_2s = 2001;
	}
	else
		Time_2s = 0;
	if(++Time_100ms == 100)
	{
		Time_100ms = 0;
		Led_light_flag ^= 1;
	}
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
void Delay750ms()		//@12.000MHz
{
	unsigned char i, j, k;
	i = 35;
	j = 51;
	k = 182;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void main()
{
	System_Init();
	Timer0Init();
	Timer1Init();
	Set_Rtc(ucRtc);
	Delay750ms();
	rd_temperature();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

B站西风大模板,自己写的会直接进入温湿度模式,不能在三个界面之间转换。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值