【问题标题】:How often/when does C execute content within if/else statements?C 在 if/else 语句中执行内容的频率/时间?
【发布时间】:2016-05-31 15:03:38
【问题描述】:

我正在做一个嵌入式 (avr) 项目,基本上我想根据一个大头针被按下的时间打印出一些不同的东西。我无法弄清楚当值通过时会发生什么并满足沿途的 if 语句(按钮仍被按下,因此计数器递增)。

设置如下:

如果溢出在 7-48 之间(按钮按下 30ms-200ms),打印出一个 '.'
如果溢出大于 48(按钮按下超过 200 毫秒),打印出一个 '-'
如果溢出大于 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++;
    }
}

我不确定这是否正确,因为似乎在“-”之前总会有一个“.”,因为随着溢出值的增加,它满足

有什么想法吗?

【问题讨论】:

  • 您是在进行一次测量,将其存储在某处,然后对该值进行逻辑处理吗?还是每次问if时都在重新测量?
  • 基本上,当我按下按钮时,它会检测到边缘。只要我按住那个按钮,它就会开始计数。这是一个莫尔斯电码检测器,所以我不想每次按住按钮足够长的时间以获得“-”时打印出“.-”。
  • 按钮也会弹跳。当你按下它时,你会得到不止一个你正在检测的边缘。弹跳很快,但微控制器更快,因此它会多次拾取。您可能必须解除按钮的抖动才能执行您想做的事情。
  • 好吧,我的问题与 C 如何在 if 语句中执行事物有关。就像我会按住按钮一段时间并希望它在超过 200 毫秒(49 次溢出)时打印出一个“-”,我不希望它也打印出一个“。”因为显然它必须保持在 30-200ms 之间(7-49 溢出)。忽略“溢出”的事情,这与我的时钟速度和计时器大小有关。
  • 不要发布伪代码,发布您的实际代码,并提供有关预期和实际行为的信息。

标签: c embedded avr atmega


【解决方案1】:

如果你想计算按下开关的次数,你可以使用 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 循环,您可以避免多次按下开关。如果你做一个开关,计数会加一。

【讨论】:

  • if(count7)&&(count = 49)传输('-'); void transmit(unsigned char b)//此函数用于LCD显示字符{ P1 = a;//端口rs = 1; //rs=0 表示命令,rs=1 表示数据 rw = 0;恩 = 1;延迟();恩 = 0; }
  • ....那么debouncing....呢?
  • 手动制作即可。开关与引脚相连。当您按下开关并释放它时,计数将增加一
【解决方案2】:

我不确定这是否正确,因为似乎总会有一个“。”在'-'之前,因为作为溢出 值递增,满足

但测试仅在上升沿执行 - 当 type == 'e'(TCCR1B &amp; 0x40) != 0 时。因此,overflow 计数仅在释放按钮时计算,因此您不会在- 之前看到中间的.

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

【讨论】:

    【解决方案3】:

    根据您的描述,我假设您的引脚上有一个按钮,因此在这种情况下,我建议在做任何事情之前首先为按钮信号实现去抖动。 我会像这样解决问题:

    #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 &amp; BUTTON_MASK) != 0; 以便读取您的引脚状态,并更改缓冲区的声明以满足您的需要 unsigned char buffer[255];

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

    希望这会有所帮助!

    如果你真的坚持你的解决方案,那么为了避免你遇到的问题是不要连续评估溢出值,不要试图确定按钮按下的长度,而是尝试测量长度推,然后评估它并将字符放入缓冲区。您需要等待“释放按钮”,然后评估按下按钮的时间。像这样的:

    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++;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2020-03-20
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      相关资源
      最近更新 更多