Blog (442)
Komentarze (5k)
Recenzje (0)
@wojtekadamsMalinowy wyświetlacz, a polske szlaczki

Malinowy wyświetlacz, a polske szlaczki

19.03.2013 20:52, aktualizacja: 08.09.2014 15:18

Ostatni mój wpis na temat małżeństwa Raspberry Pi z LCD Hitachi HD44780 został przyjęty z entuzjazmem, dlatego idąc jednocześnie za ciosem i prośbą niezalogowanego czytelnika @mielu007 pokusiłem się o sprawdzenie, czy na owym HD44780 możemy wyświetlić polskie znaki? Odpowiedź była prosta - na pewno się da, tylko jak?

Aby to zrobić musiałem troszeczkę zmodyfikować kod, który zamieściłem w poprzednim wypisie, ale na początek trochę teorii...

Teoria

Wyświetlacz HD44780 w swojej tablicy znaków nie posiada polskich liter, ale daje nam możliwość zdefiniowania 8 własnych znaków (8 wolnych bajtów w tablicy), które później musimy załadować do pamięci CGRAM. Ktoś zaraz powie... tylko osiem, ale lipa! otóż Panie/Panowie tak nie jest, wgrywać nowe znaki możemy na bieżąco (dynamicznie), ale sęk w tym że jednocześnie możemy korzystać tylko z tych 8 zdefiniowanych.

Tyle teorii wystarczy ;)

Wykonie - definicja własnych znaków

Jak już pisałem wcześniej matryca tych znaków zapisywana jest w pamięci CGRAM o rozmiarze 8×8 bajtów. Jeden bajt definiuje jedną linię znaku. Osiem następnych bajtów definiuje cały znak - kolejność od góry. Do zaprojektowania swoich znaków użyłem programu "HD44780 – Generator własnych znaków " z strony bastek79.com, dzięki któremu namazałem 4 literki z ogonkami: ą, ę, ł, ó.

0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x04, 0x06
0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x04, 0x06

[join][img=33][join][img=44]

W moim przypadku interesuje mnie zapis heksadecymalny, bo takiego użyłem w swoim programie.

Wykonie - trochę węża

Poniżej znajdziecie mój kod rozszerzony o opisywaną funkcjonalność (zwrócie uwagę na komentarze):


#!/usr/bin/python
# definicja kodowania znakow
#-*- coding: utf-8 -*-

#Importujemy zainstalowana wczesniej biblioteke i biblioteke time
import RPi.GPIO as GPIO
import time

#Prze mapowanie pinow RPi na zmienne odpowiadajace nazwą pinow wyswietlacza
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

# Definicja stalych dla LCD
LCD_WIDTH = 24    # Maksymalna ilosc znakow na linie
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM adres dla 1 linii
LCD_LINE_2 = 0xC0 # LCD RAM adres dla 2 linii

# Stale czasowe
E_PULSE = 0.00005
E_DELAY = 0.00005

# tablica adresow (pozycji) znakow dodatkowych
LCD_TAB_CHARS = [0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78]

########## Funkcja wpisujaca znak do tablicy CGRAM
def lcd_custom(pos,charDefHex):
  lcd_byte(LCD_TAB_CHARS[pos],LCD_CMD)
  for i in charDefHex:
    lcd_byte(i,LCD_CHR)

########## Funkcja glowna programu
def main():

  GPIO.setmode(GPIO.BCM)
  GPIO.setwarnings(False) #wylaczenie warningow
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7

  # Inicjalizacja wyswietlacza
  lcd_init()

  # definicja poszczegolnych liter - kolejno: spacja, ą, ę, ł, ó
  lcd_custom(0,[0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x04, 0x06])
  lcd_custom(1,[0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x04, 0x06])
  lcd_custom(2,[0x0C, 0x04, 0x06, 0x0C, 0x04, 0x04, 0x0E, 0x00])
  lcd_custom(3,[0x02, 0x04, 0x0E, 0x11, 0x11, 0x11, 0x0E, 0x0])

  # wyslanie tekstu na pierwsza linie
  lcd_byte(LCD_LINE_1, LCD_CMD)
  lcd_string("dobreprogramy.pl")
  #wyslanie tekstu nadruga linie
  lcd_byte(LCD_LINE_2, LCD_CMD)
  lcd_string(u"i mamy PL znaki: ą ę ł ó")

########## Funkcja inicjalizujaca wyswietlacz

def lcd_init():
  lcd_byte(0x33,LCD_CMD)
  lcd_byte(0x32,LCD_CMD)
  lcd_byte(0x28,LCD_CMD)
  lcd_byte(0x0C,LCD_CMD) 
  lcd_byte(0x06,LCD_CMD)
  lcd_byte(0x01,LCD_CMD) 

# funkcja zmieniajaca litere z ogonkiem na zdefiniowany znak
def lcd_custom_rep( str ):
    new_str=u""
    for i in str:
        if i==u"ą":
            new_str+= chr(0)
        elif i==u"ę":
            new_str+= chr(1)
        elif i==u"ł":
            new_str+= chr(2)
        elif i==u"ó":
            new_str+= chr(3)
        else:
            new_str+=i
    return new_str

######### Funkcja wysylajaca string na konkretna linie i zmieniajaca ogonki

def lcd_string(message):
  message = lcd_custom_rep(message)
  message = message.ljust(LCD_WIDTH," ") 

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message{i}),LCD_CHR)
                     # literka "i" powinna byc w kwadratowym nawiasie!!!
                     #musialem to zmienic bo blogowy edytor sie gubil...

########## Funkcja wysylajaca dane do pinow
def lcd_byte(bits, mode):
  GPIO.output(LCD_RS, mode) # RS

  # High bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
  if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)

  # Przelaczenie pinu 6E
  time.sleep(E_DELAY)   
  GPIO.output(LCD_E, True) 
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False) 
  time.sleep(E_DELAY)     

  # Low bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x01==0x01:
    GPIO.output(LCD_D4, True)
  if bits&0x02==0x02:
    GPIO.output(LCD_D5, True)
  if bits&0x04==0x04:
    GPIO.output(LCD_D6, True)
  if bits&0x08==0x08:
    GPIO.output(LCD_D7, True)

  # Przelaczenie pinu 6E
  time.sleep(E_DELAY)   
  GPIO.output(LCD_E, True) 
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False) 
  time.sleep(E_DELAY)  

if __name__ == '__main__':
  main()

Finał...

i tak to wszystko się prezentuje ;)
i tak to wszystko się prezentuje ;)
Wybrane dla Ciebie
Komentarze (12)