Você está na página 1de 13

Universidade Federal de Mato Grosso - UFMT

Faculdade de Arquitetura, Engenharia e Tecnologia - FAET


Departamento de Engenharia Elétrica
Microprocessadores – 2018/1

Laboratório 6: Temporizadores e Aritmética com PIC


Objetivos: Entender os procedimentos para executar processos, em períodos de tempo
programados, através de mecanismos de interrupção ativados pelo transbordo de temporizadores
(TMR0 ou TMR1). Estudar os procedimentos para projetar e implementar contadores BCD em
displays de 7 segmentos, ativados mediante mecanismos de multiplexação no tempo. Estudar e
implementar o processamento de operações aritméticas de precisão simples. O aluno deve
conhecer a utilização de bibliotecas aritméticas para: adição, subtração, multiplicação e divisão.
Assim, serão implementados temporizadores (RTC) e uma calculadora básica. Como dispositivo de
entrada será usado um teclado básico e como dispositivos de saídas: Display´s de 7 segmentos e
um Display de Cristal Líquido (LCD). Os testes experimentais devem ser realizados no módulo
didático PIC-2377.

1) Displays de 7 segmentos
Na Figura 1 é mostrado como os displays estão ligados no módulo didático. Ligue os jumpers e
as chaves conforme indicado na Tabela a seguir:
Dispositivo sob teste Jumper ON Chaves ON Jumper OFF Chaves OFF
Displays de 7seg J3 – B CH4(1-8), CH6(1-4) J4 As demais chaves

5V
10k RB3
RA5
RB2

PIC16F877A
RE2
RB1
RE1 RB0

RE0
UMIL CENT DEZE UNID 330 RC3
a a RD7
b RD6 RC2
f b c RD5
g d RD4 RC1
e RD3
e c f RC0
g RD2
d p RD1
RD0
DP-4 DP-3 DP-2 DP-1
Figura 1 - Circuito esquemático de conexões de PIC com os Displays de 7 segmentos.

2) Teclado Básico e LCD (Hitachi hd44780)


RB3
RD0
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F RB2
RD1
PIC16F877A

RB1
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
RD2
RB0
RD3

RD4 RC3 on 0 = +
RD5 RC2 1 2 3 -
RD6 RC1 4 5 6 ×
RS=0, para envio de comando RS=1, para envio de caractere
RW=0, operação de escrita RW=1, operação de leitura RD7 RC0 7 8 9 ÷
E =1, habilita operação
O esquemático mostra uma conexão simplificada do teclado básico e LCD com o µC PIC. Neste
laboratório, o teclado básico será utilizado para digitar números em BCD e escolher operações
aritméticas básicas. No LCD serão mostradas as informações de mensagens, dados e resultados
das operações.
Dispositivos sob teste Jumper Chaves ON (para cima)
Display LCD J3 off, J4 - B CH4(1 – 8), CH6(1 – 2)
Teclado básico 4x4 CH3(1– 4), CH5(1– 4)

O módulo didático PIC-2377 possui um LCD 16x2, compatível com controlador HD44780. Os
pinos: RE0 e RE1, do µC, são utilizados para controlar o envio de informação para o LCD.
No LCD podem ser mostradas duas linhas de caracteres, sendo que os códigos ASCII dos
caracteres a serem mostrados, devem estar armazenados em determinados endereços de uma
RAM do LCD. As faixas de endereços que correspondem a cada linha são: 0x80 – 0x8E para a
linha1 e 0xC0 – 0xCF para a linha 2.
Exemplo:
movlw 0x80
Posiciona o apontador do LCD no endereço 0x80 (1° endereço da linha 1)
call EnviaCmdLCD
movlw ‘A’ Mostra o caractere “A” no começo da linha 1. Além disso, o apontador do LCD
call EnviaCarLCD é auto incrementado em 1, apontando neste caso, para o endereço 0x81

3) Temporizador Timer-0 (TMR0)


