前言
第十五届蓝桥杯单片机省赛刚刚结束,在比赛之前对这届单片机的程序题预计难度会很高,因为十四届的程序题难度彪高,又整合了许多模块,导致十四届没考的模块寥寥无几,本来预计会考超声波和串口,所幸没考,本次程序着重考察的是da输出和ne555定时器,围绕着ne555检测到的模拟电压输入频率做的一系列操作,难点在于一个需要对频率做一个调参操作,涉及到负数和正数的调节,还有一个就是根据超限参数,来调整da输出的倍率,总体难度不高,正常完成时间大概在3小时左右,下面上题目:
程序题
代码:
对于这次题目的难点代码稍微解释一下,因为调参需要用到负数,并且要显示出来,所以定义了两个变量,到正数变量减到0,且按键再一次输入时,标志位置一且负数变量+100,当标志位为1时,对频率减去负数变量,且显示横杠加负数变量。然后就是根据超限频率调整DA输出,直接定义一个调整倍率的函数,switch超限参数的值,因为超限只能1k到9k,所以全部case出来,然后用计算器算出倍率,在定义一个浮点型的全局变量,根据超限的值调整这个浮点型变量的值,然后再成当前频率减500hz输出就行了。
#include "reg52.h"
#include "intrins.h"
#include "iic.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
sfr P4 = 0xc0;
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P3^4;
sbit C2 = P3^5;
sbit C3 = P4^2;
sbit C4 = P4^4;
void Display();
code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};
uchar fiag0=1;
float beilv;
uchar LED=0xff;
uchar DA;
uchar t_m,t_h,t_s;
uchar cuowu=0;
uint f,dis_fyuanshi,dis_f,dis_fmax;
uchar fushu;
uint tiaozheng,chaoxian=2000,tiaozheng2;
uchar count1s,countkey,countLED;
uchar Ds1302_Write[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar Ds1302_Read[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar Time[3] = {0x05,0x03,0x13};
void Delayus(uchar j)
{
while(j--);
}
void SelectHC573(uchar n)
{
switch(n)
{
case 0:P2 = (P2&0x1f)|0x00;break;
case 4:P2 = (P2&0x1f)|0x80;break;
case 5:P2 = (P2&0x1f)|0xa0;break;
case 6:P2 = (P2&0x1f)|0xc0;break;
case 7:P2 = (P2&0x1f)|0xe0;break;
}
}
void ShowSMG(uchar pos,uchar dat)
{
SelectHC573(6);
P0 = 0x01<<pos;
SelectHC573(7);
P0 = dat;
Delayus(500);
P0 = 0xff;
}
uchar CountS4,CountS5;
void KeyScanf()
{
R3=0;
R1 = R2 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C4==0)//S5
{
countkey=0;while(countkey==0)Display();
if(C4==0)
{
while(C4==0)Display();
CountS5++;if(CountS5==2)CountS5=0;
}
}
if(C3==0)//S9
{
countkey=0;while(countkey==0)Display();
if(C3==0)
{
while(C3==0)Display();
if((CountS4==1)&&(CountS5==0))
{
if(chaoxian!=1000)
chaoxian-=1000;
}
if((CountS4==1)&&(CountS5==1))
{
if(tiaozheng!=0)
{
tiaozheng-=100;
}
else
{
fushu=1;
if(tiaozheng2!=900)tiaozheng2+=100;
}
if((tiaozheng==0)&&(tiaozheng2==0))
{
fiag0 = 1;
}
else
{
fiag0 = 0;
}
}
}
}
R4=0;
R1 = R2 = R3 = 1;
C1 = C2 = C3 = C4 = 1;
if(C4==0)//S4
{
countkey=0;while(countkey==0)Display();
if(C4==0)
{
while(C4==0)Display();
CountS4++;if(CountS4==4)CountS4=0;
}
}
if(C3==0)//S8
{
countkey=0;while(countkey==0)Display();
if(C3==0)
{
while(C3==0)Display();
if((CountS4==1)&&(CountS5==0))
{
if(chaoxian!=9000)chaoxian+=1000;
}
if((CountS4==1)&&(CountS5==1))
{
if(fushu==1)
{
if(tiaozheng2!=0)tiaozheng2-=100;
if(tiaozheng2==0)
{
fushu=0;
}
}
else
{
if(tiaozheng!=900)tiaozheng+=100;
}
if((tiaozheng==0)&&(tiaozheng2==0))
{
fiag0 = 1;
}
else
{
fiag0 = 0;
}
}
}
}
}
void InitSystem()
{
P0 = 0x00;
SelectHC573(5);
SelectHC573(0);
}
void Inittimer()
{
TMOD = 0x16;
TH0 = 0xff;
TL0 = 0xff;
TH1 = (65535-10000)/256;
TL1 = (65535-10000)%256;
ET0 = 1;
ET1 = 1;
EA = 1;
TR0 = 1;
TR1 = 1;
}
void ServiceT0() interrupt 1
{
f++;
}
void ServiceT1() interrupt 3
{
TH1 = (65535-10000)/256;
TL1 = (65535-10000)%256;
count1s++;
countkey++;
countLED++;if(countLED==40)countLED=0;
if(count1s==100)
{
dis_fyuanshi = f;
f=0;
count1s = 0;
}
}
void Ds1302_config()
{
uchar i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<3;i++)
{
Write_Ds1302_Byte(Ds1302_Write[i],Time[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void Read_Time()
{
uchar i;
for(i=0;i<3;i++)
{
Time[i] = Read_Ds1302_Byte (Ds1302_Read[i]);
}
}
void DA_transport(uchar x)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40);
I2CWaitAck();
I2CSendByte(x);
I2CWaitAck();
}
void Showf()
{
ShowSMG(0,Seg_Table[15]);
if(dis_f/10000!=0)
{
ShowSMG(3,Seg_Table[dis_f/10000]);
}
if(dis_f/1000!=0)
{
ShowSMG(4,Seg_Table[dis_f%10000/1000]);
}
if(dis_f/100!=0)
{
ShowSMG(5,Seg_Table[dis_f%1000/100]);
}
if(dis_f/10!=0)
{
ShowSMG(6,Seg_Table[dis_f%100/10]);
}
ShowSMG(7,Seg_Table[dis_f%10]);
}
void ShowTime()
{
ShowSMG(0,Seg_Table[Time[2]/16]);
ShowSMG(1,Seg_Table[Time[2]%16]);
ShowSMG(2,0xbf);
ShowSMG(3,Seg_Table[Time[1]/16]);
ShowSMG(4,Seg_Table[Time[1]%16]);
ShowSMG(5,0xbf);
ShowSMG(6,Seg_Table[Time[0]/16]);
ShowSMG(7,Seg_Table[Time[0]%16]);
}
void Showchaoxian()
{
ShowSMG(0,0x8c);
ShowSMG(1,Seg_Table[1]);
ShowSMG(4,Seg_Table[chaoxian/1000]);
ShowSMG(5,Seg_Table[chaoxian%1000/100]);
ShowSMG(6,Seg_Table[chaoxian%100/10]);
ShowSMG(7,Seg_Table[chaoxian%10]);
}
void ShowTiaozheng()
{
ShowSMG(0,0x8c);
ShowSMG(1,Seg_Table[2]);
if(fiag0==0)
{
if(fushu==0)
{
ShowSMG(5,Seg_Table[tiaozheng/100]);
ShowSMG(6,Seg_Table[tiaozheng%100/10]);
ShowSMG(7,Seg_Table[tiaozheng%10]);
}
else
{
ShowSMG(4,0xbf);
ShowSMG(5,Seg_Table[tiaozheng2/100]);
ShowSMG(6,Seg_Table[tiaozheng2%100/10]);
ShowSMG(7,Seg_Table[tiaozheng2%10]);
}
}
else
{
ShowSMG(7,Seg_Table[0]);
}
}
void Showcuowu()
{
ShowSMG(0,Seg_Table[15]);
ShowSMG(6,0xc7);
ShowSMG(7,0xc7);
}
void Showfmax()
{
ShowSMG(0,0x89);
ShowSMG(1,Seg_Table[15]);
if(dis_fmax/10000!=0)
{
ShowSMG(3,Seg_Table[dis_fmax/10000]);
}
if(dis_fmax/1000!=0)
{
ShowSMG(4,Seg_Table[dis_fmax%10000/1000]);
}
if(dis_fmax/100!=0)
{
ShowSMG(5,Seg_Table[dis_fmax%1000/100]);
}
if(dis_fmax/10!=0)
{
ShowSMG(6,Seg_Table[dis_fmax%100/10]);
}
ShowSMG(7,Seg_Table[dis_fmax%10]);
}
void ShowTimemax()
{
ShowSMG(0,0x89);
ShowSMG(1,Seg_Table[10]);
ShowSMG(2,Seg_Table[t_h/16]);
ShowSMG(3,Seg_Table[t_h%16]);
ShowSMG(4,Seg_Table[t_m/16]);
ShowSMG(5,Seg_Table[t_m%16]);
ShowSMG(6,Seg_Table[t_s/16]);
ShowSMG(7,Seg_Table[t_s%16]);
}
void Display()
{
switch(CountS4)
{
case 0:
switch (cuowu)
{
case 0:Showf();break;
case 1:Showcuowu();break;
}
CountS5=0;
break;
case 1:
switch(CountS5)
{
case 0:Showchaoxian();break;
case 1:ShowTiaozheng();break;
}
break;
case 2:ShowTime();CountS5=0;break;
case 3 :
switch(CountS5)
{
case 0:Showfmax();break;
case 1:ShowTimemax();break;
}
break;
}
}
void Ctrlf()
{
switch(fushu)
{
case 0:dis_f = dis_fyuanshi+tiaozheng;break;
case 1:
if(dis_fyuanshi<tiaozheng2)
{
cuowu = 1;
}
else
{
cuowu = 0;
dis_f = dis_fyuanshi-tiaozheng2;
}
break;
}
if(dis_f>dis_fmax)
{
dis_fmax=dis_f;
t_h=Time[2];
t_m=Time[1];
t_s=Time[0];
}
}
void Ctrlbeilv()
{
switch(chaoxian)
{
case 1000:beilv=1;break;
case 2000:beilv=0.33;break;
case 3000:beilv=0.2;break;
case 4000:beilv=0.14;break;
case 5000:beilv=0.11;break;
case 6000:beilv=0.09;break;
case 7000:beilv=0.076;break;
case 8000:beilv=0.066;break;
case 9000:beilv=0.058;break;
}
}
void CtrlDA()
{
uint dianya;
if((dis_f<=chaoxian)&&(dis_f>500))
{
dianya = 100+((dis_f-500)*beilv);
}
if(dis_f<=500)
{
dianya = 100;
}
if(dis_f>=chaoxian)
{
dianya =500;
}
if(cuowu==1)
{
dianya = 0;
}
DA = dianya*0.51;
DA_transport(DA);
}
void CtrlLED()
{
if(CountS4==0)
{
if(countLED>=20)
{
LED = LED&0xfe;
}
if(countLED<20)
{
LED = LED|0x01;
}
}
else
{
LED = LED|0x01;
}
if((dis_f>chaoxian)||(cuowu==1))
{
if(cuowu==1)
{
LED = LED&0xfd;
}
else
{
if(countLED>=20)
{
LED = LED&0xfd;
}
if(countLED<20)
{
LED = LED|0x02;
}
}
}
else
{
LED = LED|0x02;
}
SelectHC573(0);
P0 = 0xff;
SelectHC573(4);
P0 = LED;
SelectHC573(0);
P0 = 0xff;
}
void main()
{
InitSystem();
Ds1302_config();
Inittimer();
while(1)
{
KeyScanf();
CtrlLED();
Read_Time();
Ctrlf();
Ctrlbeilv();
CtrlDA();
Display();
}
}