HD44780 tabanlı bir LCD'yi nasıl bağlayabilirim?


13

Bu soruya genişleyen . Bir HD44780'i GPIO pinlerine ve çeşitli takaslara bağlamanın birkaç farklı yolunu arıyorum.

İşte I²C kullanarak bir RPi'den çıkan "dünya saatim " I²C aracılığıyla 3 HD44780 ekran çalıştıran RPi

Şimdiye kadar Adafruit'teki eğiticiye benzer 6 GPIO pini ve MCP23017 kullanan I²C sürümü kullanarak bir çalışmam var

Çalışmak istediğim diğer fikirler:

6 GPIO pin versiyonu basit, ama 6 değerli GPIO pin kullanır
CD4094 versiyonu çok ucuz ve sadece 2 GPIO işaretçilerine ihtiyacı I²C versiyonu biraz sadece daha pahalıdır, ancak tek MCP23017 ile 6 adede kadar ekran çalıştırabilir ve paylaşabilirsiniz I²C diğer cihazlarla

Denemek için başka seçenekler düşünebilir misiniz?


Şuna bir göz atın: schnatterente.net/technik/… Raspberry Pi + HD44780 Ekran için gerçekten harika bir RSS Okuyucu! :)

Yanıtlar:


5

6 GPIO pini

İşte şu anda kullandığım kod. Şimdiye kadar sadece GPIO çalışıyor. test_gpioLCD modülünde hangi GPIO pinlerinin hangi pinlere bağlı olduğunu görmek / değiştirmek için işleve bakın.

import time
import RPi.GPIO as GPIO

class LCD_GPIO(object):
    # Timing constants
    E_PULSE = 0.00005
    E_DELAY = 0.00005
    def __init__(self, RS, E, D4, D5, D6, D7):
        self.RS = RS
        self.E = E
        self.D4 = D4
        self.D5 = D5
        self.D6 = D6
        self.D7 = D7

        GPIO.setmode(GPIO.BCM)        # Use BCM GPIO numbers
        GPIO.setup(self.E, GPIO.OUT)  # E
        GPIO.setup(self.RS, GPIO.OUT) # RS
        GPIO.setup(self.D4, GPIO.OUT) # DB4
        GPIO.setup(self.D5, GPIO.OUT) # DB5
        GPIO.setup(self.D6, GPIO.OUT) # DB6
        GPIO.setup(self.D7, GPIO.OUT) # DB7

    def lcd_byte(self, data, mode):
        GPIO.output(self.RS, mode)

        for bits in (data>>4, data):
            GPIO.output(self.D4, bits&0x01)
            GPIO.output(self.D5, bits&0x02)
            GPIO.output(self.D6, bits&0x04)
            GPIO.output(self.D7, bits&0x08)

            # Toggle E
            time.sleep(self.E_DELAY)
            GPIO.output(self.E, True)
            time.sleep(self.E_PULSE)
            GPIO.output(self.E, False)
            time.sleep(self.E_DELAY)


class LCD_23017(object):
    pass

class LCD_4094(object):
    pass    

class HD47780(object):
    LCD_CHR = True
    LCD_CMD = False
    # Base addresses for lines on a 20x4 display
    LCD_BASE = 0x80, 0xC0, 0x94, 0xD4

    def __init__(self, driver, rows=2, width=16):
        self.rows = rows
        self.width = width
        self.driver = driver
        self.lcd_init()

    def lcd_init(self):
        # Initialise display
        lcd_byte = self.driver.lcd_byte
        for i in 0x33, 0x32, 0x28, 0x0C, 0x06, 0x01:
            lcd_byte(i, self.LCD_CMD)


    def lcd_string(self, message):
        # Send string to display
        lcd_byte = self.driver.lcd_byte
        lcd_byte(self.LCD_BASE[0], self.LCD_CMD)
        for i in bytearray(message.ljust(self.width)):
            lcd_byte(i, self.LCD_CHR)

def test_gpio():
    driver = LCD_GPIO(RS=7, E=8, D4=25, D5=24, D6=23, D7=18)
    lcd = HD47780(driver=driver, rows=4, width=20)
    lcd.lcd_string("Welcome gnibbler")


def main():
    test_gpio()

if __name__ == "__main__":
    main()

5

I²C

Bağlamak oldukça basittir. Kontrast pimi (V O İhtiyaçlarım kullanıyorum, özellikle ekranlar) zemine bağlanmalıdır. Genellikle V SS ve V CC arasındaki voltajı ayarlamak için bir potansiyometreye bağlarsınız

Ekranlarımın arka ışığı yok, bu yüzden şematikteki dağınıklığı azaltmak için bunları bağlamamıştım. Sizinkinin bir arka ışığı varsa, elbette normal şekilde bağlamanız gerekir

