Microcontrolador 8051 - display 7 segmentos

  • Descrição:
  • Este experimento visa demonstrar de forma visual a técnica de multiplexação por meio do módulo PR-7SEG-4 sendo controlador pelo microcontrolador 8051.
    Ao ser iniciado, o programa exibira no módulo PR-7SEG-4 números partindo do 0 e indo até 255.
    Durante a contagem, haverá pausas no incremento, onde então a frequência de amostragem cairá, ficando bem visual a multiplexação.
    Após a diminuição da frequência de amostragem, voltará a subir gradativamente, até não sermos capazes de enxergar os segmentos piscando.
    Após isso o programa voltará a incrementar os números até a próxima pausa.

    Módulos utilizados:
    • CPU-8051-USB
    • PR-7SEG-4
    Procedimento:
    1. Grave o programa do experimento na CPU-8051-USB.
    2. Conecte o CN1 do módulo PR-7SEG-4 no port P0 da CPU-8051-USB
    3. Conecte o CN2 do módulo PR-7SEG-4 no port P2 da CPU-8051-USB
    4. Pressione e solte o botão Reset da CPU-8051-USB para iniciar a contagem.
    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.5                                                                    #
    //------------------------------
    //========== INCLUDES ==========
    //------------------------------
    #include "8051.H"                      //Flags do 8051
    //--------------------------------
    //========== PROTITIPOS ==========
    //--------------------------------
    void TRATA_TIMER0(void) interrupt 1;
    void SOBRE_FREQ(void);
    void DISP1(void);
    void DISP2(void);
    void DISP3(void);
    void DISP4(void);
    void DISP_NENHUM(void);
    void QUEBRA_NUMEROS(unsigned char);
    void TIMER(unsigned char);
    unsigned char CONV_7SEG(unsigned char);
    //--------------------------------------------
    //========== VARIAVEIS DE USO GERAL ==========
    //--------------------------------------------
    //--- timer manual ---
    unsigned char CONTA1=0;
    unsigned char CONTA2=0;
    unsigned char CONTA3=0;
    //--- PERIFERICO T0 ---
    unsigned char T0_HIGH=0;
    //--- Vars auxiliares na multiplexação ---
    unsigned char CONTADOR=0;
    unsigned char MULTIPLEX=0;
    //--- Quebra numeros ---
    unsigned char DIGITO1;
    unsigned char CENTENA;
    unsigned char DG2_AUX;
    unsigned char DIGITO2;
    unsigned char DG3_AUX;
    unsigned char DIGITO3;
    
    
    //#############################################################
    //-------------------------------------------------------------
    //=========================== MAIN ============================
    //-------------------------------------------------------------
    //#############################################################
    void main (void)
    {
        //-----------------------------------------------------
        //================== PARAMETRIZAÇÃO ===================
        //-----------------------------------------------------
        T0_HIGH=240;    //Inicializa var a ser carregada na parte alta do Timer 0
        IE=0x82;        //Interrupcoes (T0) habilitado
        TMOD=0x01;      //;TIMER 0 no modo 1 (16 bits)
        TL0=0x00;       //Carrega Tempo no Timer (Parte baixa)
        TH0=T0_HIGH;    //Carrega Tempo no Timer (Parte alta)
        TR0=1;          //Start Timer
        
        //----- Loop infinito -----
        while (1)
        {      
            CONTADOR++;
            QUEBRA_NUMEROS(CONTADOR);
            //--- Trava em 53 ---
            if(CONTADOR==53)
            {
                SOBRE_FREQ();
            }
            //--- Trava em 101 ---
            if(CONTADOR==101)
            {
                SOBRE_FREQ();
            }
            //--- Trava em 213 ---
            if(CONTADOR==213)
            {
                SOBRE_FREQ();
            }
            //--- Trava em 255 ---
            if(CONTADOR==255)
            {
                SOBRE_FREQ();
            }                        
            TIMER(1);    
            
        }
    }
    
    //#############################################################
    //-------------------------------------------------------------
    //======================= SUB ROTINAS =========================
    //-------------------------------------------------------------
    //#############################################################
    //--------------------------------------------------------
    //----- Diminui a freq, e vai subindo gradativamente -----
    //--------------------------------------------------------
    void SOBRE_FREQ(void)
    {
        T0_HIGH=00;     
        TIMER(100);
        T0_HIGH=130;
        TIMER(80);
        T0_HIGH=190;
        TIMER(70);
        T0_HIGH=220;
        TIMER(60);
        T0_HIGH=240;
        TIMER(50);        
    }
    //------------------------------------------------
    //----- TRATAMENTO DA INTERRUPCAO DO TIMER 0 -----
    //------------------------------------------------
    void TRATA_TIMER0(void) interrupt 1
    {    
        MULTIPLEX++;
        // ----- MOSTRA DIGITO 1 (Sempre 0) -----
        if(MULTIPLEX==1)
        {
            DISP_NENHUM();
            P0=CONV_7SEG(0);
            DISP1();
        }
        // ----- MOSTRA DIGITO 2 -----
        if(MULTIPLEX==2)
        {
            
            DISP_NENHUM();
            P0=CONV_7SEG(DIGITO1);
            DISP2();
        }
        // ----- MOSTRA DIGITO 3 -----
        if(MULTIPLEX==3)
        {
            DISP_NENHUM();
            P0=CONV_7SEG(DIGITO2);
            DISP3();
        }
        // ----- MOSTRA DIGITO 4 -----
        if(MULTIPLEX>=4)
        {
            DISP_NENHUM();
            P0=CONV_7SEG(DIGITO3);
            DISP4();
            MULTIPLEX=0;        
        }       
        //--- Reinicia Timer ---        
        TH0=T0_HIGH;
        TL0=0x00;   
    }
    //------------------------------------------------
    //----- QUEBRA NUMERO (Desmembra os digitos) -----
    //------------------------------------------------
    void QUEBRA_NUMEROS(unsigned char NUMERO)
    {
            DIGITO1=(NUMERO/100);
            //----- Pega segundo digito -----
            CENTENA=DIGITO1*100;
            DG2_AUX=NUMERO-CENTENA;
            DIGITO2=(DG2_AUX/10);
            //----- Pega terceiro digito -----      
            DG3_AUX=CENTENA+DIGITO2*10;
            DIGITO3=(NUMERO-DG3_AUX);
    }
    //------------------------------------------------------------
    //========== CONVERSAO DOS NUMEROS P/ DISPLAY 7 SEGM =========
    //------------------------------------------------------------
    unsigned char CONV_7SEG(unsigned char NUMERO)
    {
        if(NUMERO==0)
        {return 192;}
        if(NUMERO==1)
        {return 249;}
        if(NUMERO==2)
        {return 164;}
        if(NUMERO==3)
        {return 176;}
        if(NUMERO==4)
        {return 153;}
        if(NUMERO==5)
        {return 146;}
        if(NUMERO==6)
        {return 130;}
        if(NUMERO==7)
        {return 248;}
        if(NUMERO==8)
        {return 128;}
        if(NUMERO==9)
        {return 144;}       
    }
    //----------------------------------------------------------------
    //======================== HAB DOS DIGITOS =======================
    //----------------------------------------------------------------
    void DISP_NENHUM(void)
    {
        P2_7=1;
        P2_6=1;
        P2_5=1;       
        P2_4=1;                           
    }
    void DISP1(void)
    {
        P2_7=0;
        P2_6=1;
        P2_5=1;       
        P2_4=1;                           
    }
    void DISP2(void)
    {
        P2_7=1;
        P2_6=0;
        P2_5=1;       
        P2_4=1;                           
    }
    void DISP3(void)
    {
        P2_7=1;
        P2_6=1;
        P2_5=0;       
        P2_4=1;                           
    }
    void DISP4(void)
    {
        P2_7=1;
        P2_6=1;
        P2_5=1;       
        P2_4=0;                           
    }      
    //----------------------------------------------------------------
    //========================= TEMPORIZADOR =========================
    //----------------------------------------------------------------
    void TIMER(unsigned char TEMPO)
    {
        CONTA1=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                                            #
    ;#==============================================================================================#
    ;# PROGRAMADOR:        Israel Cortez                                                            #
    ;# DATA DO SOFTWARE:   20/05/2009                                                               #
    ;# VERSÃO ATUAL:       VR3.5                                                                    #
    ;#==============================================================================================#
    ;# Hardware Necessário: CPU-8051-USB / PR-7SEG-4                                                #
    ;#==============================================================================================#
    DIGITO_1        EQU 31
    DIGITO_2        EQU 32
    AUX_DIGITO_2    EQU 33
    DIGITO_3        EQU 34
    DIGITO_4        EQU 35
    SALVA_A         EQU 36
    MULTIPLEX       EQU 37
    NUM_A_ESCREVER  EQU 38
    NUMERO          EQU 39
    TEMPO           EQU 40
    T0_HIGH         EQU 41
    
    TABELA_7SEG     EQU 600
    ;=======================================
    ;===== TRATAMENTO DAS INTERRUPÇÕES =====
    ;=======================================
    ORG     00H
    LJMP    INICIO
    ORG     0BH
    LJMP    INTERRUPCAO_TIMER_0
    ;-----------------------------------------------------
    ;================== PARAMETRIZAÇÃO ===================
    ;-----------------------------------------------------
    INICIO:
    MOV T0_HIGH,#100
    MOV MULTIPLEX,#0    ;Inicializa multiplexador
    MOV IE,#82H         ;Interrupcoes (T0) habilitado
    MOV     TMOD,#1H    ;TIMER 0 no modo 1 (16 bits)
    MOV TL0,#0          ;Carrega Tempo no Timer (Parte baixa)
    MOV TH0,T0_HIGH     ;Carrega Tempo no Timer (Parte alta)
    SETB TR0            ;Start Timer         
    MOV A,#0
    ;-----------------------------------------------------
    ;============== SEQUENCIA DE CONTAGEM ================
    ;-----------------------------------------------------
    MOV NUM_A_ESCREVER,A
    CALL SOBRE_FREQ
    LOOP_INFINITO: 
        MOV NUM_A_ESCREVER,A    
        ;--- Trava em 53 ---
        CJNE A,#53,VERIF_101
        CALL SOBRE_FREQ
        ;--- Trava em 101 ---
    VERIF_101:
        CJNE A,#101,VERIF_213
        CALL SOBRE_FREQ
        ;--- Trava em 213 ---
    VERIF_213:
        CJNE A,#213,VERIF_255
        CALL SOBRE_FREQ    
        ;--- Trava em 255 ---
    VERIF_255:
        CJNE A,#255,INCREMENTA
        CALL SOBRE_FREQ            
        ;--- Incrementa ---
    INCREMENTA:            
        INC A
        MOV TEMPO,#1
        CALL TIMER_1    
    LJMP LOOP_INFINITO  ;Fica nesse loop p/ sempre
    
        
    ;================================================================
    ;========= MOSTRA FREQ BAIXA E VAI SUBINDO GRADATIVO ============
    ;================================================================    
    SOBRE_FREQ:
        ;-------------
        MOV T0_HIGH,#0
        MOV TEMPO,#25
        CALL TIMER_1
        ;-------------
        MOV T0_HIGH,#100
        MOV TEMPO,#24
        CALL TIMER_1
        ;-------------
        MOV T0_HIGH,#160
        MOV TEMPO,#23
        CALL TIMER_1
        ;-------------    
        MOV T0_HIGH,#190
        MOV TEMPO,#22
        CALL TIMER_1
        ;-------------    
        MOV T0_HIGH,#215
        MOV TEMPO,#22
        CALL TIMER_1   
        ;-------------    
        MOV T0_HIGH,#255
        MOV TEMPO,#20
        CALL TIMER_1
    RET       
           
        
        
    
    ;================================================================
    ;============= ATENDIMENTO DA INTERRUPCAO TIMER 0 ===============
    ;================================================================
    INTERRUPCAO_TIMER_0:
    MOV SALVA_A,A       ;Salva conteudo de A
    MOV R7,MULTIPLEX
    ; ----- MOSTRA DIGITO 1 -----
    CJNE R7,#0,DIGITO2                  
           MOV  A,#0
           MOV  DPTR,#TABELA_7SEG
           MOVC A,@A+DPTR       
           CALL DISP_NENHUM
           MOV  P0,A    
           CALL DISP1       
    ; ----- MOSTRA DIGITO 2 -----
    DIGITO2:         
    CJNE R7,#1,DIGITO3
           MOV  A,NUM_A_ESCREVER
           CALL QUEBRA_NUMEROS
           MOV  A,DIGITO_1
           MOV  DPTR,#TABELA_7SEG
           MOVC A,@A+DPTR       
    
           CALL DISP_NENHUM
           MOV  P0,A    
           CALL DISP2       
           LJMP FIM
    ; ----- MOSTRA DIGITO 3 -----
    DIGITO3:         
    CJNE R7,#2,DIGITO4
           MOV  A,NUM_A_ESCREVER
           CALL QUEBRA_NUMEROS
           MOV  A,DIGITO_2
           MOV  DPTR,#TABELA_7SEG
           MOVC A,@A+DPTR       
           CALL DISP_NENHUM       
           MOV  P0,A    
           CALL DISP3       
           LJMP FIM  
    ; ----- MOSTRA DIGITO 4 -----
    DIGITO4:
    CJNE R7,#3,FIM
           MOV  A,NUM_A_ESCREVER
           CALL QUEBRA_NUMEROS
           MOV  A,DIGITO_3
           MOV  DPTR,#TABELA_7SEG
           MOVC A,@A+DPTR       
           CALL DISP_NENHUM              
           MOV  P0,A    
           CALL DISP4       
           LJMP FIM        
    ;--- Incrementa/Zera Controle dos 4 digitos (R7) ---
    FIM:   
    MOV A,R7    
    INC A   
    CJNE A,#4,NAO_ZERA
        MOV A,#0
    NAO_ZERA:
    MOV MULTIPLEX,A
    MOV A,SALVA_A       ;Devolve conteudo de A    
    MOV TL0,#0          ;Carrega Tempo no Timer (Parte baixa)
    MOV TH0,T0_HIGH ;Carrega Tempo no Timer (Parte baixa)
    SETB    TR0         ;Restart Timer  
    RETI
    ;==============================
    ;========= Display 1 ==========
    ;==============================
    DISP1:  CLR P2.7
            SETB P2.6
            SETB P2.5       
            SETB P2.4                       
            RET
    ;==============================
    ;========= Display 2 ==========
    ;==============================        
    DISP2:  SETB P2.7
            CLR P2.6
            SETB P2.5       
            SETB P2.4 
            RET
    ;==============================
    ;========= Display 3 ==========
    ;==============================        
    DISP3: SETB P2.7
            SETB P2.6
            CLR P2.5       
            SETB P2.4 
            RET
    ;==============================
    ;========= Display 4 ==========
    ;==============================        
    DISP4:  SETB P2.7
            SETB P2.6
            SETB P2.5       
            CLR P2.4                                                               
            RET
    ;==============================
    ;====== Nenhum Display ========
    ;==============================        
    DISP_NENHUM:  SETB P2.7
            SETB P2.6
            SETB P2.5       
            SETB P2.4
            RET        
    ;=================================================================
    ;======================= QUEBRA NUMEROS ==========================
    ;=================================================================
    ;-------------------------------------
    ;--- CAPTURA DIGITOS SEPARADAMENTE ---
    ;-------------------------------------
    QUEBRA_NUMEROS:
    MOV NUMERO,A                         ;Reserva o conteudo de A
    ;----- Digito 1 -----
    MOV B,#100
    DIV AB
    MOV DIGITO_1,A
    ;----- Digito 2 -----
    MOV A,DIGITO_1
    MOV B,#10
    MUL AB
    MOV AUX_DIGITO_2,A
    MOV A,NUMERO
    MOV B,#10
    DIV AB
    MOV B,R0                ;Guarda o conteudo de R0
    MOV R0,AUX_DIGITO_2      
    SUBB A,R0
    MOV R0,B                ;Volta com o conteudo de R0
    MOV DIGITO_2,A
    ;----- Digito 3 -----
    MOV B,#10
    MOV A,NUMERO
    DIV AB
    MOV B,#10
    MUL AB
    MOV B,R0                ;Guarda o conteudo de R0
    MOV R0,A
    MOV A,NUMERO
    SUBB A,R0
    MOV R0,B                ;Volta com o conteudo de R0
    MOV DIGITO_3,A
    RET
    
    ;================================================================
    ;======================== TEMPORIZADOR ==========================
    ;================================================================
    TIMER_1:
    MOV R4,TEMPO
    INICIO_TIMER1:
    MOV R6,#50
    MOV R5,#100        
    REPETE_TEMPO:
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    NOP     ;1uS
    DJNZ R5,REPETE_TEMPO
    MOV R5,#100
    DJNZ R6,REPETE_TEMPO
    DJNZ R4,INICIO_TIMER1
    RET
    
    ;=================================================================
    ;=================== TABELA P/ DISPLAY LCD =======================
    ;=================================================================                    
    org TABELA_7SEG
    ; ----- (0) -----
    DB 192    
    ; ----- (1) -----
    DB 249    
    ; ----- (2) -----
    DB 164    
    ; ----- (3) -----
    DB 176    
    ; ----- (4) -----
    DB 153    
    ; ----- (5) -----
    DB 146    
    ; ----- (6) -----
    DB 130    
    ; ----- (7) -----
    DB 248    
    ; ----- (8) -----
    DB 128    
    ; ----- (9) -----
    DB 144    
    
    
    END
    									
    								

    VENHA TRABALHAR COM A GENTE