TMR0 é um registrador contador binário de 8 bits, que pode ser utilizado de 02 formas:
a) Como contador: Para contagem de eventos externos. Nesse caso, a entrada de clock do registrador é
aplicada por meio do pino RA4/T0CKI do µC PIC.
b) Como Temporizador: Quando a entrada de clock do registrador é proveniente do clock do sistema
(FCLOCK / 4).
FOSC/4
Bus de dados

8
0 M
pino U
1 M
RA4/T0CKI
X U Reg TMR0
1 Prescalador 8 bits: X
2,4,8,16,32,64,128,256 0
T0SE
T0CS INTCON<T0IF>=1
PS2:PS0 PSA se TMR0 transborda

Sempre que acontecer um transbordo de TMR0 (255 para 0), é ativado o flag (sinal) T0IF, sinalizando um
evento de interrupção. Mas, se INTCON<T0IE> = 1, será disparado uma interrupção por transbordo de
TMR0.
O prescalador (prescaler) é um divisor de frequência programável, utilizado para reduzir a frequência do
sinal de clock aplicado ao Timer 0.
OPTION_REG Registrador usado para definir a fonte de clock de TMR0 e valor de prescaler
R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1
RBPU’ INTDEG T0CS T0SE PSA PS2 PS1 PS0
bit 7 0: clock/4 0: presc-T0 bit 0
PS2:PS1:PS0 = 000, 001, 010, 011, 100, 101, 110, 111, define os seguintes valores de prescaler: 2, 4, 8,
16, 32, 64, 128, 256, respectivamente.
INTCON Registrador usado para definir a fonte e os flags de interrupção
R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1
GIE PEIE T0IE INTE RBIE T0IF INTF RBIF
bit 7 bit 0
INTCON<GIE> bit de habilitação global de interrupções. Se é setado, habilitará as interrupções por
transbordo de TMR0.
4) Temporizador Timer-1 (TMR1)
TMR1 é um registrador contador binário de 16 bits, composta de 2 registradores de 8 bits: TMR1H:TMR1L.
Pode ser utilizado de 02 formas:
c) Como contador: Para contagem de eventos externos. Nesse caso, a entrada de clock do registrador é
aplicada por meio dos pinos RC0/T1OSO/T1CKI ou RC1/T1OSI/CCP2 do µC PIC.
d) Como Temporizador: Quando a entrada de clock do registrador é proveniente do clock do sistema
(FCLOCK / 4).
FOSC/4 PIE1<TMR1IE>=1 Þ TMR1 dispara interrupção
b0
0
M TMR1 – 16b
Prescalador:
pino 0 U
M 1 1,2,4,8 TMR1H TMR1L
RC0 X
U
1 X
RC1 b0
T1CKPS1:T1CKPS0 PIR1<TMR1IF>=1
TMR1CS TMR1ON se TMR1 transborda
T1OSCEN

