ESP8266 Урок 8. GPIO interrupt

 

 

 

С внешними прерываниями на других МК мы уже ранее работали, поэтому, в принципе, нет необходимости объяснять очень подробно, что это такое.

У ESP8266 также имеется механизм обработки внешних прерываний.

Тем не менее повторюсь.

Внешние прерывания — это такие прерывания, которые обрабатываются вследствие возникновения некоторых событий на определённой ножке порта микроконтроллера. Таких событий может быть несколько, не смотря на всего лишь 2 возможных логических состояния ножки.

ESP8266 умеет отслеживать следующие виды событий на ножке порта, судя по данным перечисляемым типам

 

 

Из данных констант видно, что существует 5 видов обрабатываемых событий (не считая DISABLE):

  1. переход из низкого состояния в высокое,
  2. переход из высокого состояния в низкое,
  3. переход из любого состояния в любое,
  4. пребывание ножки в низком состоянии,
  5. пребывание ножки в высоком состоянии.

 

Если посмотреть Technical Reference, то там описаны все типы данных событий (там где рассматриваются биты регистров)

 

 

Для того, чтобы на практике увидеть, как именно работают прерывания, мы подключим кнопку так же, как мы делали в уроке 6, и будем следить за переходом состояния ножки, к которой подключена кнопка, из низкого состояния в высокое. А так как ножка у нас по-прежнему через резистор будет притянута к питанию, а второй контакт кнопки будет подключен к общему проводу, то данный переход мы получим в момент отжатия кнопки, что, кстати, чаще всего и используется в практике.

Как включить и настроить данные прерывания, мы изучим уже на практике.

Схема урока у нас та же что и в уроке 6

 

 

Проект мы сделаем из проекта урока 7 с именем UART_TX и назовём его EXTI01.

Откроем наш проект в Eclipse и в main.c добавим макрос для ножки кнопки

 

 

Добавим переменную для пользовательского флага

 

 

Удалим подключение библиотеки для UART, сегодня он нам не нужен

 

#include "driver/uart.h"

 

В user_init() удалим объявление локальной переменной и удалим инициализацию UART, сегодня он нам не нужен

 

uint16_t i=0;

// Configure the UART

uart_init(BIT_RATE_115200, BIT_RATE_115200);

 

Из бесконечного цикла удалим инкрементирование переменной

 

i++;

if(i>9999) i=1;

 

Также удалим весь вывод информации в UART

 

os_printf("String %04d\r\n", i);

os_printf("SDK version: %s\n", system_get_sdk_version());

os_printf("Version info of boot: %d\n", system_get_boot_version());

os_printf("Userbin address: 0x%x\n", system_get_userbin_addr());

os_printf("Time = %ld\r\n", system_get_time());

os_printf("RTC time = %ld\r\n", system_get_rtc_time());

os_printf("Chip id = 0x%x\r\n", system_get_chip_id());

os_printf("CPU freq = %d MHz\r\n", system_get_cpu_freq());

os_printf("Flash size map = %d\r\n", system_get_flash_size_map());

os_printf("Free heap size = %d\r\n", system_get_free_heap_size());

system_print_meminfo();

 

Задержку уменьшим в 10 раз в обоих местах

 

ets_delay_us(100000);

 

Проинициализируем нулём наш пользовательский флаг

 

 

Включим нашу ножку как обычный GPIO и подтянем на него резистор с шины питания

 

 

Настроим ножку на вход

 

 

Прежде чем производить серьёзные настройки прерываний, сначала их нужно будет отключить

 

 

Теперь нам надо будет добавить функцию обратного вызова, которая будет играть роль обработчика прерывания. Имя функции можно использовать любое, главное чтобы потом при регистрации данной функции внести в параметр то же имя. Добавим такую функцию выше функции user_rf_cal_sector_set

 

 

В теле данной функции сначала возьмём данные из регистра состояния GPIO

 

 

Отключим прерывания GPIO

 

 

 

Если установлен бит, соответствующий нашей ножке, то установим наш пользовательский флаг, если он сброшен, а если установлен, то сбросим, и после этого подождём немного

 

 

С помощью занесения значения регистра состояния в специальный регистр, отвечающий за сброс флагов прерываний GPIO, мы сбросим флаги перерываний, которые были установлены, так как делать это нужно программно

 

 

Также нужно не забыть опять включить прерывания GPIO

 

 

Вернёмся в user_init() и зарегистрируем наш обработчик с помощью специального макроса

 

 

Если после этого мы попытаемся собрать наш код, то мы получим следующую ошибку

 

 

Всё дело в том, что в файле ets_sys.h в вызываемом макросе вызывается функция ets_isr_mask, которая реально существует, но прототипа на неё нигде нет. Видимо, это какие-то недоработки версии SDK. То же самое мы получим и касательно отключения прерываний, там уже нужен прототип функции ets_isr_unmask. Выход из данной ситуации – простое добавление прототипов в файле main.c

 

 

Теперь всё соберётся. А когда это поправят, убрать данные прототипы будет несложно.

Далее в main() мы с помощью специальной функции SDK настроим прерывание на нашу ножку по событию перехода из низкого логического состояния в высокое

 

 

Включим прерывания GPIO

 

 

В бесконечном цикле мы устанавливать нулевой уровень на ножке, к которой подключен светодиод будем только при условии установленного пользовательского флага

 

 

Вот и весь код.

Соберём код, прошьём контроллер.

Теперь у нас светодиоды сразу мигать не будут, для того, чтобы мигалка заработала, надо будет нажать и отжать кнопку

 

 

Если мы повторим данные действия ещё раз, то светодиод мигать перестанет

 

 

Также вы можете попробовать, как будет работать программа при использовании четырёх других событий.

Итак, на данном уроке мы изучили, как работает механизм прерываний от порта GPIO, а также закрепили данные знания на практике.

Всем спасибо за внимание!

 

Предыдущий урок Программирование МК ESP8266 Следующий урок

 

Исходный код

 

 

Модуль ESP NodeMCU можно купить здесь: Модуль ESP NodeMCU

Различные модули ЕSP8266 можно приобрести здесь Модули ЕSP8266

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно приобрести здесь ftdi ft232rl

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

ESP8266 GPIO interrupt

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*