Add the STN 16x2 screen display driver
parent
5098e7b453
commit
e6974cffb2
|
@ -10,6 +10,7 @@ sha1_smol = "1.0.0"
|
|||
binascii = { version = "0.1", default-features = false, features = ["decode"] }
|
||||
ds323x = "0.5.0"
|
||||
ufmt = "0.2.0"
|
||||
embedded-hal = "0.2.7"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
use arduino_hal::delay_ms;
|
||||
use arduino_hal::delay_us;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
|
||||
const INIT_CMD: u8 = 0x03; // 0b00000011
|
||||
const MODE_4_BITS_CMD: u8 = 0x02; // 0b00000010
|
||||
const DISPLAY_MODE_CMD: u8 = 0x28; // 0b00101000
|
||||
const ENABLE_SCREEN_CMD: u8 = 0x0C; // 0b00001100
|
||||
const CLEAN_SCREEN_CMD: u8 = 0x01; // 0b00000001
|
||||
|
||||
pub struct StnScreen<'a, RS, EN, D4, D5, D6, D7> {
|
||||
rs: &'a mut RS,
|
||||
en: &'a mut EN,
|
||||
d4: &'a mut D4,
|
||||
d5: &'a mut D5,
|
||||
d6: &'a mut D6,
|
||||
d7: &'a mut D7,
|
||||
}
|
||||
|
||||
impl<
|
||||
'a,
|
||||
RS: OutputPin,
|
||||
EN: OutputPin,
|
||||
D4: OutputPin,
|
||||
D5: OutputPin,
|
||||
D6: OutputPin,
|
||||
D7: OutputPin,
|
||||
> StnScreen<'a, RS, EN, D4, D5, D6, D7>
|
||||
{
|
||||
pub fn new(
|
||||
rs: &'a mut RS,
|
||||
en: &'a mut EN,
|
||||
d4: &'a mut D4,
|
||||
d5: &'a mut D5,
|
||||
d6: &'a mut D6,
|
||||
d7: &'a mut D7,
|
||||
) -> Self {
|
||||
let mut display = StnScreen {
|
||||
rs,
|
||||
en,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
};
|
||||
|
||||
// Initializing of LCM on page 16
|
||||
// https://z3d9b7u8.stackpathcdn.com/pdf-down/L/C/D/LCD-1602A_CA.pdf
|
||||
delay_ms(16);
|
||||
display.write_nibble(INIT_CMD, false);
|
||||
delay_ms(5);
|
||||
display.write_nibble(INIT_CMD, false);
|
||||
delay_us(100);
|
||||
display.write_nibble(INIT_CMD, false);
|
||||
delay_us(100);
|
||||
display.write_nibble(MODE_4_BITS_CMD, false);
|
||||
delay_us(100);
|
||||
display.send_cmd(DISPLAY_MODE_CMD, false);
|
||||
display.send_cmd(ENABLE_SCREEN_CMD, false);
|
||||
|
||||
display
|
||||
}
|
||||
|
||||
fn pulse_enable(&mut self) {
|
||||
self.en.set_low().ok();
|
||||
delay_us(1);
|
||||
self.en.set_high().ok();
|
||||
delay_us(1);
|
||||
self.en.set_low().ok();
|
||||
delay_us(100);
|
||||
}
|
||||
|
||||
fn send_cmd(&mut self, cmd: u8, is_data: bool) {
|
||||
self.write_nibble((cmd >> 4) & 0x0F, is_data);
|
||||
self.write_nibble(cmd & 0x0F, is_data);
|
||||
delay_ms(10);
|
||||
}
|
||||
|
||||
fn write_nibble(&mut self, nibble: u8, is_data: bool) {
|
||||
self.rs.set_state(is_data.into()).ok();
|
||||
self.d4.set_state(last_bit(nibble >> 0).into()).ok();
|
||||
self.d5.set_state(last_bit(nibble >> 1).into()).ok();
|
||||
self.d6.set_state(last_bit(nibble >> 2).into()).ok();
|
||||
self.d7.set_state(last_bit(nibble >> 3).into()).ok();
|
||||
self.pulse_enable();
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
display.send_cmd(CLEAN_SCREEN_CMD, false);
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, c: char) {
|
||||
let c = c as u8;
|
||||
self.write_nibble((c >> 4) & 0x0F, true);
|
||||
self.write_nibble(c & 0x0F, true);
|
||||
delay_us(100);
|
||||
}
|
||||
|
||||
pub fn write_str<S: AsRef<str>>(&mut self, s: S) {
|
||||
let s = s.as_ref();
|
||||
for c in s.chars() {
|
||||
self.write_char(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn last_bit(n: u8) -> bool {
|
||||
(n & 1) != 0
|
||||
}
|
Loading…
Reference in New Issue