简体   繁体   English

带中断的按钮计数器

[英]Button counter with interrupt

I want to increment a variable every second when an interrupt is triggered.我想在触发中断时每秒增加一个变量。 Code on esp32, esp-idf. esp32 上的代码,esp-idf。 I have connected a button, when the button is pressed I want to count the number of seconds.我已经连接了一个按钮,当按下按钮时,我想计算秒数。

I did this using polling function, but I want to learn how to do it with interrupt, so counting and polling only when the button is pressed and not checking every second for a button pushed.我使用轮询功能做到了这一点,但我想学习如何通过中断来做到这一点,因此仅在按下按钮时进行计数和轮询,而不是每秒检查一次按钮是否按下。

#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

#define ESP_INTR_FLAG_DEFAULT 0

#define BLINK_LED 13
#define GPIO_INPUT_IO_0 33
int buttonCount = 0;
int i = 0;

SemaphoreHandle_t xSemaphore = NULL;

TaskHandle_t printVariableTask = NULL;

void printVariable(void *pvParameter) {

    int a = (int) pvParameter;
    while (1) {

        printf("A is a: %d \n", a++);
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}
// interrupt service routine, called when the button is pressed
void IRAM_ATTR button_isr_handler(void* arg) {

    // notify the button task
    xSemaphoreGiveFromISR(xSemaphore, NULL);

}
// task that will react to button clicks
void button_task(void* arg) {

    // infinite loop
    for(;;) {

        // wait for the notification from the ISR
        if(xSemaphoreTake(xSemaphore,portMAX_DELAY) == pdTRUE) {
            int buttonState = gpio_get_level(GPIO_INPUT_IO_0);

            while(buttonState == 1){ //code stucks here!!!!
                buttonCount++;
                printf("GPIO_INPUT_IO_0 %d\n", buttonState);
                printf("Button pressed! %d \n", i++);
                gpio_set_level(BLINK_LED, buttonState);
                vTaskDelay(1000 / portTICK_RATE_MS);
                }
        }
    }
}

void app_main()
{
    // create the binary semaphore
    xSemaphore = xSemaphoreCreateBinary();

    // configure button and led pins as GPIO pins
    gpio_pad_select_gpio(GPIO_INPUT_IO_0);
    gpio_pad_select_gpio(BLINK_LED);

    // set the correct direction
    gpio_set_direction(GPIO_INPUT_IO_0, GPIO_MODE_INPUT);
    gpio_set_direction(BLINK_LED, GPIO_MODE_OUTPUT);

    // enable interrupt on falling (1->0) edge for button pin
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_POSEDGE);

    // start the task that will handle the button
    xTaskCreate(button_task, "button_task", 2048, NULL, 10, NULL);

    // install ISR service with default configuration
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);

    // attach the interrupt service routine
    gpio_isr_handler_add(GPIO_INPUT_IO_0, button_isr_handler, NULL);

    int pass = 25;
    xTaskCreate(&printVariable, "printVariable", 2048, (void*) pass, 5, &printVariableTask);

}

It works, but when the code enter in the while(buttonState == 1) the loop never ends.它可以工作,但是当代码进入 while(buttonState == 1) 时,循环永远不会结束。

What am I doing wrong?我究竟做错了什么?

not sure if this is still and issue for you but try making a new global variable as a flag and set it to 1 in the interrupt routine when you want to start counting.不确定这对您来说是否仍然存在问题,但尝试将新的全局变量作为标志,并在您想要开始计数时在中断例程中将其设置为 1。 In your loop look for that flag to be set to 1 and start incrementing.在您的循环中查找要设置为 1 的标志并开始递增。 When you detect the button is no longer being pressed set the flag to 0.当您检测到按钮不再被按下时,将标志设置为 0。

Also you're never resetting your button state within the button task while loop.此外,您永远不会在循环时重置按钮任务中的按钮状态。 That's why your Button State is always coming back as 1.这就是为什么您的 Button State 总是返回 1 的原因。

Actually looking at it further I think you might just need to sample your input level level outside of your if statement within the for(;;) loop.实际上进一步研究我认为您可能只需要在 for(;;) 循环中的 if 语句之外对输入级别进行采样。 I think this because (I believe) your if in the button task wont be called on a falling edge?我认为这是因为(我相信)您的 if in the button 任务不会在下降沿被调用?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM