15届省赛已结束,这次结果也算自己的预期,考试的时候有失误,好在有惊无险,赛后已经更正
代码因为考试时间紧,就没有过多优化,有点长,但是更易懂
main
#include <STC15F2K60S2.H>
#include <Init.h>
#include <Key.h>
#include <Seg.h>
#include <Led.h>
#include "iic.h"
#include "ds1302.h"
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
unsigned char Key_Slow_Down;
unsigned char Seg_Pos;
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};
unsigned int Freq;
unsigned int Timer_1000ms;
unsigned char ucRtc[3]={0x13,0x03,0x05};
unsigned char Seg_Disp_Mode;//0-频率 1-参数 2-时间 3-回显
bit Para_Disp_Mode;//0-超限参数 1-校准值
unsigned int Freq_Para=2000;//超限参数 超限参数可调整范围: 1000Hz ~ 9000Hz
unsigned int jiaozhun_Value;//校准值参数可调整范围: -900Hz ~ 900Hz
bit Single_Flag;//符号标志位判断 1-表示有符号
bit Freq_Time;//0-频率回显 1-时间回显
unsigned int Freq_Max;
unsigned char Timer_Rtc[3];//最大频率发生的时间
bit error_Flag;//获得错误频率值标志位
float DA_Data;
unsigned char Timer_200ms;
bit Led_Flag;
bit L2_Flag;
unsigned char TimerL2_200ms;
unsigned int Freq_Data[2];//1位置放最大值 0位置实时更新
bit Freq_Flag;//判断是否是第一次获取Freq_Max标志位
void Key_Pro()
{
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;
switch(Key_Down)
{
case 4:
if(++Seg_Disp_Mode==4)
Seg_Disp_Mode=0;
if(Seg_Disp_Mode==0)//每次从频率界面切换到参数界面时, 处于超限参数子界面
Para_Disp_Mode=0;
else if(Seg_Disp_Mode==2)//每次从时间界面切换到回显界面时,处于频率回显子界面
{
Freq_Time=0;
}
break;
case 5:
if(Seg_Disp_Mode==1)//参数界面前提下
Para_Disp_Mode^=1;
else if(Seg_Disp_Mode==3)//回显界面前提下
Freq_Time^=1;
break;
case 8://加
if(Seg_Disp_Mode==1)//参数界面前提下
{
if(Para_Disp_Mode==0)//超限参数设置
{
Freq_Para+=1000;
if(Freq_Para>9000)
Freq_Para=9000;
}
else//校准值设置
{
if(jiaozhun_Value==0)//已到正数阶段
Single_Flag=0;
if(Single_Flag==1)//处于负数 需要进行减值 以完成加值操作
{
jiaozhun_Value-=100;
}
else//正常减值
{
jiaozhun_Value+=100;
if(jiaozhun_Value>900)
jiaozhun_Value=900;
}
}
}
break;
case 9://减
if(Seg_Disp_Mode==1)//参数界面前提下
{
if(Para_Disp_Mode==0)//超限参数设置
{
Freq_Para-=1000;
if(Freq_Para<1000)
Freq_Para=1000;
}
else//校准值设置
{
if(jiaozhun_Value==0)//进入负数阶段
Single_Flag=1;//符号标志位置1
if(Single_Flag==1)
{
jiaozhun_Value+=100;//进行1加值操作 以完成减成负数的结果
if(jiaozhun_Value>900)//负数边界限制
jiaozhun_Value=900;
}
else//值为100~900之间 正常减
{
jiaozhun_Value-=100;
}
}
}
break;
}
}
void Seg_Pro()
{
unsigned char i;
if(Seg_Slow_Down) return;
Seg_Slow_Down=1;
/*数据获取区域*/
Read_Rtc(ucRtc);
DA_Write(DA_Data*51);
if(error_Flag==0)//获得正确的频率条件下
{
Freq_Data[0]=Freq;
if(Freq_Flag==0)//第一次存放
{
Freq_Max=Freq_Data[0];
Freq_Data[1]=Freq_Data[0];
for(i=0;i<3;i++)
Timer_Rtc[i]=ucRtc[i];
}
else//第二次以上存放
{
if(Freq_Data[0]<=Freq_Data[1])
{
Freq_Max=Freq_Data[1];//1 位置存放大值 0位置实时更新值
}
else if(Freq_Data[0]>=Freq_Data[1])
{
Freq_Data[1]=Freq_Data[0];
Freq_Max=Freq_Data[1];
for(i=0;i<3;i++)
Timer_Rtc[i]=ucRtc[i];
}
}
Freq_Flag=1;//标志置1 表示非第一次存放
}
/*数据显示区域*/
switch(Seg_Disp_Mode)
{
case 0://频率
Seg_Buf[1]=Seg_Buf[2]=10;
Seg_Buf[0]=11;//F
if(error_Flag==1)//获得错误频率
{
for(i=1;i<=5;i++)
Seg_Buf[i]=10;//清零
Seg_Buf[6]=Seg_Buf[7]=16;
}
else
{
Seg_Buf[3]=(unsigned int)Freq/10000%10;
Seg_Buf[4]=(unsigned int)Freq/1000%10;
Seg_Buf[5]=(unsigned int)Freq/100%10;
Seg_Buf[6]=(unsigned int)Freq/10%10;
Seg_Buf[7]=(unsigned int)Freq%10;
if(Seg_Buf[3]==0)//高位熄灭
{
Seg_Buf[3]=10;
if(Seg_Buf[4]==0)
{
Seg_Buf[4]=10;
if(Seg_Buf[5]==0)
{
Seg_Buf[5]=10;
if(Seg_Buf[6]==0)
Seg_Buf[6]=10;
}
}
}
}
break;
case 1://参数
Seg_Buf[0]=12;//P
if(Para_Disp_Mode==0)//超限参数界面
{
Seg_Buf[2]=Seg_Buf[3]=10;
Seg_Buf[1]=1;
Seg_Buf[4]=Freq_Para/1000%10;
Seg_Buf[5]=Freq_Para/100%10;
Seg_Buf[6]=Freq_Para/10%10;
Seg_Buf[7]=Freq_Para%10;
if(Seg_Buf[4]==0)//高位熄灭
{
Seg_Buf[4]=10;
if(Seg_Buf[5]==0)
{
Seg_Buf[5]=10;
if(Seg_Buf[6]==0)
Seg_Buf[6]=10;
}
}
}
else//校准值界面
{
Seg_Buf[2]=Seg_Buf[3]=Seg_Buf[4]=10;
Seg_Buf[1]=2;
if(Single_Flag==0)//无符号
{
Seg_Buf[5]=(unsigned int)jiaozhun_Value/100%10;
Seg_Buf[6]=(unsigned int)jiaozhun_Value/10%10;
Seg_Buf[7]=(unsigned int)jiaozhun_Value%10;
if(Seg_Buf[5]==0)//高位熄灭
{
Seg_Buf[5]=10;
if(Seg_Buf[6]==0)
Seg_Buf[6]=10;
}
}
else//有符号
{
Seg_Buf[4]=15;//-
Seg_Buf[5]=(unsigned int)jiaozhun_Value/100%10;
Seg_Buf[6]=(unsigned int)jiaozhun_Value/10%10;
Seg_Buf[7]=(unsigned int)jiaozhun_Value%10;
if(Seg_Buf[5]==0)//高位熄灭
{
Seg_Buf[4]=10;//符号位也要熄灭
Seg_Buf[5]=10;
if(Seg_Buf[6]==0)
Seg_Buf[6]=10;
}
}
}
break;
case 2://时间
Seg_Buf[2]=Seg_Buf[5]=15;
for(i=0;i<3;i++)
{
Seg_Buf[3*i]=ucRtc[i]/16;
Seg_Buf[3*i+1]=ucRtc[i]%16;
}
break;
case 3://回显
Seg_Buf[0]=13;//H
if(Freq_Time==0)//频率回显
{
Seg_Buf[2]=10;
Seg_Buf[1]=11;//F
Seg_Buf[3]=Freq_Max/10000%10;
Seg_Buf[4]=Freq_Max/1000%10;
Seg_Buf[5]=Freq_Max/100%10;
Seg_Buf[6]=Freq_Max/10%10;
Seg_Buf[7]=Freq_Max%10;
if(Seg_Buf[3]==0)//高位熄灭
{
Seg_Buf[3]=10;
if(Seg_Buf[4]==0)
{
Seg_Buf[4]=10;
if(Seg_Buf[5]==0)
Seg_Buf[5]=10;
}
}
}
else//时间回显
{
Seg_Buf[1]=14;//A
Seg_Buf[2]=Timer_Rtc[0]/16;
Seg_Buf[3]=Timer_Rtc[0]%16;
Seg_Buf[4]=Timer_Rtc[1]/16;
Seg_Buf[5]=Timer_Rtc[1]%16;
Seg_Buf[6]=Timer_Rtc[2]/16;
Seg_Buf[7]=Timer_Rtc[2]%16;
}
break;
}
}
void Led_Pro()
{
/*DAC相关*/
if(Freq<500)
DA_Data=1;
else if(Freq>Freq_Para)
DA_Data=5;
else
DA_Data=1+4*(Freq-500)/(Freq_Para-500);
/*Led相关*/
ucLed[0]=Led_Flag&(0==Seg_Disp_Mode);
if(error_Flag==0)//正确的状态下
{
if(Freq>Freq_Para)
ucLed[1]=L2_Flag;
else
ucLed[1]=0;
}
else//频率错误情况下 点亮error_Flag=1
{
ucLed[1]=error_Flag;
}
}
/*定时器1初始化函数*/
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
/*定时器0初始化函数*/
void Timer0Init(void) //0毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
/*定时器1服务函数*/
void Timer1Server() interrupt 3
{
if(++Key_Slow_Down==10) Key_Slow_Down=0;
if(++Seg_Pos==8) Seg_Pos=0;
if(++Seg_Slow_Down==100) Seg_Slow_Down=0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
if(Seg_Disp_Mode==0)//处于频率界面
{
if(++Timer_200ms==200)
{
Timer_200ms=0;
Led_Flag^=1;
}
}
if(error_Flag==0)
{
if(++TimerL2_200ms==200)
{
TimerL2_200ms=0;
L2_Flag^=1;
}
}
// Freq=(Single_Flag==1?Freq-jiaozhun_Value:Freq+jiaozhun_Value);
if(++Timer_1000ms==1000)
{
TR0 = 0;
Timer_1000ms=0;
if(Single_Flag==0)//无符号
{
Freq=TH0<<8|TL0;
Freq+=jiaozhun_Value;
}
else
{
Freq=TH0<<8|TL0;
Freq-=jiaozhun_Value;
}
if(Freq<=65535&&Freq>50000)
error_Flag=1;//获得错误频率值
else
error_Flag=0;
TH0=TL0=0;
TR0 = 1;
}
}
void main()
{
System_Init();
Timer0Init();
Timer1_Init();
Set_Rtc(ucRtc);
while(1)
{
Key_Pro();
Seg_Pro();
Led_Pro();
}
}
总的来说,善于用标志位能解决很多问题
这里这是提供思路,可能不是很好,仅供大家参考