Сирий ввід вивід з відображеної пам'яті (MMIO)
Більшість мікроконтролерів отримують доступ до периферійних пристроїв через відображений в пам’ять IO. Давайте спробуємо включити світлодіод на нашому micro:bit:
#![no_main] #![no_std] extern crate panic_halt as _; mod interrupts; use core::mem::size_of; use cortex_m_rt::entry; /// Периферійна адреса порту GPIO 0 const GPIO_P0: usize = 0x5000_0000; // Зміщення периферії GPIO const PIN_CNF: usize = 0x700; const OUTSET: usize = 0x508; const OUTCLR: usize = 0x50c; // Поля PIN_CNF const DIR_OUTPUT: u32 = 0x1; const INPUT_DISCONNECT: u32 = 0x1 << 1; const PULL_DISABLED: u32 = 0x0 << 2; const DRIVE_S0S1: u32 = 0x0 << 8; const SENSE_DISABLED: u32 = 0x0 << 16; #[entry] fn main() -> ! { // Налаштуйте виводи GPIO 0 21 та 28 як push-pull виводи. let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::<u32>()) as *mut u32; let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::<u32>()) as *mut u32; // БЕЗПЕКА: вказівники вказують на дійсні периферійні регістри // керування, і ніяких псевдонімів не існує. unsafe { pin_cnf_21.write_volatile( DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | SENSE_DISABLED, ); pin_cnf_28.write_volatile( DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | SENSE_DISABLED, ); } // Встановіть низький рівень на виводі 28 і високий на виводі 21, щоб увімкнути світлодіод. let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32; let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32; // БЕЗПЕКА: вказівники вказують на дійсні периферійні регістри // керування, і ніяких псевдонімів не існує. unsafe { gpio0_outclr.write_volatile(1 << 28); gpio0_outset.write_volatile(1 << 21); } loop {} }
- Вивід 21 GPIO 0 підключений до першого стовпчика світлодіодної матриці, а вивід 28 – до першого рядка.
Запустіть приклад за допомогою:
cargo embed --bin mmio