<?php echo _title;?> www.prochazka.zde.cz
www.ccsinfo.com/CEH
Server si právě čte 43 lidí, dnes je sobota, 20. Duben 2024   
Kategorie: PIC, Xilinx, HW

Čtyřbitová komunikace LCD display s radičem HD44780 a mikrořadiče PIC16Fxx

icons pic Zdrojový kód pro PIC mikrokontrolér a LCD display s radičem HD44780. A přidání dalšího zdrojového kódu pro PIC16F877A, tentokrát napsaný v céčku. Jako kompilátor céčka je použit HI-TECH PICC který se dá jako demo stáhnout z: www.htsoft.com/ demo je u některých PICu omezena jen na 2KB kódu.

lcd2
lcd1
vyvojova_deska1

Podrobnější informace o LCD display s řadičem HD44780 najdete na: www.hw.cz/docs/lcd_iq_displaye/lcd_iq_dip.html
, ouwehand.net/~peter/lcd/lcd.shtml nebo www.cmail.cz/doveda/lcd/

Katalogový list lze stáhnout z: www.cmail.cz/doveda/lcd/hd44780u.pdf

  • Vývojová deska PIC + XILINX s obvody PIC16F877A a XC9572XL nebo XC95144XL.
  • Můžete si LCD display připojit i na LPT port počítače.

První kód je napsán v assembleru ve vývojovém prostředí MPLAB pro jednočipový mikrořadič PIC16F84. Druhý program pro ovládání LCD displaye s řadičem HD44780 je taktéž napsán ve stejném vývojovém prostředí ale je použit jazyk C. Jednočipový mikrořadič je použit PIC16F877A. Jako kompilátor céčka je použit HI-TECH PICC, který se dá jako demo stáhnout z: www.htsoft.com demo je u některých PICu omezena jen na 2KB kódu.

   Zdrojové kódy pro PIC16F877A v céčku si můžete stáhnout z: Vyvojova deska PIC + XILINX zdrojak pro PIC



Kód v assembleru...

PIC16 code
; Zdroják pro MPLAB
; ; Čtyřbitová komunikace LCD display s radičem HD44780 a mikrořadiče PIC16F84.
;
; Dne 19.5.2001
;
; Pavel Procházka
; hacesoft@mujmail.cz
; www.prochazka.zde.cz

  #include "P16F84.INC"

  list p=16F84, f=INHX8M, r=DEC

; Z portu B je volný pouze bit 0. Ostatní vývody portu B používá LCD display.
;Port A je celý volný.
;K ovládání Portu B bitu 0 používejte instrukce BCF PORTB,0 a BSF PORTB,0.
;K nastavení tohoto bitu jako vstupní/výstupní použijte následující sekvenci:
; BCF nebo BSF reg_trisb,0
;       MOVf    reg_trisb,w
;       TRIS    PORTB
; Za podmínky že poběží v přerušení.
; Pokud nebudete používat přerušení stačí, aby bity co používá LCD display
;byli nastavenu jako výstupní. Ale musíte konfiguraci zapsat i do registru
;'reg_trisb' jinak po provedení jakéhokoliv příkazu s LCD displayem bude
;bit 0 porty B nastaven jako výstupní (základní nastavení). Pokud Vám
;bude stačit, aby bit 0 portu B byl jen výstupní, tak nic nemusíte
;konfigurovat.
; S portem A můžete nakládat jakkoliv.
;
; Zapojeni LCD displae:  vývod PICu    vývod LCD
;        PORTB 1 RS - vyber reg.
;        PORTB 2         RW - read/write
;        PORTB 3         E - enable
;        PORTB 4         DB4
;        PORTB 5         DB5
;        PORTB 6         DB6
;        PORTB 7         DB7
; Vývody DB0 až DB3 z LCD displaye připojit na 0V.


LCD_TEMP  equ 0x020     ; hodnota, která se ma poslat do LCD
reg_trisb equ 0x021     ; hodnota, která se vyšle na TRISB

DELAY     equ 0x022     ; Used in DELAYxxx routines
X_DELAY   equ 0x023     ; Used in X_DELAYxxx routines

#define   e   PORTB,3
#define   rw  PORTB,2
#define   rs  PORTB,1


  start ORG 0x0000
DEMO
  call  LCDINIT ;inicializace LCD display

        movlw   35h
        call    LCDPUTCHAR

        movlw   36h
   call LCDPUTCHAR

        movlw   37h
        call    LCDPUTCHAR

        movlw   38h
        call    LCDPUTCHAR

DEMO1   goto DEMO1

; inicializace LCD displae.
LCDINIT
        clrf    reg_trisb
   MOVLW 0x01E
   CALL X_DELAY500 ; 30 * 0.5mS = 15mS

