esp32的GPIO操作


對於任何一款芯片,GPIO接口是其最基本的組成部分,也是一款芯片入門的最基本操作,下面論述下 關於esp32開發版的GPIO操作,本文中重點講解下

關於如何創建eclipse工程,並通過eclipse下載到esp32中去(本文的工程文件在esp-idf/example/periheral文件夾中gpio工程),這里就不再詳細論述了,可以看前面的文章,本文重點講解工程源碼,現在講代碼分塊粘貼如下,並進行講解。

本次操作比較簡單,大致可以分為以下幾個部分

PART1;

定義gpio口寄存器及一個空的xQueueHandle類型的返回信號量。

#define GPIO_OUTPUT_IO_0    18
#define GPIO_OUTPUT_IO_1    19
#define GPIO_OUTPUT_PIN_SEL  ((1<<GPIO_OUTPUT_IO_0) | (1<<GPIO_OUTPUT_IO_1)//配置gpioout位寄存器

#define GPIO_INPUT_IO_0 4 #define GPIO_INPUT_IO_1 5 #define GPIO_INPUT_PIN_SEL ((1<<GPIO_INPUT_IO_0) | (1<<GPIO_INPUT_IO_1)) #define ESP_INTR_FLAG_DEFAULT 0  //定義默認的中斷標志為0 static xQueueHandle gpio_evt_queue = NULL;     //定義一個隊列返回變量

 

PART2:

編寫中斷處理函數及信號輸出任務

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
    //xQueueSendFromISR是發生消息插入到隊列的后面,將gpio的io口數傳遞到隊列中,關於xQueueSendFromISR函數的相關知識,可以自己查詢API手冊,本文最后也有相關講解
}

static void gpio_task_example(void* arg)
{
    uint32_t io_num;
    for(;;) {
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            //接受gpio隊列,並在讀取完后刪除隊列
            printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
            //將GPIO的信息打印輸出
        }
    }
}

 

 

 

PART3:

應用主程序

 

 1 void app_main()
 2 {
 3     gpio_config_t io_conf;
 4     //定義一個gpio_config類型的結構體,下面的都算對其進行的配置
 5     //disable interrupt
 6     io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
 7     //set as output mode
 8     io_conf.mode = GPIO_MODE_OUTPUT;
 9     //bit mask of the pins that you want to set,e.g.GPIO18/19
10     io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
11     //disable pull-down mode
12     io_conf.pull_down_en = 0;
13     //disable pull-up mode
14     io_conf.pull_up_en = 0;
15     //configure GPIO with the given settings
16     gpio_config(&io_conf);
17 
18     //interrupt of rising edge
19     io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
20     //bit mask of the pins, use GPIO4/5 here
21     io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
22     //set as input mode    
23     io_conf.mode = GPIO_MODE_INPUT;
24     //enable pull-up mode
25     io_conf.pull_up_en = 1;
26     gpio_config(&io_conf);
27 
28     //change gpio intrrupt type for one pin
29     gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
30 
31     //create a queue to handle gpio event from isr
32     gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
33     //start gpio task
34     xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
35 //
36     //install gpio isr service
37     gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
38     //hook isr handler for specific gpio pin
39     gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
40     //hook isr handler for specific gpio pin
41     gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);
42 
43     //remove isr handler for gpio number.
44     gpio_isr_handler_remove(GPIO_INPUT_IO_0);
45     //hook isr handler for specific gpio pin again
46     gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
47 
48     int cnt = 0;
49     while(1) {
50         printf("cnt: %d\n", cnt++);
51         vTaskDelay(1000 / portTICK_RATE_MS);
52         gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
53         gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
54     }
55 }

 app_main中第三行申明gpio配置的結構體實例,然后在其后對gpio的結構體進行配置,然后開啟一個gpio_task_example的任務處理GPIO4或者GPIO5中斷發來的消息,這里用到FreeRTOS操作系統的消息隊列功能實現中斷函數與用戶任務之間的消息傳遞。

在44,46行中調用函數給 GPIO4和GPIO5管腳添加中斷處理函數,並在最后的while循環中每隔1s切換一次GPIO18、GPIO19的電平值,

 

 

 

實驗現象:

    對於本例子的實驗例子,實驗操作是,將程序燒寫到esp32中后,將GPIO18->GPIO4,GPIO19->GPIO5(—>表示連接),然后打開minicom(任意串口調試軟件),可以看到每隔一秒gpio輸出一次信息。由於app_main中第29行修改了GPIO_INPUT_IO_0為GPIO_INTR_ANYEDGE(即GPIO18的中斷方式,所以,GPIO18的中斷會比19多一次)。實驗輸出如下圖所示:

 

 

 

 

 

 

小TIPS:

   對於不知道的變量,想要找到其定義,選中想要查詢的變量,按下F3即可自動跳轉到其定義處,同理,選中,按F4可以看到此變量或函數被誰調用了。

 

相關知識:

1、esp32函數API:gpio口的函數API

2、FreeRTOS函數API:

以下截圖來自正點原子FreeRTOS開發手冊

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM