Làm cách nào để kết nối LCD dựa trên HD44780?


13

Mở rộng về câu hỏi này . Tôi đang xem xét một vài cách khác nhau để kết nối HD44780 với các chân GPIO và các sự đánh đổi khác nhau.

Đây là "đồng hồ thế giới" của tôi chạy hết RPi bằng I²C RPi chạy 3 màn hình HD44780 qua I²C

Cho đến nay tôi chỉ có một hoạt động bằng cách sử dụng 6 chân GPIO tương tự như hướng dẫn tại Adafbean và phiên bản I²C sử dụng MCP23017

Những ý tưởng khác tôi muốn làm việc là:

Các phiên bản 6 GPIO pin rất đơn giản, nhưng sử dụng 6 có giá trị GPIO ghim
phiên bản CD4094 là rất rẻ và chỉ cần 2 chân GPIO
các phiên bản I ² C chỉ là hơi đắt hơn, nhưng có thể chạy lên đến 6 màn hình với một MCP23017 độc thân và chia sẻ I ² C với các thiết bị khác

Bất cứ ai có thể nghĩ về các lựa chọn khác để thử?


Hãy xem cái này: schnatterente.net/technik/ Từ Đó là một trình đọc RSS tuyệt vời thực sự cho màn hình Raspberry Pi + HD44780! :)

Câu trả lời:


5

6 chân GPIO

Đây là mã tôi hiện đang sử dụng. Cho đến nay GPIO chỉ hoạt động. Nhìn vào test_gpiochức năng để xem / thay đổi chân GPIO nào được kết nối với chân nào trên mô-đun LCD.

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

Móc nó lên là khá đơn giản. Pin tương phản (V O ) của màn hình cụ thể tôi đang sử dụng cần được kết nối với mặt đất. Thông thường, bạn sẽ kết nối nó với một chiết áp để đặt điện áp giữa V SS và V CC

Màn hình của tôi không có đèn nền, vì vậy tôi đã không kết nối chúng để giảm sự lộn xộn trên sơ đồ. Nếu đèn của bạn có đèn nền, dĩ nhiên bạn nên kết nối nó theo cách thông thường

Bạn có thể kết nối tối đa 3 màn hình song song với mỗi cổng của MCP23017. Sự khác biệt duy nhất là pin cho phép từ mỗi màn hình cần kết nối với một pin riêng (GPB1-GPB3)

Raspberry Pi lái HD44780 qua MCP23017

#!/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()

Cảm ơn. Nó hoạt động!. Bài đăng tuyệt vời này giúp tôi rất nhiều. Chỉ một nhận xét cho người mới (như tôi). Nếu bạn sử dụng Raspberry Rev.2, hãy sử dụng bus = smbus.SMBus (1) thay vì bus = smbus.SMBus (0) trong mã. Địa chỉ có thể được xác định bằng cách chạy lệnh này: "sudo i2cdetect -y 1" (sử dụng 0 thay vì 1 cho Raspberry Rev.1). Trong trường hợp của tôi là 0x20 thay vì 0x27. Cảm ơn rất nhiều.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.