/*头文件声明区域*/
#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();
}
}
第十四届蓝桥杯电子类单片机决赛程序代码
最新推荐文章于 2024-08-30 21:34:59 发布