Vývody D0..D7 LCD displeje jsou propojeny s datovou sběrnicí D0..D7 mikroprocesoru. K adrese A0 je připojen RS a k adrese A1 R/W displeje. "Enable" pulz je generován přídavnou logikou, která v tomto případě úplně dekóduje adresy 0xFF00..0xFF03 a umožňuje čtení i zápis. Registry LCD displeje jsou potom přístupné na následujících adresách:
0xFF00 for - zápis do controlního registru
0xFF01 for - zápis do datového registru
0xFF02 for - čtení kontrolního registru
0xFF03 for - čtení datového registru
Program je odladěn v C51-Keil. Je třeba si uvědomit, že v některých případech délka pulzu "E" nemusí vyhovovat použitému LCD displeji - je úměrná hodinové frekvenci mikroprocesoru.




//////////////////////////////////////////////////////////////////////
// LCD INTERFACE TO EXTERNAL MEMORY
/////////////////////////////////////////////////////////////////////

#define BLINK_OFF_CURSOR_OFF  0x0C
#define BLINK_ON_CURSOR_OFF   0x0D
#define BLINK_OFF_CURSOR_ON   0x0E
#define BLINK_ON_CURSOR_ON    0x0F
#define CLEAR                 0x01
#define HOME                  0x02
#define LINE_1                0x80
#define LINE_2                0xC0
#define LINE_3                0x94
#define LINE_4                0xD4
#define LCD_OFF               0x08

xdata char wrctl_lcd  _at_ 0xFF00; // RS_LCD = 0, RW_LCD = 0
xdata char wrdata_lcd _at_ 0xFF01; // RS_LCD = 1, RW_LCD = 0
xdata char rdctl_lcd  _at_ 0xFF02; // RS_LCD = 0, RW_LCD = 1
xdata char rddata_lcd _at_ 0xFF03; // RS_LCD = 1, RW_LCD = 1


void delay(unsigned int dly){
  int d;
  for(d=0;d!=dly;d++);
}

char busy_lcd(){ // busy flag is D7, must be masked with 0x80
  return(rdctl_lcd & 0x80);
}

void init_lcd(){
  wrctl_lcd = 0x30;     // write control for the firt time on power up
  delay(5000);          // execute delay 4.1 ms or more,
                        // because busy flag can not read
  wrctl_lcd = 0x30;     // same before, the second
  delay(5000);
  wrctl_lcd = 0x30;     // one more time, without delay
  delay(5000);
  wrctl_lcd = 0x38;     // function set to 8bit length interface
  while(busy_lcd());    // now, busy flag can read for cek busy lcd
                        // set blink on and cursor off, please change if you don't like it
  wrctl_lcd = BLINK_ON_CURSOR_OFF;
  while(busy_lcd());    // now, busy flag can read for check busy lcd
  wrctl_lcd = CLEAR;    // clear lcd
  while(busy_lcd());    // now, busy flag can read for check busy lcd
}


void locate_lcd(char row, char col){
  char d;
  // locate cursor to row,col for write read char in lcd
  // row and char start at 0, for example locate_lcd(0,0) is row 1 and col 1
  switch(row){
    case 0: d = LINE_1; // set to DD_RAM start address for line_1
            break;
    case 1: d = LINE_2; // set to DD_RAM start address for line_2
            break;
    case 2: d = LINE_3; // set to DD_RAM start address for line_3
            break;
    case 3: d = LINE_4; // set to DD_RAM start address for line_4
            break;
  }
  wrctl_lcd=(d += col);
  while(busy_lcd());
}


void wrstr_lcd(char *ptrbuff){
  char d;
  // this routine send string in idata, data, pdata, cdata or cdata ending by NULL
  // the address is generic pointer *ptrbuff
  // this pointer aotumatically contain pointer for memory type that you pass to
  // this routine
  while((d=*ptrbuff++) != 0){
    wrdata_lcd = d; while(busy_lcd());
  }
}

char code  msgcode_lcd[]  = "This STRING-CODE";
char xdata msgxdata_lcd[] = "This STRING-XDATA";
char idata msgidata_lcd[] = "This STRING-IDATA";

void test_lcd(){
  locate_lcd(0,0);              // testing to write string-code to lcd (0,0)
  wrstr_lcd(&msgcode_lcd[0]);
  locate_lcd(1,0);              // testing to write string-code to lcd (1,0)
  wrstr_lcd(&msgcode_lcd[0]);
  delay(50000);                 // delay
  wrctl_lcd = CLEAR;            // now clear display
  while(busy_lcd());
  locate_lcd(0,0);              // testing to write string-code to lcd (0,0)
  wrstr_lcd(&msgidata_lcd[0]);
  locate_lcd(1,0);              // testing to write string-code to lcd (1,0)
  wrstr_lcd(&msgidata_lcd[0]);
  delay(50000);                 // delay
  wrctl_lcd = CLEAR;            // now clear display
  while(busy_lcd());
  locate_lcd(0,0);              // testing to write string-code to lcd (0,0)
  wrstr_lcd(&msgxdata_lcd[0]);
  locate_lcd(1,0);              // testing to write string-code to lcd (1,0)
  wrstr_lcd(&msgxdata_lcd[0]);
  delay(50000);                 // delay
}


main(){
  init_lcd();
  while(1) {test_lcd()};
} 



Vytisknout stránku

Zpátky Zpátky
© DH servis 2002 -