首页 > 解决方案 > 在给定时间内使led变高或变低的逻辑是什么?

问题描述

打开led开关要按2次,关闭led开关要在10秒内按3次?谁能解释一下逻辑如何实现?

我检查了延迟功能中开关的状态,但它不起作用

#include<reg51.h>


void delay_ms(unsigned int );


int count=0;
sbit sw=P2^0;
sbit led=P1^0;
main()
{

    while(1)
    {

    if(sw==0)
    {

     delay_ms(10000);   
    }
}


}
void delay_ms(unsigned int i)
{

    int j;
       for(i;i>0;i--)
         for(j=122;j>0;j--)
        {
                if(sw==0)
                {
                    while(sw==0);
                    count++;
                    if(count==2)
                         led=1;
                    if(count==3)
                         led=0;


                }

             }



}

预期结果 - 按下开关 2 次应打开 LED,按下开关 3 次应关闭 LED(10 秒内)

实际结果 - 按下开关 2 次应打开 LED,按下开关 3 次应关闭 LED(但工作没有任何时间限制)

标签: cembedded8051

解决方案


另一种更灵活的解决方案(在您可能需要同时执行其他工作的应用程序中)是对开关事件进行时间戳并将当前事件时间与之前的时间戳进行比较。

给定一个常规时间源(假设clock()这里是标准,但无论如何逻辑都是有效的):

#include <time.h>
#include <string.h>  // for memset()
#include <stdbool.h>

bool isSwitchEvent()
{
    sbit sw = P2^0 ;
    bit current_sw = sw ;
    static bit previous_sw = sw ;

    // NOTE: Ignoring switch bounce issues - different question

    // Switch event when state *changed* to 1->0...    
    bool switch_event = (current_sw == 0 && previous_sw == 1) ;
    previous_sw = current_sw ;

    return switch_event ;
}

#define SWITCH_PERIOD CLOCKS_PER_SEC * 10
int main()
{
    sbit led = P1^0;

    // Initialise so that first switch event is guaranteed to be at
    // least then 10 seconds later than the initial timestamps.
    clock_t switch_timestamp[3] = {-SWITCH_PERIOD, 
                                   -SWITCH_PERIOD, 
                                   -SWITCH_PERIOD } ;
    unsigned i = 0 ;
    bit led_state = 0 ;
    bool change = false ;

    for(;;)
    {
        // On switch event...
        if( isSwitchEvent() )
        {
            // Timestamp event
            switch_timestamp[i] = clock() ;

            // If LED off, and previous event was less 
            // than 10 seconds ago...
            if( led_state = 0 && 
                switch_timestamp[i] - switch_timestamp[(i+2)%3] < SWITCH_PERIOD )
            {
                // LED on
                led_state = 1 ;
                change = true ;
            }
            // else if LED on, and previous two events were less 
            // than 10 seconds ago...
            else if( led_state = 1 && 
                     switch_timestamp[i] - switch_timestamp[(i+1)%3] < SWITCH_PERIOD )
            {
                // LED off
                led_state = 0 ;
                change = true ;
            }

            // If LED state change...
            if( change )
            {
                // Set output to the prevailing LED state 
                led = led_state ;

                // Make timestamps older that SWITCH_PERIOD so 
                // previous events are not to be counted
                // for next LED state change.
                switch_timestamp[0] = clock() - SWITCH_PERIOD ;
                switch_timestamp[1] = switch_timestamp[0] ;
                switch_timestamp[2] = switch_timestamp[0] ;

                // Next timestamp
                i++ ;
                i %= 3 ;
            }
        }

        // You can do other work here (so long as 
        // it does not take so long as to miss a 
        // switch event).
    }

    return 0 ;
}

推荐阅读