;***************** Nastaveni 8-bitové komunikace ***************************

        MOVLW 0x030 ; 8-bit-interface
   call SENDPRIKAZ

;*************** Nastaveni 4-bitové komunikace *****************************

        MOVLW 0x020 ; 4-bit-interface
        call    SENDPRIKAZ

;***************************************************************************
        MOVLW 0x028 ; 4-bit-interface, 2-lines
        CALL LCDPUTCMD
        MOVLW 0x008 ; disp.off, curs.off, no-blink
        CALL LCDPUTCMD
        MOVLW 0x001      ;lcd smazat
        CALL LCDPUTCMD
        MOVLW 0x00C ; disp.on, curs.off
        CALL LCDPUTCMD
        MOVLW 0x006      ; Inkrementace, normální mód.
        CALL LCDPUTCMD
        RETURN

SENDPRIKAZ
        CALL LCDBUSY     ; Wait for LCD to be ready
        BCF rw
        BCF rs
        BSF e
        call    Zapis_w  ; Zápis reg. W na PortB.
        BCF e
        return

; Čeká až Display dodělá příkaz. Obsah reg. W se touto rutinou nemění!
LCDBUSY
        movwf LCD_TEMP   ; Ulož reg. W do LCD_TEMP
        movf    reg_trisb,w
        andlw   b'00001111'
        iorlw   b'11110000'      ; Byty 4 až 7 brány B jsou vstupní.
        movwf   reg_trisb
        tris    PORTB
lcd_busy
        BCF rs
        BSF rw
        BSF e
        movf PORTB,w ; Read busy flag + DDram address
        BCF e
        BSF e
        BCF e
        andlw b'10000000'        ; Test na BF příznak.
        BTFSS STATUS,Z
        goto lcd_busy
        bcf rw
        movf    reg_trisb,w
        andlw   b'00001111' ; Byty 4 az 7 brány B jsou výstupní.
        movwf   reg_trisb
        tris    PORTB
        movf LCD_TEMP,w  ; Obnov reg. W
        return

; Pošle znak na Display.
LCDPUTCHAR
        CALL LCDBUSY ; Wait for LCD to be ready
        BCF rw
        BSF rs
        BSF e
        call    Zapis_w  ; Zapíše reg. W na PortB.
        BCF e

        BSF e
        swapf   LCD_TEMP,f
        call    Zapis_w  ; Zapíše reg. W na PortB.
        BCF e
        RETURN

; Pošle příkaz na Display.
LCDPUTCMD
        call SENDPRIKAZ
        BSF e
        swapf   LCD_TEMP,f
        call    Zapis_w  ; Zapise reg. W na PortB.
        BCF e
   return

; Prekopiruje obsah reg. LED_TEMP bity 4 až 7 na PORTB bity 4 až 7.
Zápis_w
        movlw   b'00001111'
        andwf   PORTB,f
; Vynuluje bity 4 az 7 portub, výsledek uloží do portb.
        movlw   b'11110000'
        andwf   LCD_TEMP,w     
; Vynuluje bity 0 az 3 lcd_temp, výsledek uloží do w.
        iorwf   PORTB,f
; OR mezi w a potrb, výsledek uloží do portb.
        return

;*********************************** a 500uS delay @ 4MHz X-tal
DELAY500
        MOVLW D'165' ; +1 1 cycle
        MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP
        DECFSZ DELAY, F ; step1 1 cycle
        GOTO DELAY500_LOOP ; step2 2 cycles
DELAY500_END
        RETURN ; +3 2 cycles

;*********************************** a delay of 'W' * 500mS
X_DELAY500
        MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP
        CALL DELAY500 ; step1 wait 500uSec
        DECFSZ X_DELAY, F ; step2 1 cycle
        GOTO X_DELAY500_LOOP ; step3 2 cycles
X_DELAY500_END
        RETURN ; +2 2 cycles

        end


Kód v Céčku...

PIC16 code
//DEVICE PIC16F877A
//hacesoft
//www.prochazka.zde.cz
//6.11.2005
//Ovládaní LCD DISPLAYe ve vývojové desce PIC + XILINX
//Která se nachází na www.prochazka.zde.cz

//Fyzické zapojeni LCD k PICu 16F877A
//RE0 ...RS -> vyber reg.
//RE1 ...RW -> read/write
//RB3 ...EN1 -> ENABLE LCD
//RB1 ...DB4
//RB2 ...DB5
//RB4 ...DB6
//RB5 ...DB7

#include "pic.h"
#include "pic168xa.h"
#include "LCD_vyvojova_deska.h"
#define XTAL_FREQ       20MHZ
#include "delay.c"
#include "stdio.h"
#include "ctype.h"
#include "string.h"

