C在if / else语句中执行内容的频率/时间是多少?

时间:2016-02-19 06:17:29

标签: c embedded avr atmega

我正在开发一个嵌入式(avr)项目,基本上我想根据引脚被按下多长时间打印出一些不同的东西。我无法弄清楚当值通过时会发生什么,并且在整个过程中满足if语句(按钮仍被按下以便计数器递增)。

设置如下:

  

如果溢出在7-48之间(按下按钮30ms-200ms),则打印出'。'   如果溢出大于48(按下按钮超过200ms),则打印出' - '
  如果溢出大于97(超过400毫秒未按下按钮),则打印出''

我目前的代码如下:

static inline void isr(char type) {
static unsigned int overflows = 0;
static unsigned char idx = 0;
if (type == 'e') { // edge captured
    if (TCCR1B & 0x40) { // rising edge
        if (overflows < 7) {
            // do nothing
        } else if (overflows < 49) {
            buffer[idx++] = '.';
            size++;
        } else {
            buffer[idx++] = '-';
            size++;
        }
    }
    overflows = 0; // restart counting overflows at each edge
} else { // overflow occured
    overflows++;
    if (buffer[idx-1] != ' ' && !(TCCR1B & 0x40) && overflows > 97) {
        buffer[idx++] = ' ';
        size++;
    }
}

我不确定这是否正确,因为看起来在'.'之前总会有一个'-',因为当溢出值递增时,它满足&lt; 49条件。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

如果你想计算no.of次按开关,你可以使用while循环。  例如,

    if(sw==0) //sw is switch connected with I/O pin
    {
      while(sw==0)
      {
       led=1; //LED is output
       delay(); // use delay function
       led=0;
       delay();
       count++;
       }
     }

通过使用while循环,可以避免多次按下开关。如果你打开一个开关,计数将增加一个。

答案 1 :(得分:0)

  

我不确定这是否正确,因为看起来总会有'。'在' - '之前,因为溢出   值递增,满足&lt; 49条件。

但测试仅在上升沿执行 - 同时type == 'e'(TCCR1B & 0x40) != 0。因此,overflow计数仅在按钮发布时进行评估,因此您不会在.之前看到中间-

因此,为了回答您的问题,条件为真时执行条件语句或块。这里有嵌套条件,因此所有前面的条件必须为true才能评估内部条件。

答案 2 :(得分:0)

根据你的描述,我假设你的针上有一个按钮,所以在这种情况下,在做任何事情之前我首先建议的是对按钮信号实施去抖动。 我会解决这样的问题:

#define BUTTON_UNKNOWN  0
#define BUTTON_DOWN     1
#define BUTTON_UP       2

#define FALSE           0
#define TRUE            1

static inline unsigned char debounce( unsigned char current_state)
{
static unsigned char ret_value;
unsigned char state_changed = FALSE;
// Counter for number of equal states
static unsigned char count = 0;
// Keeps track of current (de-bounced) state
static unsigned char button_state = 0;
// Check if button is high or low for the moment
if (current_state != button_state) 
{
    // Button state is about to be changed, increase counter
    count++;
    if (count >= 3) 
        {
        // The button have not bounced for four checks, change state
        button_state = current_state;
        // If the button was pressed (not released), tell main so
        count = 0;
        state_changed = TRUE;
        }
} 
else 
{
state_changed = FALSE;
// Reset counter
count = 0;
}

//if butten press or release detected
if (state_changed == TRUE)
{
    //check for the current state of the button
    if (current_state != 0) 
        {
        ret_value = BUTTON_DOWN;
        }
    else
        {
        ret_value = BUTTON_UP;
        }
}

return ret_value;
}

int main(void)
{
//perform proper initialization of your pin

unsigned char button = BUTTON_UNKNOWN;    
unsigned char cycle_count  = 0;
unsigned char idx = 0;
unsigned char buffer[255];
unsigned char current_state;
unsigned char no_activity;
//unsigned char current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;

while(1)
{
//read the button state
current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;
// Update button_state
button = debounce(current_state);
// Check if the button is pressed.
if (button == BUTTON_DOWN)
{
    //count cycles in which the button was pressed
    //one cycle is 10 ms - see delay below
    cycle_count++;
}
else
{
    //check if the button was pressed before
    if ((button != BUTTON_UNKNOWN) && (cycle_count != 0))
    {
        //if button was pressed for 200ms
        if (cycle_count <= 20)
        {
            buffer[idx] = '.';
            idx++;            
        }
        else
        {
            //if the button was pressed between 200 and 400 ms
            if ((cycle_count > 20) && (cycle_count <= 40))
            {
               buffer[idx] = '-';
               idx++;
            }
            //the button was pressed for more than 400ms, uncomment if you need it

            /*else
            {
               buffer[idx] = ' ';
               idx++;
            }*/

        }
        //reset counting mechanism
        cycle_count = 0;
        no_activity = 0; 
    }
    else
    {
        no_activity++;
        if (no_activity >= 40)
        {
            buffer[idx] = ' ';
            idx++;
            no_activity = 0;
        }
    }
}

// Delay for a while so we don’t check to button too often
_delay_ms(10);
}
}

您可以根据需要调整此代码: 更改行current_state = (~BUTTON_PIN & BUTTON_MASK) != 0;以便读取您的pin状态,并更改缓冲区的声明以满足您的需求unsigned char buffer[255];

请注意,由于去抖,所测量的时间不是200毫秒(它是200毫秒+ 2 *去抖时间= 260毫秒(去抖时间是3个周期,每个周期是10毫秒,见最后的延迟),但你可以补偿通过最终减少cycle_count比较中的含量来解决这些错误。

希望这有帮助!

如果你真的坚持你的解决方案,那么为了避免问题你所经历的是不连续评估溢出值,不要试图确定按钮按下的长度,而是尝试测量长度推送和之后评估它并将char放入缓冲区。你需要等待发布按钮&#39;然后评估按下按钮的时间。像这样:

static inline void isr(char type) {
static unsigned int overflows = 0;
static unsigned char idx = 0;
unsiged char button_status;

if (type == 'e') { // edge captured
    if (TCCR1B & 0x40) { // rising edge
        //perform a debounce otherwise wont be good
        button_status = 1;

    }
    overflows = 0; // restart counting overflows at each edge
} else { // overflow occured  
    overflows++;
     //if button was pressed and its now released evaluate result
    if (!(TCCR1B & 0x40) && (button_status == 1))
    {
        if (overflows < 7) {
            // do nothing
        } else if (overflows < 49) {
            buffer[idx++] = '.';
            size++;
        } else {
            buffer[idx++] = '-';
            size++;
        }
        button_status = 0;
    }
    if (buffer[idx-1] != ' ' && !(TCCR1B & 0x40) && overflows > 97) {
        buffer[idx++] = ' ';
        size++;
    }
}