第十四届蓝桥杯电子类单片机决赛程序代码

/*头文件声明区域*/
#include <STC15F2K60S2.H>
#include "ultrasonic.h"
#include "pcf8591.h"
#include "ds18b20.h"
#include "onewire.h"
#include "Init.h"
#include "Seg.h"
#include "Key.h"
#include "Led.h"
#include "iic.h"

/*↓全局变量声明区域↓*/
unsigned char Key_Val,Key_Down,Key_Old;//键盘获取辅助变量
unsigned char Key_Slow_Down;//键盘减速专用变量
unsigned int Seg_Slow_Down;//数码管减速专用变量
unsigned char Led_Slow_Down;//Led减速专用变量
idata unsigned char Seg_Buf[]={16,16,16,16,16,16,16,16};//数码管内容寄存器
unsigned char Seg_Point[8];//数码管小数点状态寄存器
unsigned char Seg_Pos;//数码管指针
unsigned char Seg_Disp_Mode;//数码管显示模式 0-测距界面 1-参数界面 2-工厂界面
unsigned char Inner_Mode;//子模式
unsigned char ucLed[8];//Led状态寄存器
bit Relay_Flag;//继电器启动标志位
/*↓测距界面↓*/
float temperature;//获取温度
int Distance;//获取距离
/*↓参数界面↓*/
idata int Distance_Index=40;//距离参数
idata int Temperature_Index=30;//温度参数
/*↓工厂界面↓*/
idata int Distance_Correct=0;//校准值
idata int Speed=340;//速度值
idata unsigned char Voltage_Low=10;//电压下限值
int Distance_Temp;//辅助值
/*↓距离数据记录↓*/
xdata int Distance_Count[60];//连续记录60个数据,每0.1s记录一次
idata unsigned char Count_Pos;//记录数据指针
bit Start_Count;//记录数据标志位
bit Count_Flag;//记录标志位
/*↓DAC数据输出↓*/
bit Start_Voltage_Output;//电压输出标志
unsigned char Voltage_Out;//电压输出量
/*↓重置设置↓*/
bit Recovery_Flag;//重置标志位
unsigned int Recovery_Count;//长按操作计时


/*按键处理函数*/
void Key_Proc()
{
	if(Key_Slow_Down||Start_Count)return;
	Key_Slow_Down=1;
	Key_Val=Key_Read();
	Key_Down=Key_Val&(Key_Val^Key_Old);
	Key_Old=Key_Val;
	/*↓长按检测↓*/
	Recovery_Flag=0;
	if(Key_Old==89)
		Recovery_Flag=1;
	switch(Key_Down)
	{
		case 4:
			if(++Seg_Disp_Mode==3)Seg_Disp_Mode=0;
		/*↓按下后处理↓*/
			Inner_Mode=0;
			if(Seg_Disp_Mode==1)
			{
				ucLed[0]=0;
				ucLed[1]=0;
				ucLed[2]=0;
				ucLed[3]=0;
				ucLed[4]=0;
				ucLed[5]=0;
				ucLed[6]=0;
			}
			if(Seg_Disp_Mode==2)ucLed[7]=0;
			if(Seg_Disp_Mode==0)ucLed[0]=0;
		break;
		case 5:
			if(Seg_Disp_Mode==2)
			{
				if(++Inner_Mode==3)Inner_Mode=0;
			}
			else
				Inner_Mode^=1;
		break;
	}
	/*S8,S9分场景处理区域*/
	switch(Seg_Disp_Mode)
	{
		/*****************↓测距界面↓******************/
		case 0:
			if(Key_Down==8)//记录
			{
				Start_Count=1;//开始记录
				Count_Pos=0;	//指针清零
				Count_Flag=1;	//是否记录标志位
			}
			if(Key_Down==9)//DAC输出
			{
				if(Count_Flag)//判断是否记录过数据
					Start_Voltage_Output=1;//开始输出记录数据
				Count_Pos=0;//指针清零
			}
		break;
		/*******************************************/
		/****************↓参数界面↓*******************/
		case 1:
			if(Inner_Mode==0)
			{
				if(Key_Down==8)//距离参数+
				{
					if(Distance_Index!=90)Distance_Index+=10;
				}
				if(Key_Down==9)//距离参数-
				{
					if(Distance_Index!=10)Distance_Index-=10;
				}
			}//距离参数调整
			else
			{
				if(Key_Down==8)//温度参数+
				{
					if(Temperature_Index!=80)Temperature_Index++;
				}
				if(Key_Down==9)//温度参数-
				{
					if(Temperature_Index!=0)Temperature_Index--;
				}
			}//温度参数调整
		break;
		/*******************************************/
		/*******************************************/
		case 2:
			if(Inner_Mode==0)
			{
				if(Key_Down==8)//校准值+
				{
					if(Distance_Correct!=90)
						Distance_Correct+=5;
				}
				if(Key_Down==9)//校准值-
				{
					if(Distance_Correct!=-90)
						Distance_Correct-=5;
				}
			}
			else if(Inner_Mode==1)
			{
				if(Key_Down==8)//速度+
				{
					if(Speed!=9990)
						Speed+=10;
				}
				if(Key_Down==9)//速度-
				{
					if(Speed!=10)
						Speed-=10;
				}
			}
			else
			{
				if(Key_Down==8)//电压下限+
				{
					if(Voltage_Low!=20)
						Voltage_Low++;
				}
				if(Key_Down==9)//电压下限-
				{
					if(Voltage_Low!=1)
						Voltage_Low--;
				}
			}
		break;
		/*******************************************/
	}
}