__CONFIG (HS & WDTDIS & BORDIS & LVPDIS); //Konfiguracni slovo
__IDLOC (1); //verze SW
#define BF_FLAG (false); //FALSE=Cekaci smyska. TRUE=Cekani na prinzak BF z displye.

static bit      EN      @ ((unsigned)&PORTE*8+2);
static bit      LCD_RW  @ ((unsigned)&PORTE*8+1);
static bit      LCD_RS  @ ((unsigned)&PORTE*8+0);
static bit      LCD_EN  @ ((unsigned)&PORTB*8+3);
static bit      LCD_BF  @ ((unsigned)&PORTB*8+5);

static bit      DB4     @ ((unsigned)&PORTB*8+1);
static bit      DB5     @ ((unsigned)&PORTB*8+2);
static bit      DB6     @ ((unsigned)&PORTB*8+4);
static bit      DB7     @ ((unsigned)&PORTB*8+5);

unsigned char lcd_data = 0;

//----------------------------------------------------------------
void lcd_busy (void){
#if _BF_FLAG==true //Nektere displaye neposilaji informaci o dokonceni
 TRISB1 = 1; //Nastavani RB1 na vstupni PIN
 TRISB2 = 1; //Nastavani RB2 na vstupni PIN
 TRISB4 = 1; //Nastavani RB4 na vstupni PIN
 TRISB5 = 1; //Nastavani RB5 na vstupni PIN

 asm ("xxx: nop");
 //for(;;) {
  LCD_RS = 0;
  LCD_RW = 1;
  LCD_EN = 1;
  asm ("movf _PORTB,w");
  LCD_EN = 0;
  LCD_EN = 1;
  LCD_EN = 0;
  asm ("andlw _LCD_BF"); //Test na BF příznak.
  asm ("btfsc _STATUS,2"); //TEST na ZERO
  asm ("goto xxx"); //TEST na ZERO
 //     }
 LCD_RW = 0;
 TRISB1 = 0; //Nastavani RB1 na vystupní PIN
 TRISB2 = 0; //Nastavani RB2 na vystupní PIN
 TRISB4 = 0; //Nastavani RB4 na vystupní PIN
 TRISB5 = 0; //Nastavani RB5 na vystupní PIN
#else
 DelayMs(9);
#endif
}
//----------------------------------------------------------------
void send_prikaz (unsigned char bCommand){
 lcd_data = bCommand;
 lcd_busy();
 LCD_RW = 0;
 LCD_RS = 0;
 LCD_EN = 1;
 zapis_w();
 LCD_EN = 0;
}
//----------------------------------------------------------------

void lcd_init(void){
//Pro jistotu se provede několikrát inicializace
 DelayMs(255);
 lcd_init1();
 DelayMs(255);
 lcd_init1();
 DelayMs(255);
 lcd_init1();
 DelayMs(255);
 lcd_init1();
 DelayMs(255);
 lcd_init1();
}
void lcd_init1(void){
//inicializace LCD displye
 //unsigned trisb;
 TRISB = (0b11000001 & TRISB) | 0b00000000;
 //nastaveni portu B bity 37 na výstupní
 //ostatní nechá nezměněny.
 TRISE0 = 0; //RS -> data ven
 TRISE1 = 0; //RW -> data ven
 ADCON1 = 12;
 //PortA je nastaven jako vstup analog a
 //RE0 až 2 jsou nastaveny datové piny.

 DelayMs(100);
//***************** Nastaveni 8-bitové komunikace ***************************

 //8-bit-interface
 send_prikaz(0x03);

 DelayMs(100);
//*************** Nastaveni 4-bitové komunikace *****************************

 //4-bit-interface
 send_prikaz(0x02);
 DelayMs(100);

//***************************************************************************
 //4-bit-interface, 2-lines
 lcd_put_cmd (0x28);
 //lcd_put_cmd (0b00100000);

 //disp.off, curs.off, no-blink
 lcd_put_cmd (0x08);

 //lcd smazat
 lcd_put_cmd (0x01);

 //disp.on, curs.off
 lcd_put_cmd (0x0c);

 //Inkrementace, normalni mod.
 lcd_put_cmd (0x06);
}
//----------------------------------------------------------------
void zapis_w(void){
 //zkopirovat 4 az 7 bity z registru lcd_data na porty B.
 //RB1 ...DB4 ... bit4 registru lcd_data
 //RB2 ...DB5 ... bit5 registru lcd_data
 //RB4 ...DB6 ... bit6 registru lcd_data
 //RB5 ...DB7 ... bit7 registru lcd_data
 #asm
  bcf _PORTB,1
  bcf _PORTB,2
  bcf _PORTB,4
  bcf _PORTB,5
  btfsc _lcd_data,4
  bsf _PORTB,1
  btfsc _lcd_data,5
  bsf _PORTB,2
  btfsc _lcd_data,6
  bsf _PORTB,4
  btfsc _lcd_data,7
  bsf _PORTB,5
 #endasm
}
//----------------------------------------------------------------
void lcd_put_char (unsigned char sString)
{
 //Pošle znak na Display.
 lcd_data = sString;
 lcd_busy();
 LCD_RW = 0;
 LCD_RS = 1;
 LCD_EN = 1;
 zapis_w();
 LCD_EN = 0;
 LCD_EN = 1;
 asm ("swapf _lcd_data , f");
 zapis_w();
 LCD_EN = 0;
}
//----------------------------------------------------------------

