其实是我一直没有搞明白的一件事请:
问题描述,按键控制蜂鸣器和继电器。但是每当我打开蜂鸣器,继电器总会开,打开继电器,蜂鸣器总会响。蜂鸣器一响,脑子直接晕头转向。我把我的代码贴出来:
void buzz_dis()
{
P0 |= 0x40;
latch(5);
}
void buzz_init()
{
P0 &= 0xbf;
latch(5);
}
void jdq_init()
{
P0 &= 0x7f;
latch(5);
}
void jdq_dis()
{
P0 |= 0x10;
latch(5);
}
///蜂鸣器是P06口控制的,继电器是P04口控制的,我在这里其实也犯错误了,记录下来加深印象
大家有没有发现这个问题所在呢?
问题分析:为什么按位操作在这里不行了呢,既然不是引脚搞错了,那还有什么干扰了程序呢?我思来想去,看着这满满一屏幕的bug,突发奇想,可能是主函数里还有对P0口的操作,果然,我既有数码管显示操作P0还有led显示也操作P0。所以问题的根已经找到了。再细细思考一下,我又发现数码管对P0的操作影响真的有这么大吗?理论上是可能存在这种情况的,但是我这种情况是必然的呢?原来是我每次按键按下还要操作led。这一前一后对P0的操作才造成了这种情况。
问题解决:其实我们放弃按位操作这种方式就可以了。例如:
void buzz_dis()
{
P0 = 0x40;
latch(5);
}
void buzz_init()
{
P0 = 0;
latch(5);
}
void motor_init()
{
P0 = 0;
latch(5);
}
void motor_dis()
{
P0 = 0x10;
latch(5);
}
我们直接对P0赋值,那么相当于每次赋值时还将其他口进行了初始化。但这种方法还有一点缺陷就是两个器件不能同时工作。其实我们还有解决办法,那就是增加一个中间变量,如下:
void buzz_dis()
{
P0_buff |= 0x40;
P0 = P0_buff;
latch(5);
}
void buzz_init()
{
P0_buff &= 0xbf;
P0 = P0_buff;
latch(5);
}
void jdq_init()
{
P0_buff &= 0x7f;
P0 = P0_buff;
latch(5);
}
void jdq_dis()
{
P0_buff|= 0x10;
P0 = P0_buff;
latch(5);
}
这种方法就可以解决这个问题了。
事后反思:其实这个问题挺隐蔽的,如果是考试现场我的个人能力可能不足以让我解决。所以对我和大家都有警醒作用,即使再简单的模块,我们稍微不注意细节逻辑都有可能造成一个功能的缺失。写下这篇文章既为加深印象,也为和各位共勉!
感谢阅读,欢迎三连!!!!!!!
也欢迎观看我的B站主页:
宿管大爷211的个人空间_哔哩哔哩_bilibilihttps://space.bilibili.com/630519178?spm_id_from=333.1007.0.0希望大家多多三连!!!!!!!!!!!!!!!!!!!!!!!