MCP23017'nin her bağlantı noktasına paralel olarak en fazla 3 ekran bağlayabilirsiniz. Tek fark, her ekranın etkinleştirme piminin ayrı bir pime (GPB1-GPB3) bağlanması gerektiğidir.

Raspberry Pi sürüş MCP23017 üzerinden HD44780

#!/usr/bin/env python
"""World Clock Demo
   It should be fairly obvious how to change this code to work for other timezones"""
import time

class LCD_23017(object):
    # Timing constants
    E_PULSE = 0.00005
    E_DELAY = 0.00005
    def __init__(self, bus, addr, port, rs, en):
        self.bus = bus
        self.addr = addr
        self.rs = rs
        self.en = en

        self.DIRECTION = 0x00 if port == 'A' else 0x01
        self.DATA = 0x12 if port == 'A' else 0x13

        self.bus.write_byte_data(addr, self.DIRECTION, 0x00)

    def lcd_byte(self, data, rs):
        rs <<= self.rs
        en = 1 << self.en
        for nybble in (data&0xf0, data<<4):
            self.bus.write_byte_data(self.addr, self.DATA, nybble | rs)
            time.sleep(self.E_DELAY)
            self.bus.write_byte_data(self.addr, self.DATA, nybble | rs | en)
            time.sleep(self.E_PULSE)
            self.bus.write_byte_data(self.addr, self.DATA, nybble | rs)


class HD47780(object):
    LCD_CHR = True
    LCD_CMD = False
    # Base addresses for lines on a 20x4 display
    LCD_BASE = 0x80, 0xC0, 0x94, 0xD4

    def __init__(self, driver, rows=2, width=16):
        self.rows = rows
        self.width = width
        self.driver = driver
        self.lcd_init()

    def lcd_init(self):
        # Initialise display
        lcd_byte = self.driver.lcd_byte
        for i in 0x33, 0x32, 0x28, 0x0C, 0x06, 0x01:
            lcd_byte(i, self.LCD_CMD)

    def lcd_string(self, message, line=0):
        # Send string to display
        lcd_byte = self.driver.lcd_byte
        lcd_byte(self.LCD_BASE[line], self.LCD_CMD)
        for i in bytearray(message.ljust(self.width)):
            lcd_byte(i, self.LCD_CHR)


def test_i2c():
    from datetime import datetime
    import pytz
    import smbus

    ## For Rev1.0 Raspberry Pi
    driver1 = LCD_23017(bus=smbus.SMBus(0), addr=0x27, port='B', rs=0, en=1)
    driver2 = LCD_23017(bus=smbus.SMBus(0), addr=0x27, port='B', rs=0, en=2)
    driver3 = LCD_23017(bus=smbus.SMBus(0), addr=0x27, port='B', rs=0, en=3)

    ## For Rev2.0 Raspberry Pi
    #driver1 = LCD_23017(bus=smbus.SMBus(1), addr=0x27, port='B', rs=0, en=1)
    #driver2 = LCD_23017(bus=smbus.SMBus(1), addr=0x27, port='B', rs=0, en=2)
    #driver3 = LCD_23017(bus=smbus.SMBus(1), addr=0x27, port='B', rs=0, en=3)


    lcd1 = HD47780(driver=driver1, rows=2, width=16)
    lcd2 = HD47780(driver=driver2, rows=2, width=16)
    lcd3 = HD47780(driver=driver3, rows=2, width=16)
    lcd1.lcd_string("    New York")
    lcd2.lcd_string("     London")
    lcd3.lcd_string("    Melbourne")
    new_york_tz = pytz.timezone("America/New_York")
    london_tz = pytz.timezone("Europe/London")
    melbourne_tz = pytz.timezone("Australia/Melbourne")
    while True:
        time.sleep(1-time.time()%1)  # Wait until the next second
        lcd1.lcd_string(datetime.now(new_york_tz).ctime()[3:], line=1)
        lcd2.lcd_string(datetime.now(london_tz).ctime()[3:], line=1)
        lcd3.lcd_string(datetime.now(melbourne_tz).ctime()[3:], line=1)

def main():
    test_i2c()

if __name__ == "__main__":
    main()

Teşekkürler. İşe yarıyor!. Bu harika gönderi bana çok yardımcı oluyor. Yeni başlayanlar için sadece bir yorum (benim gibi). Bir Raspberry Rev.2 kullanıyorsanız, kodda bus = smbus.SMBus (0) yerine bus = smbus.SMBus (1) kullanın. Adres şu komutu çalıştırarak belirlenebilir: "sudo i2cdetect -y 1" (Raspberry Rev.1 için 0 yerine 1 kullanın). Benim durumumda 0x27 yerine 0x20 idi. Çok teşekkürler.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.