/*数据处理函数*/
void Seg_Proc()
{
	if(Seg_Slow_Down)return;
	Seg_Slow_Down=1;//无严格时序要求,不更改
	Convert_T();//温度转化
	temperature=Read_T();//温度获取
//	/*******************/
//	Distance=Read_Distance();
//	/*测量距离二次处理*/
//	Distance=Distance*(Speed/340.0);
//	Distance=Distance+Distance_Correct;
//	/******************/
//	if(Start_Count)
//	{
//		Distance_Count[Count_Pos]=Distance;
//		if(++Count_Pos==60)
//			Start_Count=0;
//	}
	
	/*数码管显示区域*/
	switch(Seg_Disp_Mode)
	{
		case 0://测距模式
			Seg_Point[6]=0;
			Seg_Buf[0]=(int)temperature/10;
			Seg_Buf[1]=(int)temperature%10;
			Seg_Buf[2]=(int)(temperature*10)%10;//温度显示
			Seg_Buf[3]=17;
			Seg_Point[1]=1;
			if(Inner_Mode)
			{
				Seg_Buf[4]=Distance>=1000?Distance/1000%10:16;
				Seg_Buf[5]=Distance/100%10;
				Seg_Point[5]=1;
				Seg_Buf[6]=Distance/10%10;
				Seg_Buf[7]=Distance%10;//距离显示(cm)
			}
			else
			{
				Seg_Buf[4]=Distance>=1000?Distance/1000%10:16;
				Seg_Buf[5]=Distance>=100?Distance/100%10:16;
				Seg_Point[5]=0;
				Seg_Buf[6]=Distance>=10?Distance/10%10:16;
				Seg_Buf[7]=Distance%10;//距离显示(m)
			}
		break;
		case 1://参数模式
			Seg_Point[5]=0;
			Seg_Buf[0]=18;
			Seg_Buf[1]=Inner_Mode+1;
			Seg_Point[1]=0;
			Seg_Buf[2]=16;
			Seg_Buf[3]=16;
			Seg_Buf[4]=16;
			Seg_Buf[5]=16;
			if(Inner_Mode)
			{
				Seg_Buf[6]=Temperature_Index/10;
				Seg_Buf[7]=Temperature_Index%10;//温度参数
			}
			else
			{
				Seg_Buf[6]=Distance_Index/10;
				Seg_Buf[7]=Distance_Index%10;//距离参数
			}
			
		break;
		case 2://工厂模式
			Seg_Buf[0]=15;
			Seg_Buf[1]=Inner_Mode+1;
//			Seg_Buf[2]=16;
//			Seg_Buf[3]=16;
			switch(Inner_Mode)
			{
				case 0:
					Seg_Point[6]=0;
					if(Distance_Correct>=0)
					{
						Seg_Buf[4]=16;
						Seg_Buf[5]=16;
						Seg_Buf[6]=Distance_Correct>=10?Distance_Correct/10:16;
						Seg_Buf[7]=Distance_Correct%10;//校准值
					}
					else
					{
						Distance_Temp=-Distance_Correct;
						Seg_Buf[4]=16;
						Seg_Buf[5]=Distance_Temp>=10?17:16;
						Seg_Buf[6]=Distance_Temp>=10?Distance_Temp/10:17;
						Seg_Buf[7]=Distance_Temp%10;//校准值
					}
				break;
				case 1:
					Seg_Point[6]=0;
					Seg_Buf[4]=Speed>=1000?Speed/1000:16;
					Seg_Buf[5]=Speed>=100?Speed/100%10:16;
					Seg_Buf[6]=Speed/10%10;
					Seg_Buf[7]=Speed%10;//速度
				break;
				case 2:
					Seg_Buf[4]=16;
					Seg_Buf[5]=16;
					Seg_Buf[6]=Voltage_Low/10%10;
					Seg_Point[6]=1;
					Seg_Buf[7]=Voltage_Low%10;//电压下限
				break;
			}
		break;
	}
//	/*DAC输出*/
//	if(Start_Voltage_Output)
//	{
//		if(Distance_Count[Count_Pos]>=90)
//			DAC_Voltage(255);
//		else if(Distance_Count[Count_Pos]<=10)
//			DAC_Voltage(Voltage_Low*5.1);
//		else
//		{
//			Voltage_Out=Voltage_Low*5.1+(Distance_Count[Count_Pos]-10)*(255-Voltage_Low*5.1)/80.0;
//			DAC_Voltage(Voltage_Out);
//		}
//		if(++Count_Pos==12)
//		{
//			Count_Pos=0;
//			Start_Voltage_Output=0;
//		}
//	}
//	/****/
}



