蓝桥杯单片机真题实践篇

这里就不完全写思路过程代码什么的,这一篇文章就写我在训练真题中遇到的过程。

(呜呜呜,时间不够辣,能做多少算多少吧....)

十三届省赛题

问题1:数码管的数字消影不明显

(参考:蓝桥杯单片机开发板的数码管的消影_数码管消除鬼影-CSDN博客

解决方法:

位选不选择任何数码管(消除影子)->再段选->再位选

或者是

先段选不选中数码管的任何段->再位选->再段选

原来:消影不明显

变成:

同时数码管Display前后显示都用关闭全部数码管,消影效果会更好。

问题2:按键切换模式时不够灵敏

问题3:IO模式下HC138译码器选通问题

经常用到的其实只有4567,其他为了操作方便可以不写,

前后关闭一下译码器会比较好,还可以将选通通道和赋值写在一起,这样比较简洁好看:

问题4 DS1302写入函数的写法:

最后最好还是要加上写操作关闭

问题5 当main函数中的执行的模块化函数过多时

可以将不在while循环里的函数,重新写一个函数放到初始化函数里面。

问题7:一个新的写LED闪烁的写法:

&=表示位与操作,|= 表示位或操作。

  1. if((LED & 0x04) == 0x04):这里是检查LED的取出第3位是否为1,(为1说明L3熄灭)如果为1则执行LED &= ~0x04,将LED的第3位清零,即L3点亮;如果为0则执行LED |= 0x04,将LED的第3位设为1,即L3熄灭。

  2. selecthc138(4, LED):这个函数应该是用来控制LED的显示,以此来控制LED灯的点亮和熄灭。

if(jdq == 0x10 )  //继电器吸合 
{
	count_100++
	if(count100 == 2)  //0.1s
	{
		count100 == 0       
		{
			if((LED & 0x04 == 0x04))
			{
				LED &= ~0x04
			}
			else
			{
				LED |= 0x04
			}
			selecthc138(4,LED)   //点亮LED灯 
		}
	}
 } 

问题8:判断继电器吸合与否

这里就是问题3中选译码器时,可以把数据也传进去函数,然后让数据用一个名称来代替,那么判断继电器吸合与否我就判断这个名称的变量即可

比如:if(jdq == 0x10 )  //判断继电器是否是吸合状态 

           selectHC138(5,jdq) 这就是让继电器吸合

问题9 :计时的一个问题

这次试题有两个计时问题,一个是0.1s L3来回闪烁,一个是5秒,L1亮5s就熄灭停止。

一个是闪烁,一个是亮了一次就停止,等到下一个整点再亮5s又停止。

首先,Delay函数写不出那么长时间,所以必须用定时器,其次,定时器用两个的话太麻烦,

可以只用一个, 这里定时一个单位是50ms。

闪烁的0.1秒就用平时的,一到0.1s就清零,或者是取余。如图:

而5s的可以设置一个F_Time标志表示5s开始,

整点,5s要开始了,F_Time=1;

后面就要判断5s开始,那么就count_5s++,加到100就是0.5s,count_5s清零,同时标志F_Time=0(如果设置标志位直接清0,则即使执行了一次点亮后,没到整点又会继续执行。)

每到整点时,标志位置一,又开始启动5s。

其次,这里的5s内执行继电器等操作,不用<5 执行,>5停止,这里只判断一次,当5s到了就停止.

问题10:读题问题

有点读题的错误:

1. 题目是参数设置界面的温度值应该是初始为23,应该是自己设置的参数,而不是DS13B20测出来的,不然就算按键按下后修改了++  -- 温度,还是会跳回当前的温度,毕竟DS13B20测出来当前是多少就是多少,这是不可以改变的。

第十四届省题

问题1:数码管显示多个界面显示还有某界面还有子界面的情况

首先自己的想法是用两个flag,一个flag表示本来的四个界面,flag1用于转换为第二个界面的子界面,这样是不好显示的我发现,很容易显示子界面时就黑屏。   XXXX

看了小蜜蜂老师的,还是只用一个flag来显示比较好,子界面也成为flag里面的一种情况。然后跳转子界面可以用if ,else if语句。

if ,elseif语句原来是如果if满足就不会再执行下面语句了!所以上面图片flag=5后不会再执行else if。但是if,if语句的话如何第一个if满足,还是会判断下一个if是否满足。

问题2:光敏电阻由亮到暗如何判断

光敏电阻用的是AD转换,是将模拟电压转换为数字电压,所以判断亮暗就变成了判断前后数字大小。

由于涉及到前后,故需要两个变量来储存前后两个状态,然后比较这两个状态的大小。

我本来的思路是两个状态相减不等于0就是有一个转变过程,但烧进去发现就一直是触发状态,这里我感觉有两个错误,1是未审好题,题目是由亮到暗,而不等于0是可能亮到暗也可能暗到亮两种;2是由于每次测量有误差,即使是不挡光,可能测得的每次本来就不太可能一样,所以这个条件总是满足,就总是触发状态。     XXXXX

看了小蜜蜂老师的思路,他是自定义一个阈值为50,>50为亮,<=50为暗

但是其实我是有疑问的,光敏电阻不是光强和阻值成反比吗?光越亮,阻值越小,分压不是越小吗?(但老师的烧进去又是正确的呜呜呜,不管啦!!!明天就比赛啦!!!)

问题3:PC8591的另一种传入函数的写法

之前写PC8591的时候,说过由ADC 和 DA输出函数,(怎么说,还是有点没太理解透...)

就这样写!之前说ADC函数是写在一起的分为写——等待——读——电压转换,现在就分开来,把等待去掉(因为这次试题又说触发小于0.05s,但是我发现触发响应的时间好长,然后就察觉到了是这个Delay函数的原因,拖长了时间,要把它去掉)

ADC函数:

注意:转换电压那里千万别忘了写5.0,.0不能去掉!!!还有公式就记成是转换成 n V的电压来计算。

//将写的这部分独立出来一个函数(然后就去掉Delay)
void Set_PCF(unsigned char AIN)
{
  I2CStart();
  I2CSendAck(0x90);
  I2CWaitAck();
  I2CSendAck(AIN);  //将AIN作为函数传进来,转换通道比较容易,不用重复写,比如光敏电阻,电位计...
  I2CWaitAck();  
  I2CStop();
}

void Read_PCF()
{
  I2CStart();
  I2CSendAck(0x91);
  I2CWaitAck();
  dat =  I2CReceiveByte();
  I2CSendAck(1);
  I2CStop();  
  
  adc_volt = dat * (5.0 / 255);      
  smg_volt = adc_volt * 100;
}

DA函数:

观察其实就是比ADC中的set(写函数)多了:DA_dat是要输出的电压

I2CSendAck(DA_dat); 
 I2CWaitAck();

void DA(unsigned DA_dat)
{
  I2CStart();
  I2CSendAck(0x90);
  I2CWaitAck();
  I2CSendAck(0x40);    
  I2CWaitAck(); 
  I2CSendAck(DA_dat); 
  I2CWaitAck();  
  I2CStop();  
}

问题4 :取最大温度时读取到最大值为初始温度85

这是因为没有去掉初始温度,要写个温度初始化函数,已经在之前的DS13B20中更新了,可以回去看看

就写到这啦!!!明天就比赛了!!!祝我好运叭!!!!!!!!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值