Sempre que acontecer um transbordo de TMR1 (de 65535 para 0), é ativado o flag PIR1<TMR1IF>,
sinalizando um evento de interrupção. Mas, se PIE1<TMR1IE> = 1, será disparado uma interrupção por
transbordo de TMR1.
T1CON Registrador usado para definir a fonte de clock de TMR1 e valor de prescaler
U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
---- ---- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC’ TMR1CS TMR1ON
bit 7 0: clock/4 bit 0
T1CKPS1:T1CKPS0 = 00, 01, 10, 11, define os seguintes valores de prescaler: 1, 2, 4 e 8, respectivamente.
INTCON Registrador usado para definir a fonte e os flags de interrupção
R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1
GIE PEIE T0IE INTE RBIE T0IF INTF RBIF
bit 7 bit 0
Setando os bits INTCON<GIE:PEIE>=11, fica habilitada as interrupções por transbordo de TMR1.
5) Configuração da frequência com que ocorrem as interrupções por transbordo de TMR0
Considerando um FCLOCK = 16MHz, sem prescalador, cada incremento de TMR0 será realizado em
intervalos de tempo definidos por (4×TCLOCK) = (250ns). Portanto, um ciclo completo de 256 incrementos
será realizado em (250ns)×256 = 64 µs.
Considerando um FCLOCK = 16MHz e um prescalador = 256, cada incremento de TMR0 será realizado em
intervalos de tempo definidos por (4×TCLOCK)×256 = (250ns)×256 = 64 µs. Então, um ciclo completo de
256 incrementos será realizado em (64 µs)×256 = 16,3844 ms.
Assim, através do transbordo de TMR0 será possível disparar interrupções em períodos máximos de 16,384
ms. Portanto, para executar eventos periódicos em intervalos de tempo maiores, será necessário disparar
interrupção várias vezes e, através de um contador, acumular o tempo, cada vez que TMR0 disparar
interrupção.
Exemplo: Uso de TMR0 para disparar eventos periódicos cada segundo. Considere FCLOCK = 16MHz e
prescalador = 256.
(Nº de passos de TMR0)×(FATOR)×64 µs = 1 s.
Solução: cada 125 interrupções por transbordo de TMR0 haverá transcorrido 1 seg.
o Nº de passos de TMR0 = 125 Þ valor inicial de TMR0 = 256 – 125 = 131
o FATOR = 125
6) Configuração da frequência com que ocorrem as interrupções por transbordo de TMR1
Considerando um FCLOCK = 16MHz, um prescalador = 1, cada incremento de TMR1 será realizado em
intervalos de tempo definidos por (4×TCLOCK) = (250ns). Portanto, um ciclo completo de 65536 incrementos
será realizado em (250ns)×65536 = 16,3844 ms.
Considerando um FCLOCK = 16MHz e um prescalador = 8, cada incremento de TMR1 será realizado em
intervalos de tempo definidos por (4×TCLOCK)×8 = (250ns)×8 = 2 µs. Então, um ciclo completo de 65536
incrementos será realizado em (2 µs)×65536 = 131,072 ms. Nota-se que, nessas condições, será necessário
disparar pelo menos 8 interrupções para acumular um tempo de 1 seg.
Assim, para executar eventos periódicos em intervalos de tempo maiores, será necessário disparar
interrupção várias vezes e, através de um contador, acumular o tempo, cada vez que TMR1 disparar
interrupção.
Exemplo: Uso de TMR1 para disparar eventos periódicos cada segundo. Considere FCLOCK = 16MHz e
prescalador = 8.
(Nº de passos de TMR1)×(FATOR)×2 µs = 1 s.
Solução: se TMR1 disparar interrupção cada 50.000 incrementos, então, serão necessários 10 interrupções,
por transbordo de TMR1, para acumular um tempo de 1 seg.
ü Nº de passos de TMR1 = 50.000 Þ valor inicial de TMR1 = 65.536 – 50.000 = 15.536 = 0x3CB0.
ü FATOR = 10.
7) Biblioteca de operações aritméticas de precisão simples
Operação Detalhe
Adição C:Op1_L = Op1_L + Op2_L C: carry
Subtração Op1_L = Op1_L - Op2_L C: borrow
Multiplicação Rpta2:Rpta1 = Mulcnd * Mulcdr = Op1_L * Op2_L
Divisão Dividendo = Divisor * Quociente + Resto
Conv. Binário 16b à BCD binario_H:binario_L à dmil:umil:cent:deze:unid
Conv. 3 BCD à Binário 8b cent:deze:unid à binario_L

8) Projeto 1: Contador BCD temporizado por TMR0


