Ir ao conteúdo

Posts recomendados

Postado

 

Boa tarde, estou tendo um problema em relação a um código para a faculdade. Esse código deve ser feito em assembly e execultado no software MCU 8051 IDE e a atividade é dividida em duas partes. Na primeira parte da atividade é necessário desenvolver um código que utiliza as interrupções externas por transição para realizar as tarefas descritas a seguir. São contagens a serem mostradas em 2 displays de 7-segmentos conectados à Porta P2, através de 2 drivers CD4511.

(a)    Interrupção 0: contagem decimal crescente de 50 até retornar para 50.

Ilustração: 50, 50+1, 50+2,...., 99, 00, 01, .... 50

(b)    Interrupção 1: contagem decimal decrescente de 84 até retornar a 84. 

Ilustração: 84, 84-1, 84-2,...., 00, 01, .... 84

Essa parte do código funcionou perfeitamente e segue anexo como c1, já na segundo pede que repita a atividade 1, mostrando o resultado no display LCD. Na primeira linha do display deve ser mostrado o nome do aluno. As contagens devem ser mostradas na linha 2.
A linha 1 está funcionando perfeitamente, já a linha 2 não exibe a contagem. Segue anexo o código como c2 e o arquivo de simulação de proteus.
Se alguém puder ajudar ficarei muto grato.

.

 

 

  • Membro VIP
Postado

Vou tentar... Dei uma olhadela rápida no seu assembly focando em...

2 horas atrás, guilherme23 disse:

A linha 1 está funcionando perfeitamente, já a linha 2 não exibe a contagem.

Achei a função pra linha1...

Em 06/10/2024 às 15:40, guilherme23 disse:
; --- Rotina para escrever a mensagem na primeira linha do LCD ---
LINHA1:
    MOV DPTR, #MSG1         ; Aponta para a mensagem
    MOV R2, #00h            ; Inicializa o índice da mensagem
ESCREVE_LINHA1:
    MOV A, R2
    MOVC A, @A+DPTR          ; Carrega caractere da string
    CJNE A, #0FFh, ESCREVE_CHAR ; Verifica se não é o terminador
    RET

ESCREVE_CHAR:
    LCALL TEXTO_WR           ; Escreve caractere no LCD
    INC R2                   ; Incrementa o índice
    SJMP ESCREVE_LINHA1       ; Continua escrevendo

Pra escrever na linha 1 você tem que enviar o comando (RS em 0) com o dado 0x80 ou #80h e pra linha 2 0xc0 ou #c0h. Onde está definindo isso?...

O que eu (eu) faço é definir coluna e linha no comando algo como setpos(x,y). Mas eu (eu) faço isso numa tacada só tipo

display(3,4,"texto"); Faça o mesmo no assembly e .. ah... vi agora

; --- Rotina para atualizar o LCD com a contagem crescente ---
DISPLAY1:
    MOV A, #196            ; Comando para posição 0 da segunda linha

e

; --- Rotina para atualizar o LCD com a contagem decrescente ---
DISPLAY2:
    MOV A, #196            ; Comando para posição 0 da segunda linha

Parece que você tentou posicionar seu texto na 2ª linha e 4ª (e não 0) coluna (0xc4) nos 2 casos, certo? Dá uma olhadela no d.s. do display e confirme que são linha1 0x80 e linha2 0xc0 por gentileza

Postado

@.if foi esse posicionamento mesmo

; Definições de pinos do LCD
RS      EQU P3.5   ; Pino RS do LCD
RW      EQU P3.6   ; Pino RW do LCD
EN      EQU P3.7   ; Pino EN do LCD
LCD     EQU P0     ; Pinos de dados do LCD

ORG 00H         
LJMP INICIO       

ORG 03H
SJMP CRESCENTE     

ORG 13H
SJMP DECRESCENTE

ORG 30H
INICIO: 
    MOV TCON, #05H       ; Habilita interrupção 0 e 1 por transição
    MOV IE, #85H         ; Habilita interrupção externa e global
    MOV P2, #00H         ; Limpa o display
    LCALL INICIA_LCD     ; Inicializa o LCD
    MOV R0, #00H         ; Inicializa contagem crescente (0)
    MOV R1, #FFH         ; Inicializa contagem decrescente (255)
    SJMP $                ; Loop infinito

