Опрос
Теперь, когда мы научились читать входы GPIO, подумаем, как это можно применить на практике. Допустим, мы хотим, чтобы программа включала светодиод при нажатии Button A и выключала его при нажатии Button B. Это можно сделать, опрашивая состояние обеих кнопок в цикле и реагируя, когда одна из них оказывается нажатой. Вот как мог бы выглядеть такой код:
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use embedded_hal::digital::{InputPin, OutputPin};
use microbit::hal::timer::Timer;
use microbit::{hal::gpio, Board};
use panic_rtt_target as _;
use rtt_target::rtt_init_print;
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = Board::take().unwrap();
let mut timer = Timer::new(board.TIMER0);
// Настраиваем кнопки
let mut button_a = board.buttons.button_a;
let mut button_b = board.buttons.button_b;
// Настраиваем светодиод (верхний левый, row1, col1)
let mut row1 = board
.display_pins
.row1
.into_push_pull_output(gpio::Level::Low);
let _col1 = board
.display_pins
.col1
.into_push_pull_output(gpio::Level::Low);
loop {
let on_pressed = button_a.is_low().unwrap();
let off_pressed = button_b.is_low().unwrap();
match (on_pressed, off_pressed) {
// Сохраняем текущее состояние, пока ничего не нажато.
(false, false) => (),
// Переходим во включённое состояние.
(true, false) => row1.set_high().unwrap(),
// Переходим в выключенное состояние.
(false, true) => row1.set_low().unwrap(),
// Сохраняем текущее состояние, пока что-нибудь не отпустят.
(true, true) => (),
}
timer.delay_ms(10_u32);
}
}
Такой способ — многократно проверять входы в цикле — называется опросом (polling). Когда мы проверяем состояние какого-либо входа, говорим, что опрашиваем этот вход. В данном случае мы опрашиваем и Button A, и Button B.
Опрос прост, но позволяет делать интересные вещи, основанные на внешнем мире. Для всех входов устройства мы можем по очереди «опрашивать» их в цикле и каким-то образом реагировать на результат. Этот метод очень прост концептуально и хорошо подходит как отправная точка для многих проектов. Вскоре мы увидим, почему опрос может не быть лучшим методом для всех (или даже большинства) случаев, но сначала попробуем его в деле.
Примечание. Слово «опрос» (polling) используется на двух уровнях детализации. На одном уровне «опрос» означает однократный запрос состояния входа. На более высоком уровне «опрос», или «опрос в цикле», означает многократный запрос состояния входа в простом потоке управления, таком как показанный выше. Такое употребление слова для обозначения потока управления встречается только в самых простых программах и редко применяется в реальных проектах (как мы вскоре увидим, это непрактично). Поэтому, когда инженеры встраиваемых систем говорят об опросе, обычно имеют в виду первое: однократный запрос состояния входа.