O objetivo deste exemplo é conhecer os procedimentos para implementar um contador de 4 BCDs. Os
BCDs serão mostrados em displays de 7 segmentos, que são acesos multiplexados no tempo. Assim, a
frequência de atualização dos valores do contador BCD é realizado na rotina de interrupção que é executada
cada vez que o TMR0 transbordar.
Nota-se que os valores usados para configurar o TMR0 são os determinados no exemplo do item 5.
Roteiro:
• Crie uma pasta para o Projeto 1, em seguida, na pasta criada, extrair os arquivos compactados em
Lab-06_p1.rar.
• Utilize o assistente do Mplab para criar um novo projeto, atribuindo o nome Lab-06_p1. Anexe o
arquivo fonte Lab-06_contador_BCD_p1.asm (arquivo copiado na pasta do projeto).
• Abrir o arquivo fonte:
list p=16f877a ; define o tipo de Microcontrolador usado
#include <p16f877a.inc> ; inclui arquivo com declarações típicas
__CONFIG H'2F02' ; define a palavra de configuração
;Atribuições de variáveis
cblock 0x20
umil, cent, deze, unid, FATOR
w_temp, status_temp
endc
org 0x00 ;vetor de reset
goto inicio
org 0x04 ;vetor de interrupção
goto ISR
tab_7seg
addwf PCL,F
dt 0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09
; Rotina de interrupção
ISR: movwf w_temp ;salva Wreg
movfw STATUS
movwf status_temp ;salva STATUS
bcf STATUS,RP0 ;importante!
btfss INTCON,T0IF ;verifica se TMR0 transbordou
goto fim_isr ;se não, termina ISR
; redefine valores do TMR0, cada 64us
isr_tmr0:
movlw .131 ;256-125
movwf TMR0 ;valor inicial
incf FATOR,F ;FATOR++ cada 64us
movfw FATOR
xorlw .125 ;se FATOR=125, tempo 1seg
btfss STATUS,Z
goto fim_isr
; completou 1s, atualiza os contadores
clrf FATOR ;reinica FATOR
incf unid,F ;unid++
movf unid,W
xorlw .10 ;unid = 10?
btfss STATUS,Z
goto fim_isr
clrf unid ;unid = 0
incf deze,F ;deze++
movf deze,W
xorlw .10 ;deze = 10?
btfss STATUS,Z
goto fim_isr
clrf deze ;deze = 0
fim_isr:
bcf INTCON,T0IF ;apaga flag de transbordo
movfw status_temp
movwf STATUS ;recupera STATUS
swapf w_temp,F
swapf w_temp,W ;recupera Wreg
retfie
; Programa principal
inicio:
movlw 0xFF
movwf PORTD ;Displays apagados
bsf PORTA,5
movwf PORTE ;Displays desabilitados
movlw .131 ;valor inicial de TMR0
movwf TMR0
bsf STATUS,RP0 ;banco0
bcf TRISA,5 ;pino RA5 como saída
clrf TRISD ;porta D como saída
clrf TRISE ;porta E como saída
movlw 0x06
movwf ADCON1 ;portas A e E com E/S digitais
movlw 0x87 ;TMR0 usando Clock_in
movwf OPTION_REG ;e prescaler = 256
bcf STATUS,RP0 ;banco1
clrf FATOR
clrf umil
clrf cent
clrf deze
clrf unid
;habilita interrupção x transbordo de TMR0
bsf INTCON,T0IE ;habilita interrupção x TMR0
bsf INTCON,GIE ;habilitação global
;mostra digitos BCD no Display de 7seg
mostra_bcd:
movf unid,W ; Wreg = bdc unid
call tab_7seg ; cod. 7seg de unid
movwf PORTD ; PORTD <- unid
bcf PORTE,0 ;habilita display-1
call delay_4ms
bsf PORTE,0 ;desabilita display-1
movf deze,W ; Wreg = bdc deze
call tab_7seg ; cod. 7seg de deze
movwf PORTD ; PORTD <- deze
bcf PORTE,1 ;habilita display-2
call delay_4ms
bsf PORTE,1 ;desabilita display-2
goto mostra_bcd
; inclusão de bibliotecas
#include "up_md_atrasos.asm"
END
• Faça a montagem do programa: Project > Build All ou <Ctrl> + <F10>.
• Para simular, abrir seu esquemático do módulo didático ou o arquivo “Lab-06_modulo_didatico.dsn”
no simulador Proteus VSM. Anexe o arquivo Lab-06_contador_BCD_p1.hex ao µC PIC.
• Para testar o exemplo no módulo didático: 1º) deixe em OFF todas as chaves CH1, CH2, CH3, CH4,
CH5 e CH6; 2º) grave o PIC utilizando o software Bootloader; 3º) configure as chaves como indicado
na tabela do item 1 e 4º) testar a aplicação.

