从单片机基础到程序框架(全集 2019pdf版).pdf - 第547页

第一百零七节: 开关感应器的识别与软件滤波。 【107.1 开关感应器的识别与软件滤波。 】 上图 10 7.1.1 独立按键模 拟开关感应器 上图 10 7.1.2 LED 电路 什么叫开关 感应器?凡是 只能输出 0 和 1 这两 种状态的感应 器都可 以统称为开关 感应器。 前面花了大 量 的章节讲按 键, 按键的识别 主要是识别 电平变化状态 的 “下降沿” , 程序 代码中 有 1 个特别的变量标志 叫 “自 锁标志” , 还…

100%1 / 836
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)
{
P3_4=1;
}
void VoiceScan(void)
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
第一百零七节: 开关感应器的识别与软件滤波。
【107.1 开关感应器的识别与软件滤波。
上图 107.1.1 独立按键模拟开关感应器
上图 107.1.2 LED 电路
什么叫开关感应器?凡是只能输出 0 1 这两种状态的感应器都可以统称为开关感应器。前面花了大
的章节讲按键,按键的识别主要是识别电平变化状态“下降沿”程序代码中 1 个特别的变量标志“自
锁标志”还有 1 用来消除抖动的计时器”本节讲的开关感应器跟按键很相似,差别在于,开关感应器
是识别电平变化状态的“电平程序代码中没有“自锁标志”但是多增加了 1 个用来消除抖动“计时器”
也就是一共有两个用来消除抖动的“计时器”,这两个“计时器”相互“清零”相互“抗衡,从而实现了开
关感应器的“消抖处理,专业术语也“软件滤波”消抖的时间跟按键差不多,我的经验值是 20ms 30ms
之间,我平时在项目中喜欢用 20ms。
在显示框架方面,除了之前讲过 Gu8DisplayUpdate 这类显示刷新变量”本节介绍另外一种常用的显
示框架,原理“某数值跟上一次对比,如果发生了变化两数值不一样)则自动刷新显示,并及时记录
前值”
本节例程实现的功能如下:用 K1 独立按键模拟开关感应器,K1 独立按键“没有被按下”时是高电平,
单片机识别到这种“高电平”就让 P1.4 所在的 LED 灯发亮;K1 独立按键被按下”时是低电平,单片机识
别到这种“低电平”,就 P1.4 所在的 LED 灯熄灭。
#include "REG52.H"
#define SENSOR_TIME 20 //开关感应器的“滤波”时间
void T0_time();
void SystemInitial(void) ;
void Delay(unsigned long u32DelayTime) ;
void PeripheralInitial(void) ;
void VoiceScan(void);
void SensorScan(void);
void DisplayTask(void); //显示的任务函数(LED 显示状态)
sbit P1_4=P1^4;
sbit Sensor_K1_sr=P2^2; //开关感应器 K1 所在的引脚
volatile unsigned char vGu8Sensor_K1=0; //K1 开关感应器的当前电平状态。
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
DisplayTask(); //显示的任务函数(LED 显示状态)
}
}
/* 注释一:
* 后缀为_Last 这类“对比上一次数值发生变化而自动刷新显示”在“显示框架”里是很常见的,
* 目的是,既能及时刷新显示,又能避免主函数“不断去执行显示代码”而影响程序效率。
*/
void DisplayTask(void) //显示的任务函数(LED 显示状态)
{
// Su8Sensor_K1_Last 初始化取值 255,只要不为 0 或者 1 就行,目的是让上电就发生第一次刷新
static unsigned char Su8Sensor_K1_Last=255; //记录 K1 开关感应器上一次的电平状态。
if(Su8Sensor_K1_Last!=vGu8Sensor_K1) //如果当前值与上一次值不一样,就自动刷新
{
Su8Sensor_K1_Last=vGu8Sensor_K1; //及时记录最新值,避免主函数“不断去执行显示代码”
if(0==vGu8Sensor_K1) //如果当前电平状态为“低电平”LED 熄灭
{
P1_4=1; //LED 熄灭