void lcd_scroll(char Direction)
//Pohybuje celým displayem. Toto je funkce LCD (HW)
{
 if(Direction==SCROLL_LEFT)
 {
  lcd_put_cmd(0b00011000); //Scroll LEFT
 }
 else
 {
  lcd_put_cmd(0b00011100); //Scroll RIGHT
 }
}
//----------------------------------------------------------------
void ScrollMessage(unsigned char pozice, unsigned char radek,const char Message[])
//Pohybuje textem na zvoleném řádku od zadané pozice.
{
 char TempS[20];
 unsigned int MHead=0,Done=0,count;
 while(Done==0)
 {
  for(count=0;count<20;count++)
  {
   TempS[count]=Message[MHead+count];
   if(Message[MHead+count+1]==0) Done=1;
  }
  MHead++;
  lcd_goto(pozice, radek);
  lcd_string(TempS);
  DelayMs(250);
 }
}
//----------------------------------------------------------------
void lcd_goto(unsigned char pozice, unsigned char radek)
{
 if(radek >1) radek=1;
 lcd_put_cmd(((radek * 40) + 0x80)+ pozice);
}

//----------------------------------------------------------------
void lcd_string(const char * s)
{
 while(*s)
 lcd_put_char(*s++);
}
//----------------------------------------------------------------
void lcd_put_cmd (unsigned char bCommand)
{
 //Posle prikaz na Display.
 //asm ("movwf _lcd_data");
 send_prikaz (bCommand);
 LCD_EN = 1;
 asm ("swapf _lcd_data , f");
 zapis_w();
 LCD_EN = 0;
}
//----------------------------------------------------------------
main(void){
unsigned char loop;
 lcd_init();
for(;;) {
 ScrollMessage(0,0," Vita Vas Vyvojova deska PIC+XILINX ");
 lcd_cls;
 lcd_goto(0,1);
 lcd_string("Verze SW: 1.0.4.");
 ScrollMessage(0,0," Ze dne: 6. listopadu, 2005. ");
 ScrollMessage(0,0," Veskera dokumentace teto demonstracni desky se da stahnout z: ");

 for (loop = 0; loop < 10; loop++){
  lcd_goto(0,1);
  lcd_string("prochazka.zde.cz");
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  lcd_goto(0,1);
  lcd_string(" ");
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  }

  lcd_goto(0,0);
  lcd_string("prochazka.zde.cz");
  lcd_goto(0,1);
  lcd_string(" ----ahoj---- ");

 for (loop = 0; loop < 5; loop++){
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  lcd_scroll(SCROLL_LEFT);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  }

 for (loop = 0; loop < 5; loop++){
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  lcd_scroll(SCROLL_RIGHT);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  }

 lcd_cursor_home;
 lcd_string("prochazka.zde.cz");
 ScrollMessage(0,1," Uvitaci program vyvojoveho kitu PIC16F887A + XILINX XC9572XL. Zelenim tlacitkem se zvysuje hodnota na LED display a Modrim se hodnota Na LED display zmensuje. Zluta tlacitka ovladaji LED diody. Prepinace zapinaji a vypinaji blikani LED diod. Pokud je zapnuto blikani a stisknuto zlute tlacitko, tak LED dioda nesviti ale blika!!! ");
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);
 lcd_cls;
 }

}

print Formát pro tisk

Komentáře rss

Přidat komentář >

Nebyly přidány žádné komentáře.

Všechny informace jsou zahrnuty pod GPL licenci, pokud není explicitně uveden jiný typ licence.
Používání těchto stránek ke komerčním účelům lze jen se souhlasem autora.
Všechna práva vyhrazena (c) 1997 - 2024 hacesoft.
Jste návštevník číslo: 370818
Celkem zobrazeno stránek: 12326192
Přihlásit do administrace