9) Projeto 2: Relógio de tempo real (RTC) usando TMR1


O objetivo deste exemplo é configurar o TMR1 para implementar um RTC e mostrar, no LCD, as
informações de hora, minuto e segundo. Nota-se que os valores usados para configurar o TMR1 são os
determinados no exemplo do item 6.
Roteiro:
• Crie uma pasta para o Projeto 2, em seguida, na pasta criada, extrair os arquivos compactados em
Lab-06_p2.rar.
• Crie um novo projeto adicionando o arquivo fonte Lab-06_RTC_p2.asm, extraído previamente.
• Abrir o arquivo fonte:
list p=16f877a ; define o tipo de Microcontrolador usado
#include <p16f877a.inc> ; inclui arquivo com declarações típicas
__CONFIG H'2F02' ; define a palavra de configuração
;Atribuições de variáveis
cblock 0x20
FATOR, seg, min, hrs, w_temp, status_temp
endc
org 0x00 ;vetor de reset
goto inicio
org 0x04 ;vetor de interrupção
goto ISR
#include "up_mensagens.asm"
; Rotina de interrupção
ISR: movwf w_temp ; salva Wreg
movfw STATUS
movwf status_temp ; salva STATUS
bcf STATUS,RP0 ; banco-0
btfss PIR1,TMR1IF ; TMR1 transbordou?
goto fim_isr
; redefine valores do TMR1, atualiza RTC
isr_tmr1: bcf T1CON, TMR1ON ;TMR1 off
movlw high (.65536 - .50000) ;15.536
movwf TMR1H
movlw low (.65536 - .50000)
movwf TMR1L
bsf T1CON, TMR1ON ; TMR1 on
incf FATOR,F
movfw FATOR
xorlw .10
btfss STATUS,Z ; FATOR = 10?
goto fim_isr
; completou 1s, atualiza os contadores
clrf FATOR
incf seg,F ; seg++
movfw seg
xorlw .60
btfss STATUS,Z ; seg = 60?
goto fim_isr
clrf seg
incf min,F ; min++
movfw min
xorlw .60
btfss STATUS,Z ; min = 60?
goto fim_isr
clrf min
incf hrs,F ; hrs++
movfw hrs
xorlw .24
btfss STATUS,Z ; hrs = 24?
goto fim_isr
clrf hrs
fim_isr: bcf PIR1,TMR1IF ; apaga flag
movfw status_temp
movwf STATUS
swapf w_temp,F
swapf w_temp,W
retfie
; Programa principal
inicio: clrf PORTD
clrf PORTE
movlw 0x30
movwf T1CON ; presc=8, Clock_in, T1_off
bsf STATUS, RP0 ; banco-0
clrf TRISD
clrf TRISE
movlw 0x06
movwf ADCON1 ; PORTA e PORTE E/S digitais
bsf PIE1,TMR1IE
bcf STATUS, RP0 ; banco-0
clrf FATOR
clrf seg
clrf min
clrf hrs
call Inicia_LCD
;inicia TMR1 e habilita interrupções
movlw high (.65536 - .50000) ;15.536
movwf TMR1H
movlw low (.65536 - .50000)
movwf TMR1L
bsf T1CON, TMR1ON
bsf INTCON, PEIE
bsf INTCON, GIE
;mostra "RTC:" no LCD
call msg_rtc
mostra_hhmmss: ; mostra HH:MM:SS
movlw LCD_Linha_2 + 1 ; endereço 0xC1
call EnviaCmdLCD
movfw hrs
call print_2BCD
movlw ':'
call EnviaCarLCD
movfw min
call print_2BCD
movlw ':'
call EnviaCarLCD
movfw seg
call print_2BCD
call delay_100ms
goto mostra_hhmmss
; sub-rotina para mostrar 2BCD no LCD
print_2BCD:
movwf binario_L
clrf binario_H
call Bin16_BCD
movfw deze
addlw 0x30
call EnviaCarLCD
movfw unid
addlw 0x30
call EnviaCarLCD
return
; inclusão de bibliotecas
#include "up_md_atrasos.asm"
#include "up_md_lcd_driver.asm"
#include "up_Bin16_BCD.asm"
END
• Faça a montagem do programa: Project > Build All ou <Ctrl> + <F10>.
• Simule o programa usando o esquemático do arquivo “Lab-06_modulo_didatico.dsn”.
• Para testar o exemplo no módulo didático: 1º) deixe em OFF todas as chaves CH1, CH2, CH3, CH4,
CH5 e CH6; 2º) grave o PIC utilizando o software Bootloader; 3º) configure as chaves como indicado
na tabela do item 2 (apenas para o LCD) e 4º) testar a aplicação.