/*Led处理函数*/
void Led_Proc()
{
	if(Led_Slow_Down)return;
	Led_Slow_Down=2;//误差消除
	/*******************/
	Distance=Read_Distance();//获取距离
	/*↓测量距离二次处理↓*/
	Distance=Distance*(Speed/340.0);
	Distance=Distance+Distance_Correct;
	/******↓记录距离数据↓******/
	if(Start_Count)
	{
		Distance_Count[Count_Pos]=Distance;
		if(++Count_Pos==60)
			Start_Count=0;
	}
	/*Led显示区域*/
	switch(Seg_Disp_Mode)
	{
		case 0:
			if(Distance>=255)
			{
				ucLed[0]=1;
				ucLed[1]=1;
				ucLed[2]=1;
				ucLed[3]=1;
				ucLed[4]=1;
				ucLed[5]=1;
				ucLed[6]=1;
				ucLed[7]=1;//大于255全亮
			}
			else
			{
				ucLed[0]=Distance%2;
				ucLed[1]=Distance/2%2;
				ucLed[2]=Distance/4%2;
				ucLed[3]=Distance/8%2;
				ucLed[4]=Distance/16%2;
				ucLed[5]=Distance/32%2;
				ucLed[6]=Distance/64%2;
				ucLed[7]=Distance/128%2;
			}//Led显示距离256种状态
		break;
		case 1:
			ucLed[7]=1;
		break;
		case 2:
			ucLed[0]^=1;
		break;
	}
	/*判断继电器动作*/
	if((Distance>=Distance_Index-5)&&(Distance<=Distance_Index+5)&&(temperature<=Temperature_Index))
		Relay_Flag=1;
	else
		Relay_Flag=0;
	/*DAC输出*/
	if(Start_Voltage_Output)
	{
		if(Distance_Count[Count_Pos]>=90)//距离大于等于90
			DAC_Voltage(255);
		else if(Distance_Count[Count_Pos]<=10)//距离小于等于10
			DAC_Voltage(Voltage_Low*5.1);
		else
		{
			Voltage_Out=Voltage_Low*5.1+(Distance_Count[Count_Pos]-10)*(255-Voltage_Low*5.1)/80.0;
			DAC_Voltage(Voltage_Out);
		}
		if(++Count_Pos==60)
		{
			Count_Pos=0;
			Start_Voltage_Output=0;
		}
	}
	/****/
	if(Recovery_Flag&&(Recovery_Count>=2000))
	{
		Distance_Index=40;//距离参数
		Temperature_Index=30;//温度参数
		Distance_Correct=0;//校准值
		Speed=340;//速度值
		Voltage_Low=10;//电压下限值
		Seg_Disp_Mode=0;//显示模式清零
		Inner_Mode=0;//子模式清零
		Count_Flag=0;//重置记录状态
	}
}

/*定时器0中断服务函数*/
void Timer0_Isr(void) interrupt 1
{
	if(++Key_Slow_Down==20)Key_Slow_Down=0;//20ms
	if(++Seg_Slow_Down==500)Seg_Slow_Down=0;//500ms
	if(++Led_Slow_Down==100)Led_Slow_Down=0;//100ms!!!
	if(Recovery_Flag)Recovery_Count++;//长按计时
	if(++Seg_Pos==8)Seg_Pos=0;//指针
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);//数码管刷新
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);//Led刷新
	Relay(Relay_Flag);//继电器
}
void Timer0_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA  = 1;				//打开总中断
}
/*主函数区域*/
void main()
{
	System_Init();	//系统初始化
	Timer0_Init();	//定时器0初始化
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值