蓝桥杯单片机15届省赛案例,基于b站up主,Alice_西风的模板
此处仅发布main.c代码,整个工程文件在我发的唯一一个资源那里,学习用
#include <STC15F2K60S2.H>
#include <key.h>
#include <led.h>
#include <seg.h>
#include <ds1302.h>
#include <iic.h>
#define uchar unsigned char
#define uint unsigned int
//TIME
uchar ucrtc[]={19,5,20};
//LED
bit led_alarm;
bit led_flag_1,led_flag_2;
uchar led_buf[]={0,0,0,0,0,0,0,0};
//SEG
uchar seg_flag;
uchar seg_buf[]={10,10,10,10,10,10,10,10};
//宏
uint int_time;
uchar mode1;
bit mode2,mode3;
//KEY
uchar key_flag;
uchar key_val,key_down,key_old,key_up;
//VOLTAGE
bit vol_flag;//电压输出flag
float vol;//电压
//FREQUENCY
uint fre;
uint fre_m;//频率、频率最大值
uchar fre_c=2;//超限参数
char fre_j;//校准值
uchar ucrtc_m[]={0,0,0};//最大值触发时间
void vol_proc()
{
uint fre_cx;
fre_cx=fre_c*1000;
if(vol_flag) return;
vol_flag=1;
if(fre<=500) vol=1;
if(500<fre<=fre_cx) vol=((4*(fre-500))/(fre_cx-500)+1);
if(fre_cx<fre)
{vol=5;led_alarm=1;}
else{led_alarm=0;}
IIC_Write(vol);
}
void key_proc()
{
if(key_flag) return;
key_flag=1;
key_val=key_dis();
key_down=key_val&(key_old^key_val);
key_up=~key_val&(key_old^key_val);
key_old=key_val;
switch(key_down)
{
case 4:
mode1=(++mode1)%4;
mode2=mode3=0;
break;
case 5:
if(mode1==1) mode2=~mode2;
if(mode1==3) mode3=~mode3;
break;
case 8:
if(mode1==1)
{
if(mode2==0) fre_c=(++fre_c>=9)? 9:fre_c;
if(mode2==1) fre_j=(++fre_j>=9)? 9:fre_j;
}
break;
case 9:
if(mode1==1)
{
if(mode2==0) fre_c=(--fre_c<=1)? 1:fre_c;
if(mode2==1) fre_j=(--fre_j<=-9)? -9:fre_j;
}
break;
}
}
void seg_proc()
{
uint fre_jz=0;
uchar i;
if(seg_flag) return;
seg_flag=1;
DS1302_read(ucrtc);
fre_jz=fre+fre_j*100;
if(fre_jz<0) fre_jz=0;
if(fre_jz>fre_m)
{
fre_m=fre_jz;
for(i=0;i<3;i++)
{ucrtc_m[i]=ucrtc[i];}
}
if((mode1==0)&&(fre_jz!=0))//频率界面(fre>0
{
seg_buf[0]=12;
seg_buf[1]=10;
seg_buf[2]=10;
seg_buf[3]=(fre_jz/10000==0) ? 10 : fre_jz/10000;
seg_buf[4]=fre_jz/1000%10;
seg_buf[5]=fre_jz/100%10;
seg_buf[6]=fre_jz/10%10;
seg_buf[7]=fre_jz%10;
}
if((mode1==0)&&(fre_jz==0))//频率界面(fre<0
{
seg_buf[0]=12;
seg_buf[1]=10;
seg_buf[2]=10;
seg_buf[3]=10;
seg_buf[4]=10;
seg_buf[5]=10;
seg_buf[6]=16;
seg_buf[7]=16;
}
if(mode1==1&&mode2==0)//参数界面1
{
seg_buf[0]=14;
seg_buf[1]=(uchar)mode2+1;
seg_buf[2]=10;
seg_buf[3]=10;
seg_buf[4]=fre_c;
seg_buf[5]=0;
seg_buf[6]=0;
seg_buf[7]=0;
}
if(mode1==1&&mode2==1)//参数界面2
{
seg_buf[0]=14;
seg_buf[1]=(uchar)mode2+1;
seg_buf[2]=10;
seg_buf[3]=10;
seg_buf[4]=(fre_j<0)?11:10;
seg_buf[5]=(fre_j<0)? -fre_j:fre_j;
seg_buf[6]=0;
seg_buf[7]=0;
}
if(mode1==2)//时间界面
{
seg_buf[0]=ucrtc[0]/10;
seg_buf[1]=ucrtc[0]%10;
seg_buf[2]=11;
seg_buf[3]=ucrtc[1]/10;
seg_buf[4]=ucrtc[1]%10;
seg_buf[5]=11;
seg_buf[6]=ucrtc[2]/10;
seg_buf[7]=ucrtc[2]%10;
}
if(mode1==3&&mode3==0)//回显界面1
{
seg_buf[0]=15;
seg_buf[1]=(uchar)mode3+12;
seg_buf[2]=10;
seg_buf[3]=(fre_m/10000==0) ? 10 : fre_m/10000;
seg_buf[4]=fre_m/1000%10;
seg_buf[5]=fre_m/100%10;
seg_buf[6]=fre_m/10%10;
seg_buf[7]=fre_m%10;
}
if(mode1==3&&mode3==1)//回显界面2
{
seg_buf[0]=15;
seg_buf[1]=(uchar)mode3+12;
seg_buf[2]=ucrtc_m[0]/10;
seg_buf[3]=ucrtc_m[0]%10;
seg_buf[4]=ucrtc_m[1]/10;
seg_buf[5]=ucrtc_m[1]%10;
seg_buf[6]=ucrtc_m[2]/10;
seg_buf[7]=ucrtc_m[2]%10;
}
}
void led_proc()
{
if((mode1==0)&&(led_flag_1==0))
{
led_flag_1=1;
led_buf[0]=~led_buf[0];
}
if(mode1!=0){led_buf[0]=0;}
if((led_alarm)&&(led_flag_2==0))
{
led_flag_2=1;
led_buf[1]=~led_buf[1];
}
if(~led_alarm){led_buf[1]=0;}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0; //设置定时初值
TH0 = 0; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1;
}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void Timer1() interrupt 3
{
if(++int_time==1000)
{
int_time=0;
fre=TH0<<8|TL0;
TH0=TL0=0;
}
if(int_time%500==0) vol_flag=seg_flag=0;
if(int_time%50==0) key_flag=0;
if((int_time%200==0)&&(led_flag_1==1)) led_flag_1=0;
if((int_time%200==0)&&(led_flag_2==1)) led_flag_2=0;
led_dis(int_time%8,led_buf[int_time%8]);
seg_dis(int_time%8,seg_buf[int_time%8]);
}
void allinit()
{
P0=0xff;
P2=P2&0x1f|0x80;
P2=0x1f;
P0=0x00;
P2=P2&0x1f|0xa0;
P2=0x1f;
Timer0Init();
Timer1Init();
DS1302_init(ucrtc);
}
void main()
{
allinit();
while(1)
{
key_proc();
vol_proc();
seg_proc();
led_proc();
}
}