Microcontrolador 8051 - Display LCD

  • Descrição:
  • Este experimento executa escrita diversas no LCD no modo 4 Bits, portanto utilizando apenas 1 port do 8051

    Módulos utilizados:
    • CPU-8051-USB
    • PR-LCD-1602
    Procedimento:
    1. Grave o programa do experimento na CPU-8051-USB.
    2. Conecte o CN1 do módulo PR-LCD-1602 no port P0 da CPU-8051-USB
    3. Pressione e solte o botão reset.
    Conexões do experimento:
    imagem conexoes
    Código Utilizado(Disponível em C ou Assembly):
    									//################################################################################################
    //# EMPRESA:            ========== CONTROL CHIP ENGENHARIA ========                              #
    //# SITE:               http://www.controlchip.com.br                                            #
    //#==============================================================================================#
    //# PROGRAMADOR:        Israel Cortez                                                            #
    //# DATA DO SOFTWARE:   20/05/2009                                                               #
    //# VERSÃO ATUAL:       VR3.2                                                                    #
    //#==============================================================================================#
    //# Hardware Necessário: CPU-8051-USB / PR-LCD-1602                                              #
    //#==============================================================================================#
    //------------------------------
    //========== INCLUDES ==========
    //------------------------------
    #include "8051.H"                //Flags do 8051
    //----------   ----------
    #include           //TRATAMENTO DE STRINGS
    //--------------------------------
    //========== PROTITIPOS ==========
    //--------------------------------
    void INICIALIZA_LCD(void);
    void LCD_CLEAR(void);
    void LCD_POSIC_LINHA1(char);
    void LCD_POSIC_LINHA2(char);
    void LCD_WRITE(char[16]);
    void LCD_WAIT(unsigned char);
    void LCD_WAIT_RAPIDO(void);
    void BITS4(unsigned char);
    void TIMER(unsigned char);
    void QUEBRA_NUMEROS(unsigned char);
    void WRITE_NUMERO(unsigned char);
    void WRITE_CARAC(unsigned char);
    //--------------------------------------------
    //========== VARIAVEIS DE USO GERAL ==========
    //--------------------------------------------
    unsigned char ESCRITA_LENTA=0;            // 1= Escrita LCD lenta | 0= Escrita LCD rápida
    //=====  BYTE AUXILIAR P/ ACESSO BIT A BIT =====                         
    data unsigned char at 0x2F BYTE_BIT_BIT=0;
    //=====  BITS =====
    bit at 0x78 BYTE_BIT_BIT_0=0;   //BIT 0     2F.0
    bit at 0x79 BYTE_BIT_BIT_1=0;   //BIT 1     2F.1
    bit at 0x7A BYTE_BIT_BIT_2=0;   //BIT 2     2F.2
    bit at 0x7B BYTE_BIT_BIT_3=0;   //BIT 3     2F.3
    bit at 0x7C BYTE_BIT_BIT_4=0;   //BIT 4     2F.4
    bit at 0x7D BYTE_BIT_BIT_5=0;   //BIT 5     2F.5
    bit at 0x7E BYTE_BIT_BIT_6=0;   //BIT 6     2F.6
    bit at 0x7F BYTE_BIT_BIT_7=0;   //BIT 7     2F.7
    //--- Quebra numeros ---
    unsigned char DIGITO1;
    unsigned char DG1_AUX;
    unsigned char CENTENA;
    unsigned char DG2_AUX;
    unsigned char DIGITO2;
    unsigned char DG3_AUX;
    unsigned char DIGITO3;
    //-----------------------------------------------------------
    //======== DECLARAÇÃO DAS VIAS ENTRE uC E Lcd (I/Os) ========
    //-----------------------------------------------------------
    #define RS P0_0
    #define RW P0_1
    #define EN P0_2
    #define DB4 P0_4
    #define DB5 P0_5
    #define DB6 P0_6
    #define DB7 P0_7
    //#############################################################
    //-------------------------------------------------------------
    //=========================== MAIN ============================
    //-------------------------------------------------------------
    //#############################################################
    void main (void)
    {
        TIMER(2);
        INICIALIZA_LCD();                   //Inicializa o modo do display            
        ESCRITA_LENTA=1;
        //----- Loop infinito -----
        while (1)        
        {                      
            
            //--- Mensagem 1 ---
            LCD_CLEAR();                        //Limpa display e posiciona o cursor na linha 0 posic 0
            LCD_POSIC_LINHA1(0);
            LCD_WRITE("PROGRAMA EXEMPLO");
            LCD_POSIC_LINHA2(0);
            LCD_WRITE("MOD  PR-LCD-1602");
            TIMER(100);
            //--- Mensagem 2 ---
            LCD_CLEAR();                       
            LCD_WRITE(" CONTROL  CHIP  ");
            LCD_POSIC_LINHA2(0);
            LCD_WRITE("   ENGENHARIA   ");     
            TIMER(100);
            //--- Mensagem 3 ---
            LCD_CLEAR();                       
            LCD_WRITE("  Hello  Word   ");
            LCD_POSIC_LINHA2(0);
            LCD_WRITE("  Hello  Word   ");     
            TIMER(100);  
            
            //--- Alterna entre escrita Rápida e lenta --- 
            if(ESCRITA_LENTA==0)
            {
               ESCRITA_LENTA=1; 
            }
            else
            {
               ESCRITA_LENTA=0;            
            }         
        }
    }
    
    //#############################################################
    //-------------------------------------------------------------
    //======================= SUB ROTINAS =========================
    //-------------------------------------------------------------
    //#############################################################
    
    //======================================================================
    //================== EXECUTA INICIALIZAÇÃO DO LCD ======================
    //======================================================================
    void INICIALIZA_LCD(void)
    {
        RS=0;
        RW=0;
        EN=0;
        EN=1;
        DB4=0;
        DB5=1;
        DB6=0;
        DB7=0;
        EN=0;
        LCD_WAIT(100);       
        //Prepara o LCD para trabalhar com 4 bits e 2 linhas
        RS=0;    
        BITS4(0x28);
        //----- Envia segundo Byte -----
        BITS4(0x0C);
        //----- Envia terceiro Byte -----
        BITS4(0x06);
        //----- Limpa display -----
        LCD_CLEAR();
        //----- Posiciona cursor -----
        LCD_POSIC_LINHA1(0);
    }
    //------------------------------------------------
    //----- QUEBRA NUMERO (Desmembra os digitos) -----
    //------------------------------------------------
    void QUEBRA_NUMEROS(unsigned char NUMERO)
    {
            DG1_AUX=(NUMERO/100);
            //----- Pega segundo digito -----
            CENTENA=DG1_AUX*100;
            DG2_AUX=NUMERO-CENTENA;
            DG2_AUX=(DG2_AUX/10);
            //----- Pega terceiro digito -----      
            DG3_AUX=CENTENA+DG2_AUX*10;
            DG3_AUX=(NUMERO-DG3_AUX);
            //--- Converte os numeros em ASCLL ---
            DIGITO1=DG1_AUX+48;
            DIGITO2=DG2_AUX+48;        
            DIGITO3=DG3_AUX+48;                        
    }
    //======================================================================
    //================== ESCREVE NUMEROS DE 3 DIGITOS ======================
    //======================================================================
    void WRITE_NUMERO(unsigned char NUMEROS)
    {
        QUEBRA_NUMEROS(NUMEROS);
        WRITE_CARAC(DIGITO1);
        WRITE_CARAC(DIGITO2);
        WRITE_CARAC(DIGITO3);                    
    }
    //============================================================
    //================== ESCREVE CARACTERES ======================
    //============================================================
    void WRITE_CARAC(unsigned char CARACTER)
    {
            EN=1;
            RS=1;
            BITS4(CARACTER);
            EN=0;    
    }
    //======================================================================
    //============================ WAIT LCD ================================
    //======================================================================
    void LCD_WAIT(unsigned char tempo)
    {
        unsigned char conta1=0;
        unsigned char conta2=0;
        unsigned char conta3=0;   
        while(conta1<=tempo)
        {
            conta1++;
            conta2=0;
            while(conta2<=5)
            {
                conta2++;
                conta3=0;
                while(conta3<=25)
                {
                conta3++;
                }
            }   
        }   
    }
    //======================================================================
    //========================= WAIT LCD RAPIDO ============================
    //======================================================================
    void LCD_WAIT_RAPIDO(void)
    {   
    
        unsigned char conta2=0;
        unsigned char conta3=0;
            conta2=0;
            while(conta2<=2)
            {
                conta2++;
                conta3=0;
                while(conta3<=2)
                {
                conta3++;
                }
            }           
    }
    //======================================================================
    //========================== ENVIA NIBBLE ==============================
    //======================================================================
    void BITS4(unsigned char DADO)
    {
        EN=1;
        BYTE_BIT_BIT=DADO;
        DB4=BYTE_BIT_BIT_4;
        DB5=BYTE_BIT_BIT_5;
        DB6=BYTE_BIT_BIT_6;
        DB7=BYTE_BIT_BIT_7; 
        EN=0;
        EN=1;
        BYTE_BIT_BIT=DADO;   
        DB4=BYTE_BIT_BIT_0;
        DB5=BYTE_BIT_BIT_1;
        DB6=BYTE_BIT_BIT_2;
        DB7=BYTE_BIT_BIT_3; 
        EN=0;
        LCD_WAIT_RAPIDO();
        
    }
    //======================================================================
    //============================ CLEAR LCD ===============================
    //======================================================================
    void LCD_CLEAR(void)
    {
        EN=1;
        RS=0;
        BITS4(1);
        EN=0;
        LCD_WAIT(6);
    }
    //======================================================================
    //============================ POSIC LCD ===============================
    //======================================================================
    void LCD_POSIC_LINHA1(char POSIC)
    {   
        RW=0;
        EN=1;
        RS=0;
        BITS4(POSIC + 0x80);
        EN=0;   
        LCD_WAIT(6);
    }
    void LCD_POSIC_LINHA2(char POSIC)
    {   
        RW=0;
        EN=1;
        RS=0;
        BITS4(POSIC + 0xC0);
        EN=0;   
        LCD_WAIT(6);
    }
    
    
    //======================================================================
    //=========================== WRITE TEXT ===============================
    //======================================================================
    void LCD_WRITE(char TEXTO[16])
    {
        int SIZE_LCD;
        int PTR_LCD=0;
        SIZE_LCD=strlen(TEXTO);
        while(SIZE_LCD>=1)
        {
            SIZE_LCD--;
            WRITE_CARAC(TEXTO[PTR_LCD]);
            PTR_LCD++;
            if(ESCRITA_LENTA==1)
            {
                LCD_WAIT(80);
                
            }
        }
    }
    //----------------------------------------------------------------
    //========================= TEMPORIZADOR =========================
    //----------------------------------------------------------------
    void TIMER(unsigned char TEMPO)
    {
        unsigned char CONTA1=0;
        unsigned char CONTA2=0;
        unsigned char CONTA3=0;   
        while(CONTA1<=TEMPO)
        {
            CONTA1++;
            CONTA2=0;
            while(CONTA2<=10)
            {
                CONTA2++;
                CONTA3=0;
                while(CONTA3<=250)
                {
                CONTA3++;
                }
            }   
        }   
    }
    									
    								
    									;################################################################################################
    ;# EMPRESA:            ========== CONTROL CHIP ENGENHARIA ========                              #
    ;# SITE:               http://www.controlchip.com.br                                            #
    ;# E-Mail:             suporte@controlchip.com.br                                               #
    ;#==============================================================================================#
    ;# PROGRAMADOR:        Israel Cortez                                                            #
    ;# DATA DO SOFTWARE:   20/05/2009                                                               #
    ;# VERSÃO ATUAL:       VR3.2                                                                    #
    ;#==============================================================================================#
    ;# Hardware Necessário: CPU-8051-USB / PR-LCD-1602                                              #
    ;#==============================================================================================#
    ;# Descrição:   Este programa exibe mensagens diversas no LCD utilizando soment 1 port          #
    ;#              do microcontrolador (LCD no modo 4 Bits)                                        #
    ;################################################################################################
    ;=========================== CONSTANTES ==========================
    DADO_LCD        EQU  0030H
    LENTO           EQU  31H
    ;=========================== TELAS LCD ===========================               
    MENSAGEM1          EQU     1000
    MENSAGEM2          EQU     1020
    MENSAGEM3          EQU     1040
    MENSAGEM4          EQU     1060
    MENSAGEM5          EQU     1080
    ;---------------------------
    ;------- PINAGEM LCD -------
    ;---------------------------
    RS          EQU     P0.0
    RW          EQU     P0.1
    EN          EQU     P0.2
    PIN4        EQU     P0.4
    PIN5        EQU     P0.5
    PIN6        EQU     P0.6
    PIN7        EQU     P0.7                                     
    ;######################################################################################################
    ;------------------------------------------------------------------------------------------------------
    ;====================================== PROGRAMA PRINCIPAL ============================================
    ;------------------------------------------------------------------------------------------------------
    ;######################################################################################################
    ORG   0000H
    INICIO:
    MOV LENTO,#1
    ;===============================================
    ;================= INICIALIZA LCD ==============
    ;===============================================
    CALL  INICIALIZ_LCD
    CALL  CLEAR_LCD
    MOV   A,#10D
    CALL  TIMER_6ms     
    ;===============================================
    ;=============== ESCREVE TELAS =================
    ;===============================================
    TELAS:
    ;------------------
    ;===== TELA 1 =====
    ;------------------
    CALL  CLEAR_LCD
    ;--- Linha 1 ---
    MOV A,#0
    LCALL POS_LIN1
    MOV   DPTR,#MENSAGEM1
    LCALL WRITESTRING
    ;--- Linha 2 ---
    MOV A,#0
    LCALL POS_LIN2
    MOV   DPTR,#MENSAGEM2
    LCALL WRITESTRING
    MOV A,#150
    CALL TIMER_6ms
    ;------------------
    ;===== TELA 2 =====
    ;------------------
    CALL  CLEAR_LCD
    ;--- Linha 1 ---
    MOV A,#0
    LCALL POS_LIN1
    MOV   DPTR,#MENSAGEM3
    LCALL WRITESTRING
    ;--- Linha 2 ---
    MOV A,#0
    LCALL POS_LIN2
    MOV   DPTR,#MENSAGEM4
    LCALL WRITESTRING
    MOV A,#150
    CALL TIMER_6ms
    ;------------------
    ;===== TELA 3 =====
    ;------------------
    CALL  CLEAR_LCD
    ;--- Linha 1 ---
    MOV A,#0
    LCALL POS_LIN1
    MOV   DPTR,#MENSAGEM5
    LCALL WRITESTRING
    ;--- Linha 2 ---
    MOV A,#0
    LCALL POS_LIN2
    MOV   DPTR,#MENSAGEM5
    LCALL WRITESTRING
    MOV A,#150
    CALL TIMER_6ms
    
    
    
    ;--- INVERTE ESTADO ESCRITA Rapida/Lenta ---
    MOV A,LENTO
    CJNE A,#0,VAI_LENTO
        MOV LENTO,#1
    LJMP TELAS    
    
    VAI_LENTO:
        MOV LENTO,#0
    LJMP TELAS
    
    
    
    
    
    
    
    
    
    
    
    ;#####################################################################################################
    ;-----------------------------------------------------------------------------------------------------
    ;============================================ SUB ROTINAS ============================================
    ;-----------------------------------------------------------------------------------------------------
    ;#####################################################################################################
    ;=================================================================
    ;======================== TEMPORIZADOR 1 =========================
    ;=================================================================
    ;timer ajustado para aproximadamente 6 mili segundos
    TIMER_6ms:          MOV  R0,A
                        CJNE R0,#0,INICIO_TIMER_6ms
                        MOV  R0,#1D
    INICIO_TIMER_6ms:   MOV  R1,#200D
                        MOV  R2,#6D
    REPETE_TEMPO:       NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        NOP
                        DJNZ R1,REPETE_TEMPO
                        MOV  R1,#200D
                        DJNZ R2,REPETE_TEMPO
                        DJNZ R0,INICIO_TIMER_6ms
                        RET
    ;=================================================================
    ;======================== INICIALIZ LCD ==========================
    ;=================================================================
    INICIALIZ_LCD:      CLR  RS
                        CLR  RW
                        CLR  EN
                        SETB EN
                        CLR  PIN4
                        SETB PIN5
                        CLR  PIN6
                        CLR  PIN7
                        CLR  EN
                        MOV  A,#8D
                        CALL TIMER_6ms
    ;Prepara o LCD para trabalhar com 4 bits e 2 linhas
                        CLR  RS
                        MOV  DADO_LCD,#28h
                        CALL ENVIA_NIBBLE
                        MOV  A,#1D
                        CALL TIMER_6ms
    ;----- Envia segundo Byte -----
                        CLR  RS
                        MOV  DADO_LCD,#0Ch      ;Cursor Desabilitado
    ;                    MOV  DADO_LCD,#0Ch     ;Cursor Habilitado
                        CALL ENVIA_NIBBLE
                        MOV  A,#1D
                        CALL TIMER_6ms
    ;----- Envia terceiro Byte -----
                        CLR  RS
                        MOV  DADO_LCD,#06h
                        CALL ENVIA_NIBBLE
                        MOV  A,#1D
                        CALL TIMER_6ms
                        RET
    ;=================================================================
    ;=============== ENVIA NIBBLE (LCD EM MODO 4 BITS) ===============
    ;=================================================================
    ;---- ENVIA 1 NIBBLE ----
    ENVIA_NIBBLE:       SETB EN
                        CLR  PIN4
                        CLR  PIN5
                        CLR  PIN6
                        CLR  PIN7
                        MOV  ACC,DADO_LCD
                        JNB  ACC.4,PIN5_1
                        SETB PIN4
    PIN5_1:             JNB  ACC.5,PIN6_1
                        SETB PIN5
    PIN6_1:             JNB  ACC.6,PIN7_1
                        SETB PIN6
    PIN7_1:             JNB  ACC.7,FIM_NIBLE
                        SETB PIN7
    FIM_NIBLE:          CLR  EN
    ;--------- ENVIA 2 NIBBLE ---------
                        SETB  EN
                        CLR   PIN4
                        CLR   PIN5
                        CLR   PIN6
                        CLR   PIN7
                        MOV   ACC,DADO_LCD
                        JNB   ACC.0,PIN5_2
                        SETB  PIN4
    PIN5_2:             JNB   ACC.1,PIN6_2
                        SETB  PIN5
    PIN6_2:             JNB   ACC.2,PIN7_2
                        SETB  PIN6
    PIN7_2:             JNB   ACC.3,FIM_NIBLE2
                        SETB  PIN7
    FIM_NIBLE2:         CLR   EN
                        CALL  WAIT_LCD
                        RET
    ;=================================================================
    ;========================= WAIT LCD  =============================
    ;=================================================================
    ;ajustado para aproximadamente mili segundo
    WAIT_LCD:           MOV   R7,#50D
                        MOV   R6,#4D
    LOOP:               NOP
                        DJNZ  R7,LOOP
                        MOV   R7,#50D
                        DJNZ  R6,LOOP
                        RET
    ;=================================================================
    ;=========================== CLEAR LCD ===========================
    ;=================================================================
    CLEAR_LCD:          CLR   RS
                        MOV   DADO_LCD,#01h
                        CALL  ENVIA_NIBBLE
                        CALL  WAIT_LCD
                        RET
    
    ;=================================================================
    ;========================= WRITE CARAC ===========================
    ;=================================================================
    WRITE_CARAC:        SETB  RS
                        MOV   DADO_LCD,A
                        LCALL ENVIA_NIBBLE
                        CLR   RS
                        RET
    ;=================================================================
    ;========================== WRITE TEXT ===========================
    ;=================================================================
    WRITESTRING:        MOV   A,#0D
                        MOVC  A,@A+DPTR
                        CJNE  A,#'$',WRITE_NEXT
                        SJMP  FINIS_STRING
    
    WRITE_NEXT:         SETB  RS
                        MOV   DADO_LCD,A
                        LCALL ENVIA_NIBBLE
                        CLR   RS
                        INC   DPTR
                        ;--- Verifica se escrita deve ser lenta ---
                        MOV A,LENTO
                        CJNE A,#1,PULA_TEMPO
                            MOV A,#5
                            CALL TIMER_6ms
    PULA_TEMPO:                    
                        SJMP  WRITESTRING
    
    FINIS_STRING:       CLR   RS
                        RET
    ;=================================================================
    ;=========================== POSIC LCD============================
    ;=================================================================
    POS_LIN1:           CLR  RW
                        CLR  RS
                        ADD  A,#80H
                        MOV  DADO_LCD,A
                        CALL ENVIA_NIBBLE
                        RET
    ;=================================================================
    ;========================= POSIC LCD 2 ===========================
    ;=================================================================
    POS_LIN2:           CLR  RW
                        CLR  RS
                        ADD  A,#192
                        MOV  DADO_LCD,A
                        CALL ENVIA_NIBBLE
                        RET                    
    ;=================================================================
    ;========================= WRITE TEXT 2 ==========================
    ;=================================================================
    ENVIA_NIBBLE2:      SETB EN
                        SETB PIN4
                        SETB PIN5
                        CLR  PIN6
                        CLR  PIN7
                        CLR  EN
    ;--------- ENVIA 2 NIBBLE ---------
                        SETB  EN
                        CLR   PIN4
                        CLR   PIN5
                        CLR   PIN6
                        CLR   PIN7
                        MOV   ACC,DADO_LCD                 
                        JNB   ACC.0,PIN5_22
                        SETB  PIN4
    
    PIN5_22:            JNB   ACC.1,PIN6_22
                        SETB  PIN5
    
    PIN6_22:            JNB   ACC.2,PIN7_22
                        SETB  PIN6
    
    PIN7_22:            JNB   ACC.3,FIM_NIBLE22
                        SETB  PIN7
    
    FIM_NIBLE22:        CLR   EN
                        CALL  WAIT_LCD
                        RET                                                                                
    ;==========================================================
    ;============ TEXTOS A SEREM ESCRITOS NO LCD ==============
    ;==========================================================
    org MENSAGEM1
    DB 'PROGRAMA EXEMPLO$'
    org MENSAGEM2
    DB 'MOD  PR-LCD-1602$'
    org MENSAGEM3
    DB ' CONTROL  CHIP  $'
    org MENSAGEM4
    DB '   ENGENHARIA   $'
    org MENSAGEM5
    DB '  Hello  Word   $'
    END
    									
    								

    VENHA TRABALHAR COM A GENTE