AVR LCD - Magyar betük

2013-01-13 - Van benne egy hiba, ami itt nem jön elő, az lcd_cls()-ben a parancs kiadása után kell 2 msec-t várakozni!

2013-01-04

 

Lehet, hogy elegendő lett volna az LCD kijelzőt lefényképezni. A kapcsolás megegyezik a "Szia Levi!" project-tel.

A változást a kiteljesedett rutinkészlet jelenti. Úgy gondolom, hogy mindent meg lehet benne találni, amire szükség van (talán a vízszintes scrollozást nem, mert ilyesmit én nem használtam). Lehetőségünk van az LCD vezérlőnek az első 8 karakterét tetszőlegesen megadni. Lehet kis telefont, borítékot, de szükség esetén mgyar betüket is beprogamozni. Pontosabban a 0-7 lévő karakterek rajzolatát a vezérlő RAM-jába feltölteni. Erre szolgál az lcd_defc() függvényem. Érdekessége, - valójában a WinAVR-nek - hogy pgm_read_byte()-ot használja, mert a karkterek rajzolatát a PROGMEM-ből kell felolvasnia. Ezeknek a funkcióknk a használata miatt kellett beszúrni az -t. Másik érdekessége, hogy egyszerre az összes karakter képét be tudja tölteni. Addig dolgozik, ameddig nem olvas 0xFF-t. De egyenként is lehet definiálnia betüket, arra kell figyelni, hogy az első byte a betü sorszáma, azután jön 8 byte a betü rajzolatával, és utána 0xFF zárja a sort. További érdekesség a karakterek rajzolatának definiálása. A "tkiraaly_lcddef.h"-ban definiáltam tulajdonképpen egy kvázigrafikus számsorozatot. Ezeknek a szimbólumoknak a használatával, külső LCD karakterszerkesztő nélkül, a szövegszerkesztővel tudjuk a karaktereket szerkeszteni. A magyar karaktereknél érdekesség, hogy néhány betü megtalálható a vezérlő ROM-jában. (Annak idején a németek a vasfüggöny másik oldalán voltak. Most már nincs vasfüggöny.) Így sikerült olyan takarékos lenni, hogy az összes kisbetü elérhető, és még maradt egy fel nem használt hely is. Az lcd_putc_hu() függvényem gondoskodik arról, hogy a Win (kódolás) alatt begépelésre került ékezetes betük helyett a megfelelő LCD betük legyenek kiírva. Ennek párja az lcd_puts_hu(). A PSTR() gondoskodik róla, hogy a különböző helyeken alkalmazott konstans stringek a PROGMEM-be kerüljenek. Az lcd_puts_hu()-ban megint a pgm_read_byte() olvassa ezeket fel. Van még itt 4 sor/ 16 oszlopos kurzor pozícionálás. Ha valakinek 20 karakteres kijelző kerülne a kezébe, és szüksége lenne rá, írja át a függvényt :-). Készitettem egy bináris, és egy hexadecimális kiíró függvényt is. Amelyik függvényre nincs szükségünk az adott project-ben töröljük ki, mert feleslegesen foglalja helyrt.

Itt látható a program.



/*******************************************************************************
*   Author       -  Kiraly Tibor                                               *
*                   http://www.tkiraaly.hu                                     *
*   Date         -  2013.01.03.                                                *
*   Chip         -  Atmel ATtiny2313 & HD44780                                 *
*   Compiler     -  avr-gcc (WinAVR )                                          *
*                                                                              *
*   Magyar betukeszlet LCD-re, es mas fuggvenyek.                              *
*                                                                              *
********************************************************************************
*   PonyProg Configuration and Security Bits (bepipalva):                      *
*   Belso 4MHz-es osszc.:     SUT0, CKSEL3, CKSEL2, CKSEL0                     *
*                                                                              *
*******************************************************************************/
//
//
//    LCD bekotese:
//
//    14   LCD D7       - AVR PB3 - 15
//    13   LCD D6       - AVR PB2 - 14
//    12   LCD D5       - AVR PB1 - 13
//    11   LCD D4       - AVR PB0 - 12
//    10   LCD D3       - VDD              ( VDD - 2 soros kijelzo, GND - 1 soros)
//     9   LCD D2       - GND
//     8   LCD D1       - GND
//     7   LCD D0       - GND
//     6   LCD E        - AVR PD6 - 11     (1 - change data - 0)
//     5   LCD RW       - GND              (0- write, 1- read)
//     4   LCD RS       - PD5              (0- istruction, 1- data)
//     3   LCD KONTR    - 10 kOhm trim.
//     2   LCD VDD      - +5V
//     1   LCD VSS      - GND


#ifndef F_CPU
#define F_CPU                4000000             // orajel (MHz)
#endif




#include "tkiraaly_attiny2313.h"
#include "tkiraaly_lcddef.h"
#include 
#include 




