AVR LCD - Kvázi analóg kijelzés

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

 

A kapcsolás még mindig megegyezik a "Szia Levi!" project-tel.

Aki leküzdötte az előző programot, annak ez már csak érdekesség. Ez a program demonstrálja, hogyan lehet egy kvázi analóg kijelzést megvalósítani egy karakteres LCD kijelzőn. A bargraph() függvényem gondoskodik a kijelzésről. Igazából az egész sort felülírja. Az érdekesség a közepén van, mer az elején "tele" karakterek kellenek, a végén meg "üresek". A közepén meg ki kell vákasztani, milyenre van szükség. A függvény a main()-ban van meghívva, 1/5 másodpercenként beolvasunk egy értéket a demo_adatok-ból. Ha 0xFF-hez értünk, előlről kezdődik az egész. Érdemes kipróbálni, látványos kis animáció.

Itt látható a program.



/*******************************************************************************
*   Author       -  Kiraly Tibor                                               *
*                   http://www.tkiraaly.hu                                     *
*   Date         -  2013.01.03.                                                *
*   Chip         -  Atmel ATtiny2313 & HD44780                                 *
*   Compiler     -  avr-gcc (WinAVR )                                          *
*                                                                              *
*   Karakterese LCD-n kvazigrafikus bargraph kijelzes es demoja.               *
*                                                                              *
********************************************************************************
*   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_puts( const char *);                    // string kiirasa, magyar betuk is
void lcd_defc( const uint8_t *);                 // egyedi betu(k) beallitasa        
void bargraph( UC);                              // 15 segments bar graph, n<46



 
#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 bar_cdef[] PROGMEM =
{
   1,                                  // 1
   Cx________,
   Cx_______X,
   Cx________,
   Cx________,
   Cx________,
   Cx________,
   Cx___X_X_X,
   Cx________,
                                       // 2
   Cx________,
   Cx_______X,
   Cx________,
   Cx___X____,
   Cx___X____,
   Cx___X____,
   Cx___X_X_X,
   Cx________,
                                       // 3
   Cx________,
   Cx_______X,
   Cx________,
   Cx___X_X__,
   Cx___X_X__,
   Cx___X_X__,
   Cx___X_X_X,
   Cx________,
                                       // 4
   Cx________,
   Cx_______X,
   Cx________,
   Cx___X_X_X,
   Cx___X_X_X,
   Cx___X_X_X,
   Cx___X_X_X,
   Cx________,
                                       // 5
   Cx________,
   Cx_______X,
   Cx_______X,
   Cx_______X,
   Cx_______X,
   Cx_______X,
   Cx_______X,
   Cx________,
   
   0xFF
};



 
const uint8_t demo_adatok[] PROGMEM =
{
   1,12,20,28,33,42,34,41,45,26,11,6,2,9,
   0xFF
};



 
int main( void)
{
   const unsigned char *s;
   register unsigned char c;
   DDRD= 0B01110000;                             // kimenetek beallitasa (1)
   LCD_PORT_ENABLE;
   lcd_init4();
   LED_BE;
   lcd_defc( bar_cdef);
   lcd_yx( 0, 3);
   lcd_puts( PSTR( "tkiraaly.hu"));
   for(;;)
   {
      s= demo_adatok;
      while (( c= pgm_read_byte( s++)) != 0xFF)
      {
         bargraph( c);
         _delay_ms( 200);
      }  
   }
   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;
}



 
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_puts( const char *s)                    // string kiiras, magyar betuk is
{
   register unsigned char c;
   while ( ( c= pgm_read_byte( s++))) lcd_putc( c);
}



    
void bargraph( UC n)                             // 15 segments bar graph, n<46
{
   UC i;
   UC c;
   if( n>45) n= 45;
   lcd_yx( 1, 0);
   lcd_putc( 5);
   for( i= 0; i < 15; i++)
   {
      switch( n)
      {
         case 0: c= 1; break;
         case 1: c= 2; n= 0; break;
         case 2: c= 3; n= 0; break;
         default: c= 4; n-= 3;
      }
      lcd_putc( c);
   }
}

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