Какова логика для того, чтобы сделать высокий или низкий уровень за заданное время? - PullRequest
0 голосов
/ 10 октября 2019

Чтобы включить светодиод, нужно нажать кнопку выключателя 2 раза, выключить светодиод, который нужно нажимать выключатель 3 раза в течение 10 секунд. Кто-нибудь может объяснить логику, как это реализовать?

Я проверил состояние переключателя в функции задержки, но он не работает

#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 раза должно включить светодиод, а нажатие выключателя 3 раза - выключение светодиода (в течение 10 секунд)

фактический результат - нажатие кнопки 2 раза должно включить светодиод, а нажатие кнопки 3 раза должно привести к отключению светодиода (но работает без ограничения по времени)

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Альтернативное и более гибкое решение (в приложении, где вам может потребоваться выполнять другую работу одновременно), состоит в том, чтобы пометить меткой времени события переключения и сравнить текущее время события с предыдущими метками времени.

При условии регулярногоисточник времени (при условии, что здесь стандарт 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 ;
}
0 голосов
/ 10 октября 2019

Проблема заключается в том, что вы не предоставляете никакой дебат для вашего коммутатора. Кроме того, где count инициализируется? Я не вижу этого.

Вам нужно иметь задержку, когда вы обнаружите, что переключатель замкнут, потому что он будет «подпрыгивать» разомкнутым и замкнутым много раз за первые несколько миллисекунд. Я бы задержал минимум на 10 мс, прежде чем проверять, был ли выключатель открыт, а затем вы можете изменить count.

ОБНОВЛЕНИЕ НА ОСНОВАНИИ OP-КОММЕНТАРИЙ:

Ну, опять же, это будет только работать в симуляции. Переключатели не так хороши. Но я вижу вашу проблему: вы не сбрасываете count в вашем main(). Попробуйте:

    main()
        {
        while(1)
           {
           count = 0;
           if(sw==0)
               {
               delay_ms(10000);   
               }
           } 
        }
...