void lcd_init4( void);                           // LCD inicializalasa 4 bitre
void lcd_putc( UC);                              // betu kiirasa
void lcd_putcmd( UC);                            // parancskod kiadasa
void lcd_yx( UC, UC);                            // kurzor pozicioja 0..3/0..15
void lcd_cls( void);                             // kepernyo torles
void lcd_putc_hu( UC);                           // betu kiirasa, magyar Win konverzio
void lcd_puts_hu( const char *);                 // string kiirasa, magyar betuk is
void lcd_defc( const uint8_t *);                 // egyedi betu(k) beallitasa        
void lcd_putbyte_bin( UC);                       // 1 byte kiirasa binarisa
void lcd_putc_hex( UC);                          // 1 hexadecimalis szamjegy kiirasa
void lcd_putbyte_hex( UC);                       // 1 byte kiirasa hexadecimalisan




#define LCD_E                6
#define LCD_E_0              BC( PORTD, LCD_E)
#define LCD_E_1              BS( PORTD, LCD_E)

#define LCD_RS               5
#define LCD_RS_UTASITAS      BC( PORTD, LCD_RS)
#define LCD_RS_ADAT          BS( PORTD, LCD_RS)

#define LED                  4
#define LED_BE               BC( PORTD, LED)
#define LED_KI               BS( PORTD, LED)

#define LCD_PORT             PORTB               // also 4 bit
#define LCD_PORT_ENABLE      DDRB= 0B00001111    // also 4 bit kimenet




const uint8_t magyar_betuk[] PROGMEM =
{
   0,
                                                 // á - 0
   Cx______X_,
   Cx_____X__,
   Cx____XXX_,
   Cx_______X,
   Cx____XXXX,
   Cx___X___X,
   Cx____XXXX,
   Cx________,
                                                 // é - 1
   Cx______X_,
   Cx_____X__,
   Cx____XXX_,
   Cx___X___X,
   Cx___XXXXX,
   Cx___X____,
   Cx____XXX_,
                                                 // í- 2
   Cx________,
   Cx______X_,
   Cx_____X__,
   Cx________,
   Cx____XX__,
   Cx_____X__,
   Cx_____X__,
   Cx____XXX_,
   Cx________,
                                                 // ó - 3
   Cx______X_,
   Cx_____X__,
   Cx____XXX_,
   Cx___X___X,
   Cx___X___X,
   Cx___X___X,
   Cx____XXX_,
   Cx________,
                                                 // ő - 4
   Cx_____X_X,
   Cx____X_X_,
   Cx____XXX_,
   Cx___X___X,
   Cx___X___X,
   Cx___X___X,
   Cx____XXX_,
   Cx________,
                                                 // ú - 5
   Cx______X_,
   Cx_____X__,
   Cx________,
   Cx___X___X,
   Cx___X___X,
   Cx___X__XX,
   Cx____XX_X,
   Cx________,
                                                 // Ű - 6
   Cx_____X_X,
   Cx____X_X_,
   Cx________,
   Cx___X___X,
   Cx___X___X,
   Cx___X__XX,
   Cx____XX_X,
   Cx________,
   
   0xFF
};




int main( void)
{
   DDRD= 0B01110000;                             // kimenetek beallitasa (1)
   LCD_PORT_ENABLE;
   lcd_init4();
   LED_BE;
   lcd_defc( magyar_betuk);
   lcd_yx( 0, 2);
   lcd_puts_hu( PSTR( "tkiraaly.hu"));
   lcd_yx( 1, 3);
   lcd_puts_hu( PSTR( "áéíóöőúüű"));
   // lcd_puts_hu( PSTR( "(C) 3BYTE 2012"));
   // lcd_putbyte_bin( 0x57);
   // lcd_putbyte_hex( 0x5B);
   return 0;
}




void lcd_init4( void)                            // LCD inicializalasa 4 bitre
{
   _delay_ms( 15);
   LCD_RS_UTASITAS;
   LCD_PORT= 0x00000010;                         // 4 bit interface
   LCD_E_1;
   LCD_E_0;
   _delay_ms( 5);
   LCD_E_1;
   LCD_E_0;
   _delay_us( 120);
   lcd_putc( 0B00101000);                        // 4 bit interface, 2 sor, 5x8 pontos betu
   lcd_putc( 0B00101000);                        // 2x kell kiadni, vagy LCD D3-t VDD-re kell kotni
   lcd_putc( 0B00001100);                        // kijelzes be, cursor ki
   lcd_putc( 0B00000110);                        // kiiras jobbra
   LCD_RS_ADAT;
}


   // HD44780 parancskodjai
   
   // lcd_putc( 0B00000001);                     // kepernyo torlese

   // lcd_putc( 0B00000010);                     // kurzor a bal felso sarokba, utana var 1,5 msec

   // lcd_putc( 0B00000110);                     // kiiras jobbra
   // lcd_putc( 0B00000100);                     // kiiras balra

   // lcd_putc( 0B00001000);                     // kijelzes ki
   // lcd_putc( 0B00001100);                     // kijelzes be, cursor ki
   // lcd_putc( 0B00001110);                     // kijelzes be, cursor be, villogas ki
   // lcd_putc( 0B00001111);                     // kijelzes be, cursor be, villogas be

   // lcd_putc( 0B00010000);                     // cursor mozgatasa balra
   // lcd_putc( 0B00010100);                     // cursor mozgatasa jobbra
   // lcd_putc( 0B00011000);                     // kiiras eltolasa balra
   // lcd_putc( 0B00011100);                     // kiiras eltolasa jobbra

   // lcd_putc( 0B00100000);                     // 4 bit interface, 1 sor kijelzes, 5x7 pontos betu
   // lcd_putc( 0B00101000);                     // 4 bit interface, 2 sor kijelzes, 5x7 pontos betu
   // lcd_putc( 0B00101100);                     // 4 bit interface, 2 sor kijelzes, 5x10 pontos betu
   // lcd_putc( 0B00111000);                     // 8 bit interface, 2 sor kijelzes, 5x7 pontos betu

   // lcd_putc( 0B01000000);                     // betu rajzolatok kezdo cime

   // lcd_putc( 0B10000000);                     // bal felso sarok betujenek cime



