目录
2.直接使用char类型 会自动判别校准值与0的大小(范围:-128~+127)写入数码管时在负数的情况下前面再加个负号就能解决
前言
本文介绍了蓝桥杯单片机第十四届国赛易错点及注意事项
第十四届国赛实现难度相比于省赛更加容易,但是对于题目的理解才是重中之重。
一.负数
负数问题在第十五届省赛中也有考到,现给出两种解决办法
1.采用设置标志位的办法实现假负数
if(fu==0)//校准值大于等于0的情况
{
if(check>0)
{
if(Key_Up==8)
{
check+=5;
if(check==95)check=90;
}
else if(Key_Up==9)
{
check-=5;
}
}
else if(check==0)//当校准值等于0
{
if(Key_Up==8)//正常加
{
check+=5;
if(check==95)check=90;
}
else if(Key_Up==9)//减的时候校准值变成5,并改变标志位
{
check=5;
fu=1;//对应为数码管带负号的情况
}
}
}
else if(fu==1)//此时为负数的情况,加减对调
{
if(check>0)
{
if(Key_Up==8)
{
check-=5;//注:校准值等于0时让fu默认为0,就会跳出语句
}
else if(Key_Up==9)
check+=5;
if(check==95)check=90;
}
}
2.直接使用char类型 会自动判别校准值与0的大小(范围:-128~+127)写入数码管时在负数的情况下前面再加个负号就能解决
二.按键
1.S8按键
仔细看题
记录功能:只在测距界面下生效,并且记录6s内距离的连续变化,其他按键无效,保留最近记录的一组数据(整套题目的关键点)
相信大部分人第一眼看到都会觉得是记录6s结束的最后一个数据,这是错误的
我们应该设置一个数组来存储6s内的一串距离数据,并且因为题目性能要求超声波数据刷新时间最长为1s,为了节省内存所以设置7位的数组
if(writedown==1)//按键按下标志
{
if(count4%1000==0)//1s记录一次
{
Grouplength[i]=writelength;
i++;
if(i==7)i=0;
}
if(count4==6000)//6s后退出记录
{
count4=0;
writedown=0;
}
count4++;//放最后是为了count4=0时可以记录到数据
}
2.S9按键
同样的 输出数据也是一连串的
输出功能也只在测距界面生效
if(readac==1)//输出数据
{
if(count8%1000==0)
{
lastlength=Grouplength[j];
j++;
if(j==7)j=0;
}
if(count8==6000)
{
readac=0;
count8=0;
}
count8++;
}
3.双按键
在矩阵键盘底层加入双按键情况,因为题目说长按持续状态超过2s实现功能,所以无需松手检测
只要定时达到2s时立刻恢复初始状态,和松手时间无关。
又因为松手产生的时间差会导致某个数值的加减变化,这里设一个标志位,当双按键按下时锁住其他按键的加减功能,但此时键值读取还是正常的,等松手后再解锁键盘就实现了完美的双按键长按功能。
P42=0;P34=P35=P44=1;
if(P33==0&&P32==0)Temp=89;
if(Key_Down==89)
{
writedown=0; //防止在测距界面按下s8时会触发记录功能
time2s=1; //开始计时
lock=1; //因为双按键按下会有时间差 为了避免造成影响将键盘锁住
}
else if(Key_Old==0)//如果上一个时刻的键值读取为0 意味着没有按键按下
{
time2s=0;
lock=0;//此时退出锁定
}
还有一个注意点 初始状态 并不只是数值初始化 还有界面的初始状态为测距界面
三. DAC
dac输出是本套试题的一大难点 归根结底很多人做不出来是记录和输出有问题
if(readac==1)//定时器内进行计时
{
if(count8%1000==0)//按顺序每s输出一次记录的其中一个数据
{
lastlength=Grouplength[j];
j++;
if(j==7)j=0;
}
if(count8==6000)
{
readac=0;
count8=0;
}
count8++;
}
if(readac==1)//测距界面下进行输出数据
{
if(lastlength<=10)
putdac=dac*0.1;
else if(lastlength>10&&lastlength<90)
{
putdac=((lastlength-10)/80.0)*(5-dac/10.0)+dac*0.1;
}
else if(lastlength>=90)
putdac=5.0;
}
DA_Write(putdac*51.0);//在while里直接输出dac
四.LED
最大的问题是在测距界面按距离点亮led指示灯
这里采用直接赋值给P0并取反,因为计算机会将十进制自动转化为二进制 而十六进制的本质也是转化成了二进制 所以可以直接赋值
值得注意的是为了防止LED闪烁太快造成现象不好 我们可以在定时器内设置一个200ms延时的标志位
if(flag1==1)//测距界面下
{
flag1=0;
P0=~length;
InitHC138(4);
}
if(count6==200)//定时器内
{
flag1=1;
count6=0;
}
五.继电器
因为继电器控制没有特定在某一界面 所以测距读取要放在while内
为了避免继电器和蜂鸣器间的影响 我们直接使用优化后的继电器模块
void Relay(unsigned char flag)
{
static unsigned char temp = 0x00;
static unsigned char temp_old = 0xff;
if(flag)
temp |= 0x10;
else
temp &= ~0x10;
if(temp != temp_old)
{
P0 = temp;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
temp_old = temp;
}
}