10) Projeto 3: Calculadora Básica


O objetivo deste exemplo é desenvolver uma calculadora básica de precisão simples, que implementa as
quatro operações aritméticas básicas. Os BCD de cada operando devem ser digitados através do teclado
básico 4x4, sendo que cada operando não deve ser maior do que 255. Os BCD do equivalente decimal do
resultado serão mostrados no LCD.
Roteiro:
• Crie uma pasta para o Projeto 3, em seguida, na pasta criada, extrair os arquivos compactados em
Lab-06_p3.rar.
• Crie um novo projeto adicionando o arquivo fonte Lab-06_calc_p3.asm, extraído previamente.
• Abrir o arquivo fonte:
list p=16f877a ; define o tipo de Microcontrolador usado
#include <p16f877a.inc> ; inclui arquivo com declarações típicas
#include <macros.inc> ; inclui macros
__CONFIG H'2F02' ; define a palavra de configuração
;Atribuições de variáveis
cblock 0x20
Op1_H, Op1_L, Op2_H, Op2_L, Loper, conta
endc
org 0x00 ;vetor de reset
goto inicio
org 0x04 ;vetor de interrupção
#include "up_md_teclado_4x4.asm"
checa_BCD:
bcf fpress,0
movlw 0x30
subwf code_tecla,W ;code_tecla - 0x30
btfss STATUS,C ;C=1: 0x30 <= code_tecla
return ;BCD inválido
movfw code_tecla
sublw 0x39 ;0x39 - code_tecla
btfsc STATUS,C ;C=1: code_tecla <= 0x39
bsf fpress,0 ;indica BCD válido
return

inicio: call Inicia_teclado ;configura PORTB e PORTC