void lcd_putcmd( UC cmd)                         // parancskod kiadasa
{
   LCD_RS_UTASITAS;
   lcd_putc( cmd);
   LCD_RS_ADAT;
}




void lcd_putc( UC c)                             // egy betu kiiras
{
   LCD_E_1;                                      // felso 4 bit
   LCD_PORT= ( LCD_PORT & 0B11110000) | ( 0B00001111 & c >> 4);
   LCD_E_0;
   LCD_E_1;                                      // also 4 bit
   LCD_PORT= ( LCD_PORT & 0B11110000) | ( 0B00001111 & c);
   LCD_E_0;
   _delay_us( 37);                               // var 37 usec  
}




void lcd_yx( UC sor, UC betu)                    //  kurzor pozicionalasa 0..3/0..15
{
   UC cim= 0x80;                                 // parancs kodja
   if (sor & 0B00000001) cim+= 64;               // 1. es 3. sor
   if (sor & 0B00000010) cim+= 20;               // 2. es 3. sor
   cim+= betu & 0x0F; 
   lcd_putcmd( cim);
}




void lcd_cls( void)                              // kepernyo torles
{
   lcd_putcmd( 0x01);
}




void lcd_defc( const uint8_t *s)                 // egyedi betu(k) beallitasa
{
   register unsigned char c;
   LCD_RS_UTASITAS;
   lcd_putc( ( ( pgm_read_byte( s++) & 0B00000111) << 3) | 0B01000000);   // betu cime + parancs 
   LCD_RS_ADAT;
   while ( ( c= pgm_read_byte( s++)) != 0xFF) lcd_putc( c);
   LCD_RS_UTASITAS;
   LCD_RS_ADAT;
}

    
    
    
void lcd_putbyte_bin( UC c)                       // 1 byte kiirasa binarisa
{
   UC i= 8;
   while( i--)
   {
      if( c & 0x80) lcd_putc( '1');
      else          lcd_putc( '0');
      c= c << 1;
   }
}




void lcd_putc_hex( UC c)                          // 1 hexadecimalis szamjegy kiirasa
{
   c&= 0x0F;
   if( c < 10) c+= '0';
   else        c+= 'A'- 10;
   lcd_putc( c);
}




void lcd_putbyte_hex( UC c)                       // 1 byte kiirasa hexadecimalisan
{
   lcd_putc_hex( c >> 4);
   lcd_putc_hex( c);
}




void lcd_putc_hu( UC c)                          // magyar betu kiirasa LCD-re
{
   switch( c)
   {
      case 0xD6:                                 // Ö
      case 0xF6:                                 // ö
                  c= 0xEF;
                  goto kiir;
      case 0xDC:                                 // Ü
      case 0xFC:                                 // ü
                  c= 0xF5;
                  goto kiir;
      case 0xC1:                                 // Á
      case 0xE1:                                 // á
                  c= 0;
                  goto kiir;
      case 0xC9:                                 // É
      case 0xE9:                                 // é
                  c= 1;
                  goto kiir;
      case 0xCD:                                 // Í
      case 0xED:                                 // í
                  c= 2;
                  goto kiir;
      case 0xD3:                                 // Ó
      case 0xF3:                                 // ó
                  c= 3;
                  goto kiir;
      case 0xD5:                                 // Ő
      case 0xF5:                                 // ő
                  c= 4;
                  goto kiir;
      case 0xDA:                                 // Ú
      case 0xFA:                                 // ú
                  c= 5;
                  goto kiir;
      case 0xDB:                                 // Ű
      case 0xFB:                                 // ű
                  c= 6;
                  goto kiir;
      default:;
   }
   kiir:
   lcd_putc( c);
}




void lcd_puts_hu( const char *s)                 // string kiiras, magyar betuk is
{
   register unsigned char c;
   while ( ( c= pgm_read_byte( s++))) lcd_putc_hu( c);
}

Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.