蓝桥杯单片机第十一届第一场省赛-多功能电压测量装置

本文分享了作者在蓝桥杯单片机竞赛中的一些经验,包括如何灵活使用2x2矩阵按键,探讨AT24C02 EEPROM写入周期是否需要软件延时,以及参数边界处理和PCF8591上电初始化的处理。同时,介绍了利用定时器处理ADC计数问题的高效方法,强调了代码优化的重要性。
摘要由CSDN通过智能技术生成

九层妖塔 起于垒土

在这里插入图片描述


改编自国信长天蓝桥杯官方蓝皮书例程,按照自己的习惯进行了补充和修改


2021.4.3
在这里插入图片描述

源码题目0积分下载

Notes1:矩阵按键的灵活使用

 只用到S12,S13,S16,S17四个按键,即2乘2的矩阵按键。此时再使用4*4的程序模板有点臃肿。

在这里插入图片描述
 按键处理部分的算法依旧是三行代码。改的只是按键扫描部分:

uchar Key_Read(void)
{
    uchar Key_Value = 0;
	uchar Key_temp = 0;
  
	P35=0;P34=1;P33=1;P32=1;
	Key_temp = P3&0x0c;
	
	P35=1;P34=0;P33=1;P32=1;
	Key_temp = Key_temp | ((P3&0x0c)>>2) ;

	switch(~Key_temp)
	{
	  case 0xf8:Key_Value=12;break;
	  case 0xf4:Key_Value=13;break;
	  case 0xf2:Key_Value=16;break;
	  case 0xf1:Key_Value=17;break;
	  default: Key_Value = 0;
	}
	return Key_Value;
}

Notes2:AT24C02-EEPROM写入周期是否需要软件延时

 刚开时按照模板的写法是加了的,测试时候发现,按键变得不灵敏了。将5ms的软件延时(写入周期)删除后,按键依旧灵敏。
 其实大部分情况下是不需要延时来等待写入周期的。除非在写入EEPROM后马上读取,或者写入后马上对EEPROM进行读写操作。
 本届赛题中,只有在上电初始化时,未进入死循环前从EEPROM中读取了一个字节。写入是在退出参数界面时候写入。除此之外没有任何对EEPROM的操作。
 本届赛题中,要求在退出参数界面时候将电压参数P写入EEPROM,在参数界面有按键的加减功能,那怎么才算退出参数界面?我选择的是在进入下一个页面—计数界面的时候将数据写入EEPROM。各个界面之间依次循环,进入下一个界面也就是退出这一个页面。


Notes3:参数边界范围 防止出现参数越界

 1、加操作
 Value 是最大值+1,是暂态。

if(++num == Value) num = 0

 2、减操作

if(!num)  num = max;
else num--;

Notes4:PCF8591上电初始值0x80

 由于本届ADC是放在循环里移植读取刷新的,并且进入死循环前还需要对ADC的电压值进行判断来决定L1灯的亮灭。于是在死循环前加入以下代码。

uc_ADC_Value = PCF8591_ADC();
while(uc_ADC_Value == 0x80)
{
  uc_ADC_Value = PCF8591_ADC();
}

 如果是在数码管处理函数中显示:

uc_ADC_Value = PCF8591_ADC();
if(uc_ADC_Value != 0x80)
sprintf(puc_SEG_Buf,"%05.2f",(float)uc_ADC_Value/255.0*5);


Notes5:计数问题

在这里插入图片描述
1、先用定时器对电压值进行离散化采样。
 100ms保存一次电压值,100ms后再保存一次。只保存两次的电压值。本次的采样电压值ADC_temp,100ms前的采样电压值ADC_Old
 2、判断
 如果100ms前的采样电压值ADC_Old 比参数Vp大,而本次的采样电压值ADC_temp比参数Vp小,即可推出电压曲线向下穿过参数Vp,即满足计数条件。

  ADC_temp = uc_ADC_Value*10;
	
	if( (ADC_temp < c_V_p*51) && (ADC_Old > c_V_p*51) )  //下降沿
	{
		ADC_State = 'D';
		uc_jishu_num++;
		ul_ms_ADC = ul_ms;
	}
	
	if( (ADC_temp > c_V_p*51) && (ADC_Old < c_V_p*51) )  //上升沿
	{
	   ADC_State = 'G';
	}

  这个思路来自三行代码按键消抖的算法。

uc_ADC_Value = PCF8591_ADC();  //三行代码第一行
if( (ADC_temp < c_V_p*51) && (ADC_Old > c_V_p*51) ) //三行代码第二行 
	{//下降沿
      …… 
    }
ADC_Old = ADC_temp;   //三行代码第三行

  用 定时器三行代码 的按键算法,是因为看的官方例程(蓝色指导书)。没想到又会应用到这儿。使用这种算法判断ADC的电压值,可以达到小数点后第二位的精度。
  总之,官方代码永远的神!!!

👉定时器三行代码的按键算法

  
  
  
  
彩 蛋

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#法外狂徒张三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值