; --- Rotina para inicializar o LCD ---
INICIA_LCD:
    MOV A, #38H          ; Configura o modo de 8 bits
    LCALL INSTR_WR       ; Envia comando
    MOV A, #0EH          ; Liga o display e o cursor
    LCALL INSTR_WR       ; Envia comando
    MOV A, #01H          ; Limpa o display
    LCALL INSTR_WR       ; Envia comando
    MOV A, #06H          ; Modo de entrada: desloca para a direita
    LCALL INSTR_WR       ; Envia comando
    RET

; --- Rotina para escrever comandos no LCD ---
INSTR_WR:
    CLR RS               ; Define modo de comando
    CLR RW               ; Define modo de escrita
    SETB EN              ; Habilita o LCD
    MOV LCD, A           ; Envia comando para o LCD
    CLR EN               ; Desabilita o LCD
    LCALL ATRASO_LCD     ; Chama a rotina de atraso
    RET

; --- Rotina para escrever texto no LCD ---
TEXTO_WR:
    SETB RS              ; Define que é dado
    CLR RW               ; Define modo de escrita
    SETB EN              ; Habilita o LCD
    MOV LCD, A           ; Envia dado para o LCD
    CLR EN               ; Desabilita o LCD
    LCALL ATRASO_LCD     ; Chama a rotina de atraso
    RET

; --- Interrupção INT0: contagem crescente ---
CRESCENTE:
    MOV A, R0
    ADD A, #01H          ; Incrementar o valor de A
    CJNE A, #100H, ATUALIZA_LCD ; Se A < 100H (255 decimal), atualizar display
    MOV A, #00H          ; Reiniciar contagem se A >= 100H
    MOV R0, A            ; Reiniciar contagem crescente
    SJMP ATUALIZA_LCD    ; Atualiza o LCD com o novo valor

; --- Atualiza o LCD com os valores atuais ---
ATUALIZA_LCD:
    ; Limpa o display antes de escrever novos valores
    MOV A, #01H          ; Comando para limpar o display
    LCALL INSTR_WR       ; Envia comando para limpar o LCD
    ; Escreve a contagem crescente
    MOV A, R0            ; Pega o valor da contagem crescente
    ADD A, #30H          ; Converte para ASCII
    LCALL TEXTO_WR       ; Chama a rotina para escrever no LCD

    ; Escreve um espaço ou outra string para separar os valores
    MOV A, #20H          ; Código ASCII para espaço
    LCALL TEXTO_WR       ; Adiciona espaço entre os valores

    ; Escreve a contagem decrescente
    MOV A, R1            ; Pega o valor da contagem decrescente
    ADD A, #30H          ; Converte para ASCII
    LCALL TEXTO_WR       ; Chama a rotina para escrever no LCD
    RETI                  ; Retorno da interrupção

; --- Interrupção INT1: contagem decrescente ---
DECRESCENTE:
    MOV A, R1
    CJNE A, #00H, DECREMENTA ; Se R1 >= 00h, atualizar display
    MOV A, #FFH           ; Reiniciar contagem para 255H após 00
    MOV R1, A            ; Atualiza o registrador de contagem decrescente
    SJMP ATUALIZA_LCD     ; Atualiza o LCD com o novo valor

DECREMENTA:
    ADD A, #0FFH          ; Decrementar o valor de A
    DA A
    MOV R1, A            ; Atualiza o registrador de contagem decrescente
    SJMP ATUALIZA_LCD     ; Atualiza o LCD com o novo valor

; --- Sub-rotina de atraso para operações ---
ATRASO_LCD: 
    MOV R3, #200         ; Ajuste para obter aproximadamente 100 ms de atraso
ATRASO_LOOP1:
    MOV R2, #230
ATRASO_LOOP2:
    DJNZ R2, ATRASO_LOOP2
    DJNZ R3, ATRASO_LOOP1
    RET

END  ; Diretiva END adicionada para finalizar o código

 

Repostei o código, pois a publicação foi apagada.

  • Membro VIP
Postado

ok.. mostre agora as funções em que você escreve na 1ª e 2ª linha, explique como você define linha e coluna, mostre o que não funciona e o que funciona, mostre um Vídeo simulação do problema - eu uso o vokoscreen https://linuxecke.volkoh.de/vokoscreen/vokoscreen.html e o https://imgur.com/upload  pra mostrar aqui

Lembrando que o foco continua sendo ...

21 horas atrás, guilherme23 disse:

A linha 1 está funcionando perfeitamente, já a linha 2 não exibe a contagem.

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...