需求分析
在上一篇博客中,实现了能识别周围光线强度变化(主要判别标准是光敏电阻前有无遮挡物)并利用传感器do口输出值,通过oled显示屏给出当前光线情况。
那么很自然的想法是,对于光敏传感器来说,如果能计下其do口电平变化次数,岂非可以读出光敏电阻被遮挡次数,进而实现“计数”功能?
为了实现该需求,我们做如下尝试
编写代码
第一次尝试
int main(){
lit_init();
OLED_Init();
int a=0;
int b=0;
while(1){
if(get_lit()==0){
OLED_ShowString(1,1,"enoughlit");
OLED_ShowNum(2,1,a,6);
}
if(get_lit()==1){
OLED_ShowString(1,1,"nolit");
a++;
OLED_ShowNum(2,1,a,6);
}}}
这里引入一个变量a对当get_lit返回数值为1时,a=a+1,即实现当光敏电阻被遮挡时,计数加一功能,那么实际运行代码,烧录进stm32中却发现,当光线充足时,计数值为0,当光敏电阻被遮挡时,计数值从000000一直增长000001,000002...,重新分析代码,在while循环中,执行if判别,当get_lit()=1时,执行一遍对应代码,后重新进入循环,执行if判别,故可知当光敏传感器被遮挡时,始终执行循环体内第二个if判别式中内容,故出现计数值一直增长情况
第二次尝试
int main(){
lit_init();
OLED_Init();
int a=0;
int b=0;
while(1){
if(get_lit()==0){
OLED_ShowString(1,1,"enoughlit");
OLED_ShowNum(2,1,b,6);
b=a+1;}
if(get_lit()==1){
OLED_ShowString(1,1,"nolit");
a++;
OLED_ShowNum(2,1,a,6);
a=b;
}}}
第二次尝试中,吸取第一次的教训,为了不使得计数变量在被遮挡时一直增长,引入另一个中间变量b,b的功能是在每一次第二个if判别式执行末尾时,对a进行复位,这样即使遮挡,如果第一次循环中a=2,b=2,那么第二次循环,执行到a++语句时,a=3,再到后面a=b,使得a复位为b,那么b值应该为一次循环后a的值,很容易想到在另一个if判别中对b进行赋值,赋值为b=a+1,如此可实现相应功能
总结
在两次尝试中,第一次想到要使用变量进行计数,第二次对计数过程进行优化改进,使得计数更贴合使用实际。但总而言之,为了实现计数,我们引入了两个多余的变量,增加了程序额外的负担,并且嵌套在if判别式中的重复调用,在代码理解上也是人为增加了一些难度,下一篇博客尝试引入stm32的中断概念,利用EXTI外部中断,更为简洁地实现对端口电平变化的检测与计数