Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
| products:laboratory_iot:exp36 [2020/05/22 14:06] – [Программный код эксперимента] labuser29 | products:laboratory_iot:exp36 [2024/11/17 16:27] (текущий) – [Программный код эксперимента] labuser30 | ||
|---|---|---|---|
| Строка 12: | Строка 12: | ||
| ==== Прерывания ==== | ==== Прерывания ==== | ||
| - | Оказывается есть отличное решение этой проблемы. Микроконтроллер умеет аппаратно отслеживать изменения состояния выводов. Пока процессор занят чем-то по-настоящему важным за состоянием пинов слежит специальная электронная схема. Как только изменение происходит, | + | Оказывается есть отличное решение этой проблемы. Микроконтроллер умеет аппаратно отслеживать изменения состояния выводов. Пока процессор занят чем-то по-настоящему важным за состоянием пинов следит специальная электронная схема. Как только изменение происходит, |
| // | // | ||
| - | Представь, | + | Представь, |
| ==== Эксперимент ==== | ==== Эксперимент ==== | ||
| - | Попробуем применить прерывания для работы с энкодером. Нам потребуется сделать две вещи — настроить прерывание и написать функцию- обработчик прерывания. | + | Попробуем применить прерывания для работы с энкодером. Нам потребуется сделать две вещи — настроить прерывание и написать функцию-обработчик прерывания. |
| ==== Схема эксперимента ==== | ==== Схема эксперимента ==== | ||
| Строка 31: | Строка 31: | ||
| ==== Программный код эксперимента ==== | ==== Программный код эксперимента ==== | ||
| - | <file python | + | <file python |
| from machine import I2C, Pin | from machine import I2C, Pin | ||
| from esp8266_i2c_lcd import I2cLcd | from esp8266_i2c_lcd import I2cLcd | ||
| Строка 37: | Строка 37: | ||
| _init() | _init() | ||
| - | DEFAULT_I2C_ADDR = 0x3F | + | DEFAULT_I2C_ADDR = 0x3F # Или 0x27 в зависимости от модели микросхемы на плате |
| encA = Pin(13, Pin.IN) | encA = Pin(13, Pin.IN) | ||
| Строка 57: | Строка 57: | ||
| lcd.putstr(str(data)) | lcd.putstr(str(data)) | ||
| - | def callback2(p): | + | def callback(p): |
| global count | global count | ||
| global encB | global encB | ||
| Строка 87: | Строка 87: | ||
| lcd.backlight_on() | lcd.backlight_on() | ||
| - | encA.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING, | + | encA.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, |
| - | encB.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING, | + | encB.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, |
| Строка 95: | Строка 95: | ||
| </ | </ | ||
| - | Сначала настраиваем прерывание: | + | Сначала настраиваем прерывания: |
| - | <code python[enable_line_numbers=" | + | <code python[enable_line_numbers=" |
| - | encA.irq(trigger=Pin.IRQ_FALLING, | + | encA.irq(trigger=Pin.IRQ_FALLING |
| + | encB.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=callback) | ||
| </ | </ | ||
| - | Мы настроили, | + | Мы настроили, |
| Какие могут быть события: | Какие могут быть события: | ||
| Строка 110: | Строка 111: | ||
| События можно комбинировать. Например, | События можно комбинировать. Например, | ||
| - | Рассмотрим функцию- обработчик прерывания: | + | Рассмотрим функцию-обработчик прерывания: |
| - | <code python[enable_line_numbers=" | + | <code python[enable_line_numbers=" |
| def callback(p): | def callback(p): | ||
| global count | global count | ||
| global encB | global encB | ||
| global encA | global encA | ||
| - | | + | |
| + | global old_state | ||
| value_a = encA.value() | value_a = encA.value() | ||
| value_b = encB.value() | value_b = encB.value() | ||
| - | | + | |
| - | print(' | + | |
| - | count += 1 | + | if (current_state - old_state == 1) or (current_state == 0 and old_state == 3): |
| - | | + | |
| - | elif (not value_a and value_b) or (value_a | + | if not (count % 2): |
| - | print(' | + | |
| + | print_lcd(int(count/2)) | ||
| + | old_state = current_state | ||
| + | elif (current_state - old_state == -1) or (current_state == 3 and old_state == 0): | ||
| count -= 1 | count -= 1 | ||
| - | print_lcd(count) | + | |
| + | print(' | ||
| + | | ||
| + | old_state = current_state | ||
| </ | </ | ||
| Она начинается с | Она начинается с | ||
| - | <code python[enable_line_numbers=" | + | <code python[enable_line_numbers=" |
| global count | global count | ||
| global encB | global encB | ||
| global encA | global encA | ||
| + | global states | ||
| + | global old_state | ||
| </ | </ | ||
| - | Ключеваое слово '' | + | Ключевое слово '' |
| + | |||
| + | Потом, как и раньше, | ||
| + | |||
| + | Как мы заметили ранее, при одном щелчке энкодера происходит смена двух состояний энкодера. Чтобы одному щелчку соответствовало изменение счетчика на 1, мы просто проверяем счетчик на четность. | ||
| + | |||
| + | <code python[enable_line_numbers=" | ||
| + | if not (count % 2): | ||
| + | print(' | ||
| + | print_lcd(int(count/ | ||
| + | </ | ||
| + | |||
| + | Если число четное (нет остатка от деления на 2) то пишем в терминал + и выводим число, деленное на 2 на дисплей. | ||
| + | |||
| + | Теперь самое главное. Обратим внимание на основной цикл программы. Мы в нем ничего не делаем. Все действия, | ||
| + | |||
| + | <WRAP center round important 60%> | ||
| + | В этом эксперименте мы производили настройку аппаратных средств микроконтроллера, | ||
| + | </ | ||
| - | Потом, как и раньше, | ||