call Inicia_LCD ;configura LCD e Portas
banco1
movlw 0x06
movwf ADCON1
banco0
calculadora:
movlw LCD_CLEAR
call EnviaCmdLCD ; limpa LCD
;mostrar "calculadora" no LCD
call env_msg_calc
operandos:
movlw 0xC1
call EnviaCmdLCD ; apontador para o endereço 0xC1
movlw 3
movwf conta
;Lê 1° operando
Lop1: call teclado ; lê BCD1 de op1
btfss fpress,0
goto $–2
call checa_BCD ; code_tecla = [0x30,0x39]
btfss fpress,0
goto Lop1
movfw code_tecla
xorlw 0x30
btfsc STATUS,Z
goto Lop1
movfw code_tecla
movwf cent ; armazena BCD1
call EnviaCarLCD
decf conta,F
call teclado ; lê BCD2 ou operador
btfss fpress,0
goto $–2
call checa_BCD
btfss fpress,0
goto operador
movfw code_tecla
movwf deze ; armazena BCD2
call EnviaCarLCD
decf conta,F
call teclado ; lê BCD3 ou operador
btfss fpress,0
goto $–2
call checa_BCD
btfss fpress,0
goto operador
movfw code_tecla
movwf unid ; armazena BCD3
call EnviaCarLCD
decf conta,F
call teclado ; lê operador
btfss fpress,0
goto $–2
;valida operador
opdor movlw 0x2A ; '*'
subwf code_tecla,W ; code_tecla - 0x2A
btfss STATUS,C ; C=1: 0x2A <= code_tecla
goto opdor – 3
movfw code_tecla ; '/'
sublw 0x2F ; 0x2F - code_tecla
btfss STATUS,C ; C=1: code_tecla <= 0x2F
goto opdor – 3
movfw code_tecla
movwf Loper ; caractere da operação
call EnviaCarLCD
;ajuste de operando1
movfw conta
btfsc STATUS,Z
goto pop1
adj1 movfw deze
movwf unid
movfw cent
movwf deze
movlw 0x30
movwf cent
decfsz conta,F
goto adj1
pop1 call BCD_bin8
movfw binario_L
movwf Op1_L ; cent:deze:inid -> Op1_L
movlw 3
movwf conta
;Lê 2° operando
Lop2: call teclado ; lê BCD1 de op2
btfss fpress,0
goto $–2
call checa_BCD ; code_tecla = [0x30,0x39]
btfss fpress,0
goto Lop2
movfw code_tecla
xorlw 0x30
btfsc STATUS,Z
goto Lop2
movfw code_tecla
movwf cent ; armazena BCD1
call EnviaCarLCD
decf conta,F
call teclado ; lê BCD2 ou operador
btfss fpress,0
goto $–2
call checa_BCD
btfss fpress,0
goto operador2
movfw code_tecla
movwf deze ; armazena BCD2
call EnviaCarLCD
decf conta,F
call teclado ; lê BCD3 ou operador
btfss fpress,0
goto $–2
call checa_BCD
btfss fpress,0
goto operador2
movfw code_tecla
movwf unid ; armazena BCD3
call EnviaCarLCD
decf conta,F
call teclado
btfss fpress,0
goto $–2
;valida operador '='
opdor2 movlw 'E' ;=
xorwf code_tecla,W ; code_tecla [=]
btfss STATUS,Z
goto opdor2 – 3
movlw ' '
call EnviaCarLCD
movlw '='
call EnviaCarLCD
movlw ' '
call EnviaCarLCD
;ajuste de operando2
movfw conta
btfsc STATUS,Z
goto pop2
adj2 movfw deze
movwf unid
movfw cent
movwf deze
movlw 0x30
movwf cent
decfsz conta,F
goto adj2
pop2 call BCD_bin8
movfw binario_L
movwf Op2_L ; cent:deze:inid -> Op2_L
clrf binario_H
clrf binario_L
je_rl Loper,'+',Soma
je_rl Loper,'-',Subtrai
je_rl Loper,'*',Multiplica
je_rl Loper,'/',Divide
goto calculadora
Soma: movfw Op2_L
addwf Op1_L, F ; C:Op1_L = Op1_L + Op2_L
btfsc STATUS, C
incf binario_H
movfw Op1_L
movwf binario_L
goto prt_rpta
Subtrai: movfw Op2_L
subwf Op1_L,F ; Op1_L = Op1_L - Op2_L
movfw Op1_L
movwf binario_L
btfss STATUS,C
goto comp2
movlw '+'
call EnviaCarLCD
goto prt_rpta
comp2: movlw '-'
call EnviaCarLCD
comf binario_L,F
incf binario_L,F ; complemento de 2(Op1_L)
goto prt_rpta
Multiplica:
movfw Op1_L
movwf Mulcnd
movfw Op2_L
movwf Mulcdr
call Multi8 ; Rpta2:Rpta1 = Op1_L * Op2_L
movfw Rpta1
movwf binario_L
movfw Rpta2
movwf binario_H
goto prt_rpta
Divide: movfw Op1_L
movwf Dividendo
movfw Op2_L
movwf Divisor
call Divide8 ; Op2_L = Op1_L / Op2_L
movfw Quociente
movwf binario_L
goto prt_rpta
prt_rpta: bcf fpress,0 ;para indicar se já tem digito ¹ 0
call Bin16_BCD
movfw dmil
btfsc STATUS,Z
goto $+4
bsf fpress,0
addlw 0x30 ; ASCII(dmil)
call EnviaCarLCD
movfw umil
btfss STATUS,Z
goto $+3
btfss fpress,0
goto $+4
bsf fpress,0
addlw 0x30 ; ASCII(umil)
call EnviaCarLCD
movfw cent
btfss STATUS,Z
goto $+3
btfss fpress,0
goto $+4
bsf fpress,0
addlw 0x30 ; ASCII(cent)
call EnviaCarLCD
movfw deze
btfss STATUS,Z
goto $+3
btfss fpress,0
goto $+3
addlw 0x30 ; ASCII(deze)
call EnviaCarLCD
movfw unid
addlw 0x30 ; ASCII(unid)
call EnviaCarLCD
call teclado
btfss fpress,0
goto $-2
movlw 'A'
xorwf code_tecla,W ; tecla [on]?
btfss STATUS,Z
goto $-6
goto calculadora
#include "up_md_atrasos.asm"
#include "up_Bin16_BCD.asm"
#include "up_3BCD_bin8.asm"
#include "up_aritmetica_8b.asm"
#include "up_md_lcd_driver.asm"
END
• Faça a montagem do programa: Project > Build All ou <Ctrl> + <F10>.
• Simule o programa usando o esquemático do arquivo “Lab-06_modulo_didatico.dsn”. Durante o teste,
cada operando deve ser indicado necessariamente por 3 dígitos BCD. Então, deve-se digitar os 3BCD
do operando 1, o caractere da operação e os 3BCD do operando 2. Após o resultado ser mostrado no
LCD, para continuar, o programa espera a tecla [on] ser pressionada.
• Para testar o exemplo no módulo didático: 1º) deixe em OFF todas as chaves CH1, CH2, CH3, CH4,
CH5 e CH6; 2º) grave o PIC utilizando o software Bootloader; 3º) configure as chaves como indicado
na tabela do item 2 (para LCD e teclado) e 4º) testar a aplicação.
11) Exercícios - desafios:
Desafio 1: Faça as mudanças necessárias ao programa do Projeto 1, a fim de implementar um contador
BCD ascendente de 4 dígitos.
Desafio 2: Faça as mudanças necessárias ao programa do Projeto 2, para SETAR (definir) os valores dos
contadores de tempo. Para isso, usando as teclas [+] e [-], deve-se aumentar e diminuir o valor do contador
de horas, respectivamente e, usando as teclas [×] e [÷], deve-se aumentar e diminuir o valor do contador de
minutos, respectivamente.
12) Exercícios - tarefa:
Tarefa 1: Faça as mudanças necessárias ao programa do Projeto 2, para adicionar e mostrar no LCD, um
contador de centésimas de segundo.
Tarefa 2: Escreva um programa em Assembly que implemente uma calculadora básica, de maneira que os
operandos decimais, representados por 3BCD, não excedam do valor de 255. Para isso, o programa não
deve aceitar como primeiro BCD um digito > 2. Se o primeiro BCD digitado é 2, então o segundo BCD
não poderá ser maior que 5. Se os primeiros BCDs digitados são 25, então o terceiro BCD não poderá ser
maior que 5.
13) Avaliação do aprendizado:
No dia do laboratório nº 07, cada aluno deve apresentar:
a) Os programas solução das tarefas 1 e 2 enunciados no item 12, funcionando no módulo didático:
b) Um relatório a manuscrito, incluindo:
• O fluxograma do programa da tarefa 1;
• O código em Assembly do programa da tarefa 2;
• Um ressumo, sucinto e objetivo, dos programas;
• Observações e comentários pertinentes

BOM TRABALHO!

Você também pode gostar