Buscar

Lista Exercicios com Gabarito

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 15 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Aplicações de Microprocessadores e Microcontroladores 
 
Lista de Exercícios P1 - Gabarito 
 
1) Assinale V ou F de acordo com a afirmação estar correta ou errada, respectivamente: 
 
(V) Um processador é composto basicamente por três partes: a ULA, responsável pelas operações lógicas e 
aritméticas, a Unidade de Controle, responsável por buscar, decodificar e executar as instruções e os 
Registradores, que são posições de memória que armazenam resultados de operações e outros valores 
necessários ao funcionamento do processador. 
(F) O registrador IR é responsável por indicar qual a posição de memória na qual uma nova instrução será 
buscada, o registrador SP é responsável por controlar o acesso à pilha do processador e o registrador PC 
recebe o dado buscado na memória para decodificação e execução. As funções do IR e do PC estão trocadas. 
(V) As principais etapas na execução de uma instrução pelo processador são: busca, decodificação e 
execução. A unidade de referência utilizada para indicar o tempo gasto na realização dessas etapas é 
chamada de ciclo de máquina. 
(F) A pilha em um sistema computacional é utilizada para armazenar o endereço de retorno nas chamadas de 
subrotinas. O endereço salvo na pilha é o endereço da instrução que chama a subrotina. O endereço salvo é o 
da instrução seguinte à instrução que chamou a subrotina. 
(V) Se um processador tivesse um registrador de 12 bits, ele possuiria 3 nibbles e poderia armazenar 4.096 
valores, de 0 a 4095. 
(F) Se uma operação AND for realizada em um processador e o resultado for 10010001, a flag Z não será 
afetada. A flag Z é sempre afetada pelas instruções NOT, AND, OR e XOR. Nesse caso, como o resultado não 
deu zero, a flag Z seria colocada em 0. 
(F) Existe uma situação particular na qual a operação XOR pode afetar a flag C. As instruções NOT, AND, OR 
e XOR nunca afetam a flag C. 
(V) Se a operação 2AH – 7DH for realizada dentro do processador em complemento de 2, podemos afirmar 
que, após a mesma, o resultado será ADH e as flags C e Z serão zeradas. Como o resultado dessa operação é 
negativo, a flag C será zerada, e como o resultado não deu zero, a flag Z será zerada. 
(V) O cristal é um componente utilizado por um circuito oscilador para produzir uma onda quadrada com 
frequência fixa e conhecida, que sincroniza as operações dentro do processador. 
(F) O número 1423 na base 5 equivale a 321 na base 7. 14235 → 23810 e 3217 → 16210 
(F) Um processador de 8 bits não é capaz de realizar operações de 16 bits. 
 
2) Associe as duas colunas relacionando os componentes de um Sistema Computacional com sua função no 
sistema: 
 
1. Pilha (3) Memória volátil utilizada pelo processador para armazenar dados do 
programa durante sua execução. 
2. Registrador (5) Circuito eletrônico responsável pela geração do sinal de relógio, que 
sincroniza as operações do microprocessador. 
3. Memória RAM (6) Conjunto de sinais utilizados para transmitir uma informação do mesmo 
tipo. Um dos tipos indica a quantidade de memória que o processador pode 
endereçar. 
4. Memória ROM (1) Memória volátil utilizada para armazenar o endereço de retorno nas 
chamadas das subrotinas. O endereço salvo é o endereço da instrução 
seguinte à instrução que chama a subrotina. 
5. Oscilador (4) Memória não-volátil utilizada para armazenar as instruções do programa 
inicial a ser executado pelo microprocessador 
6. Barramento (2) Memória volátil utilizada para armazenar dados do processador durante a 
execução de um programa. 
Assinale a alternativa que apresenta a relação correta entre a segunda coluna e a primeira coluna, de cima 
para baixo: 
 
a) 3 – 5 – 2 – 1 – 4 – 6 
b) 2 – 6 – 5 – 4 – 1 – 3 
c) 3 – 5 – 6 – 1 – 4 – 2 
d) 1 – 2 – 6 – 3 – 5 – 4 
e) 2 – 5 – 1 – 6 – 4 – 3 
 
3) Carregue a posição de memória 20H com a constante A3H e a posição 22H com a constante com a 
constante 240. Some os valores existentes nas posições 20H e 21H, sem alterar esses valores, colocando o 
resultado na posição 23H. Caso a flag C esteja zerada, faça uma operação OR do resultado com o conteúdo 
da posição 22H, alterando o valor dessa posição de memória. Caso a flag C tenha sido setada, a operação a 
ser realizada será um XOR. Teste seu programa com os seguintes valores na posição de memória 21H: 1EH (a 
operação OR deverá ser a selecionada) e 8EH (a operação XOR deverá ser a selecionada). 
 
#INCLUDE P16F628A.INC 
 
 ORG 000H 
 
 MOVLW 0A3H 
 MOVWF 20H ; Coloca A3H na posição de memória 20H 
 MOVLW .240 
 MOVWF 22H ; Coloca 240 na posição de memória 22H 
 
 MOVFW 20H ; Soma o conteúdo de 20H com o conteúdo de 21H 
 ADDWF 21H,W ; sem alterar os valores ali contidos 
 MOVWF 23H ; Salva resultado em 23H 
 BTFSS STATUS,C 
 IORWF 22H,F ; Se a flag C estiver zerada, efetua a operação OR do resultado com 22H 
 BTFSC STATUS,C 
 XORWF 22H,F ; Se a flag C estiver setada, efetua a operação XOR do resultado com 22H 
 
FIM: GOTO FIM 
 
 END 
 
4) Dado que um registrador do PIC armazena um valor de 8 bits dispostos na sequência D7 D6 D5 D4 D3 D2 
D1 D0, faça um programa que pegue um valor qualquer na posição 30H e produza a seguinte saída: D7 1 0 0 
/D3 1 0 /D0. As instruções BCF e BSF NÃO devem ser utilizadas. Obs.: /D3 significa D3 “barrado”. 
 
#INCLUDE P16F628A.INC 
 
 ORG 000H 
 
 MOVFW 30H ; Pega valor contido em 30H 
 ANDLW B'11001101' ; Zera os bits D1, D4 e D5, sem afetar os demais bits 
 IORLW B'01000100' ; Seta os bits D2 e D6, sem afetar os demais bits 
 XORLW B'00001001' ; Inverte os bits D0 e D3, sem afetar os demais bits 
 MOVWF 30H ; Valor final em 30H: D7 1 0 0 /D3 1 0 /D0 
 
FIM: GOTO FIM 
 
 END 
 
5) Dada uma posição de memória chamada VALOR e outra chamada BITS0, crie uma rotina que “conte” 
quantos bits zero existem no byte contido na posição VALOR. O resultado dessa contagem deve aparecer na 
posição BITS0. O dado na posição VALOR não pode ser alterado. Teste seu programa com os valores 7FH (1 
bit em zero), 3BH (3 bits em zero), 81H (6 bits em zero) e 20H (7 bits em zero). 
 
#INCLUDE P16F628A.INC 
 
VALOR EQU 20H 
BITS0 EQU 21H 
CONTA EQU 22H 
TEMP EQU 23H 
 
 ORG 000H 
 
 MOVLW 7FH ; Valor de teste (pode-se carregar outros valores) 
 MOVWF VALOR 
 CLRF BITS0 ; Zera contador de bits iguais a 0 
 MOVLW 8 
 MOVWF CONTA ; Contador de bits (8 bits em um byte) 
 
 MOVFW VALOR 
 MOVWF TEMP ; Copia dado contido em VALOR para TEMP 
 
LOOP: RRF TEMP,F ; Ao rotacionar, o bit D0 irá para a flag CARRY 
 ; Na segunda rotação, será o bit D1, e assim sucessivamente 
 BTFSS STATUS,C ; Se o bit for 1, não faz nada 
 INCF BITS0,F ; Se o bit for 0, incrementa contador 
 DECFSZ CONTA,F ; Os 8 bits do byte já foram testados? 
 GOTO LOOP 
 
FIM: GOTO FIM 
 
 END 
 
6) Faça um programa que teste o resultado da rotina anterior. Caso o resultado em BITS0 for igual a 6, o bit 5 
da posição FLAG deve ser setado. Já se o resultado em BITS0 for igual a 7, os bits 4, 6 e 7 da posição FLAG 
deverão ser setados. A posição FLAG deve ser zerada no início do programa. 
 
#INCLUDE P16F628A.INC 
 
VALOR EQU 20H 
BITS0 EQU 21H 
CONTA EQU 22H 
TEMP EQU 23H 
FLAG EQU 24H 
 
 ORG 000H 
 
 MOVLW 7FH ; Valor de teste (pode-se carregar outros valores) 
 MOVWF VALOR 
 CLRF BITS0 ; Zera contador de bits iguais a 0 
 MOVLW 8 
 MOVWF CONTA ; Contador de bits (8 bits em um byte) 
 
 MOVFW VALOR 
 MOVWF TEMP ; Copia dado contido em VALOR para TEMP 
 
 CLRF FLAG ; Zera as flags do programa 
 
LOOP: RRF TEMP,F ; Ao rotacionar, o bit D0 irá para a flag CARRY 
 ; Na segunda rotação, será o bit D1, e assim sucessivamente 
 BTFSS STATUS,C ; Se o bit for 1, não faz nada 
 INCF BITS0,F ; Se o bit for 0, incrementa contador 
 DECFSZ CONTA,F ; Os 8 bits do byte já foram testados? 
 GOTO LOOP 
 
 MOVLW 6 
 XORWF BITS0,W ; Testa se VALOR possui 6 bits iguais a 0? 
 BTFSC STATUS,ZBSF FLAG,5 ; Se sim, seta o bit 5 de FLAG 
 
 MOVLW 7 
 XORWF BITS0,W ; Testa se VALOR possui 7 bits iguais a 0? 
 BTFSS STATUS,Z 
 GOTO FIM 
 
 MOVLW B'11010000' 
 IORWF FLAG,F ; Se sim, seta os bits 4, 6 e 7 de FLAG 
 
FIM: GOTO FIM 
 
 END 
 
7) Em um experimento no laboratório de eletrônica foram medidos os seguintes valores de uma tensão V2 em 
função de uma outra tensão V1: quando V1 = 5, V2 = 63, quando V1 = 8, V2 = 96 e quando V1 = 11, V2 = 129. 
Elabore um programa que, dado o valor de V1, retorne com o valor de V2. Um valor de V1 = 0 é inválido e V2 
deverá retornar zerado nesse caso. 
 
#INCLUDE P16F628A.INC 
; Quando V1 = 5 -> V2 = 63 
; Quando V1 = 8 -> V2 = 96 
; Quando V1 = 11 -> V2 = 129 
; Dessa forma, V1 e V2 possuem uma relação linear dada por uma equação da forma: V2 = aV1 + b 
; Substituindo os pontos na equação, temos que: a = 11 e b = 8 
; Além de V1=0 fazer com que V2 volte zerado (exigência do enunciado), V2 também tem que ser menor ou 
; igual a 255. Para isso, o valor limite de V1 é: 11V1 + 8 <= 255 → 11V1 <= 247 → V1 <= 22,45 
; Potências de 2 que compõem o número 11: 8 + 2 + 1 
 
 
 
 
 
 
 
V1 EQU 20H 
V2 EQU 21H 
 
 ORG 000H 
 
 CLRF V2 
 
 MOVFW V1 
 SUBLW .22 ; 22 - V1 
 BTFSS STATUS,C ; Se V1 <= 22, então flag C = 1 
 GOTO FIM 
 
 BCF STATUS,C ; Zera flag C antes das rotações (simular um SHIFT LEFT) 
 MOVFW V1 ; W = V1 
 RLF V1,F ; 2V1 
 ADDWF V1,W ; W = V1 + 2V1 = 3V1 
 RLF V1,F ; 4V1 
 RLF V1,F ; 8V1 
 ADDWF V1,W ; W = 3V1 + 8V1 = 11V1 
 ADDLW 8 ; W = 11V1 + 8 
 MOVWF V2 ; V2 = 11V1 + 8 
 
FIM: GOTO FIM 
 
 END 
 
8) Crie uma subrotina que recebe um valor numa variável chamada TEMPO, multiplique esse valor por 5 e o 
resultado seja passado como um parâmetro para um laço de tempo. Quando receber o maior valor possível, a 
rotina de tempo deve demorar 1,87 milisegundos, aproximadamente. Caso o valor 0 seja recebido, a subrotina 
deve retornar imediatamente. O valor da variável pode ser alterado pela subrotina. Dado: o PIC opera com um 
cristal de 3,2 MHz. 
 
- Resolução no exercício 9 
 
9) Dado que uma certa subrotina (exercício 8) só pode receber valores de 0 a 50, crie uma rotina que teste se o 
valor contido em uma posição de memória chamada TEMPO atende essa condição. Caso isso ocorra, a 
subrotina do exercício 8 deverá ser chamada. 
 
#INCLUDE P16F628A.INC 
; Com o PIC operando com um cristal de 3,2MHz: CM = 4 / Fcristal -> CM = 4 / 3,2 = 1,25 useg 
; O maior valor possível que a subrotina pode receber será quando a variável TEMPO for igual a 50, 
; que será ainda multiplicado por 5, resultando em 250. Esse valor será fornecido ao contador do laço 
; de tempo. Dessa forma, quando o contador da rotina de tempo for igual a 250, a rotina deve durar, 
; aproximadamente, 1,87 mseg 
; Uma rotina básica de tempo utiliza uma instrução NOP e sua duração é calculada por: DURACAO = 4 x K x 
; CM. Então, quando o contador for igual a 250, teremos: 4 x 250 x 1,25 useg = 1,25 mseg (abaixo do 
; esperado) 
; Adicionando mais um NOP na rotina de tempo: 5 x 250 x 1,25 useg = 1,56 mseg (também abaixo do 
; desejado) 
; Adicionando dois NOP's à rotina básica de tempo, temos: 6 x 250 x 1,25 useg = 1,87 mseg 
 
TEMPO EQU 20H 
 
 ORG 000H 
 
 MOVFW TEMPO 
 SUBLW .50 ; 50 - TEMPO 
 BTFSC STATUS,C ; Se TEMPO > 50, então flag C = 0 
 CALL DELAY ; Chama subrotina de tempo (TEMPO <= 50) 
FIM: GOTO FIM 
 
DELAY: MOVF TEMPO,F ; Faz flag Z ser alterada de acordo com o conteúdo de TEMPO 
 BTFSC STATUS,Z ; Se TEMPO = 0, flag Z = 1 
 RETURN ; Se TEMPO = 0, então retorna 
 
 BCF STATUS,C ; Zera flag C antes das rotações (simular um SHIFT LEFT) 
 MOVFW TEMPO ; W = TEMPO 
 RLF TEMPO,F ; 2 x TEMPO 
 RLF TEMPO,F ; 4 x TEMPO 
 ADDWF TEMPO,F ; TEMPO = TEMPO + 4 x TEMPO = 5 x TEMPO 
LOOP: NOP ; A duração da rotina de tempo vai variar de acordo com a variável TEMPO 
 NOP ; sendo, no máximo, de 1,87 mseg 
 NOP 
 DECFSZ TEMPO,F 
 GOTO LOOP 
 
 RETURN 
 
 END 
10) Dado que um registrador do PIC armazena um valor de 8 bits dispostos na sequência D7 D6 D5 D4 D3 D2 
D1 D0, faça um programa que inverta a ordem desses bits para D0 D1 D2 D3 D4 D5 D6 D7. 
 
#INCLUDE P16F628A.INC 
 
VALOR1 EQU 20H 
VALOR2 EQU 21H 
CONTA EQU 22H 
 
 ORG 000H 
 
 MOVLW 8 ; 8 bits em um byte 
 MOVWF CONTA 
 
LOOP: RLF VALOR1,F ; Inicia com D7 indo para a flag C, depois D6, e assim sucessivamente até 
 ; D0 
 RRF VALOR2,F ; A cada repetição do laço, D7 vai sendo "empurrado" para o início do 
 ; byte, assim como os outros bits que forem entrando em VALOR2 
 DECFSZ CONTA,F ; 8 bits já transferidos de VALOR1 para VALOR2? 
 GOTO LOOP ; Não, prossegue com o laço de repetição 
 
FIM: GOTO FIM 
 
 END 
 
11) Crie uma subrotina para cada uma das operações descritas abaixo: 
a) Some dois números de 16 bits; 
#INCLUDE P16F628A.INC 
; 
; VAL1_H VAL1_L (primeiro valor com 16 bits - 2 bytes) 
; + VAL2_H VAL2_L (segundo valor com 16 bits - 2 bytes) 
; ------------------- 
; RES_C RES_H RES_L (resultado valor com 24 bits - 3 bytes) 
 
VAL1_L EQU 20H ; Parte LOW do primeiro valor 
VAL1_H EQU 21H ; Parte HIGH do primeiro valor 
VAL2_L EQU 22H ; Parte LOW do segundo valor 
VAL2_H EQU 23H ; Parte HIGH do segundo valor 
RES_L EQU 24H ; Parte LOW do resultado 
RES_H EQU 25H ; Parte HIGH do resultado 
RES_C EQU 26H ; Ajuste do resultado (uma soma de 16 bits pode resultar num valor de 17 bits) 
 
 ORG 000H 
 
 CLRF RES_H 
 CLRF RES_C 
 
 MOVFW VAL1_L 
 ADDWF VAL2_L,W ; Soma partes LOW dos valores 
 MOVWF RES_L 
 
 BTFSC STATUS,C 
 INCF RES_H,F ; Ajusta parte HIGH se houve carry 
 
 MOVFW VAL1_H 
 ADDWF VAL2_H,W ; Soma partes HIGH dos valores 
 
 BTFSC STATUS,C 
 INCF RES_C,F ; Ajusta 3o byte do resultado se houve carry 
 
 ADDWF RES_H,F ; Coloca resultado da soma anterior no byte HIGH do resultado 
 
 BTFSC STATUS,C ; Necessário testar a flag C novamente, já que foi efetuada outra soma 
 INCF RES_C,F ; Ajusta 3o byte do resultado se houve carry 
 
FIM: GOTO FIM 
 
 END 
 
b) Subtraia dois números de 16 bits; 
#INCLUDE P16F628A.INC 
; 
; VAL2_H VAL2_L 
; - VAL1_H VAL1_L 
; ------------- 
; RES_H RES_L 
; 
; Essa rotina supõe que o valor contido em VAL2_H VAL2_L é maior que o contido em VAL1_H VAL1_L 
 
VAL1_L EQU 20H ; Parte LOW do primeiro valor 
VAL1_H EQU 21H ; Parte HIGH do primeiro valor 
VAL2_L EQU 22H ; Parte LOW do segundo valor 
VAL2_H EQU 23H ; Parte HIGH do segundo valor 
RES_L EQU 24H ; Parte LOW do resultado 
RES_H EQU 25H ; Parte HIGH do resultado 
 
 ORG 000H 
 
 MOVFW VAL1_L 
 SUBWF VAL2_L,W ; Subtrai partes LOW dos valores (VAL2_L - VAL1_L) 
 MOVWF RES_L 
 
 BTFSS STATUS,C ; Se a flag C = 1, não é necessário ajuste (resultado anterior positivo) 
 DECF VAL2_H,F ; Ajusta parte HIGH do valor 2 se não houve carry ("empréstimo" 
 ; para a parte LOW) 
 
 MOVFW VAL1_H 
 SUBWF VAL2_H,W ; Subtrai partes HIGH dos valores (VAL2_H - VAL1_H) 
 MOVWF RES_H 
 
FIM: GOTO FIM 
 
 END 
 
c) Calcule o valor médio de 4 números de 8 bits. 
 
#INCLUDE P16F628A.INC 
 
VALOR1 EQU 20H 
VALOR2 EQU 20H 
VALOR3 EQU 20H 
VALOR4 EQU 20H 
RES_L EQU 24H ; Parte LOW do resultado 
RES_H EQU 25H ; Parte HIGH do resultado 
 
 ORG 000H 
 
 CLRF RES_H 
 
 MOVFW VALOR1 
 ADDWF VALOR2,W ; Soma os dois primeiros valores (resultado em W) 
 
 BTFSC STATUS,C 
 INCF RES_H,F ; Ajusta parte HIGH do resultado se houve carry 
 
 ADDWF VALOR3,W ; Soma com terceiro valor (resultado em W) 
 
 BTFSC STATUS,C 
 INCF RES_H,F ; Ajusta parte HIGH do resultado se houve carry 
 
 ADDWF VALOR4,W ; Soma com quarto valor (resultado em W) 
 MOVWF RES_L ; Salva parte LOW do resultado 
 
 BTFSC STATUS,C 
 INCF RES_H,F ; Ajusta parte HIGH do resultado se houve carry 
 
 BCF STATUS,C ; Garante flag C zerada (para a instrução de rotação virar um 
 ; SHIFT)RRF RES_H 
 RRF RES_L 
 
 RRF RES_H ; Divide o resultado final por 4 (média dos 4 valores) 
 RRF RES_L 
 
FIM: GOTO FIM 
 
 END 
 
12) Uma certa subrotina, chamada ULA, recebe um valor na posição de memória MEM e outro valor na posição 
OPERACAO. Os bits do valor contido em OPERACAO indicam que operações a subrotina fará com o valor 
contido em MEM, de acordo com a tabela abaixo. Se mais de um bit estiver setado no valor contido em 
POSICAO, mais de uma operação deverá ser realizada em MEM. O resultado das operações deve ser 
retornado em MEM. 
OPERACAO MEM 
Bit 0 Complemento de 2 de MEM 
Bit 1 MEM dividido por 2 
Bit 2 Nibbles de MEM deverão ser trocados 
Bit 3 Bits 0, 6 e 7 de MEM devem ser zerados 
Bit 4 Se MEM for um valor BCD válido, o bit 7 de 
OPERACAO deve ser setado. Caso contrário, 
deve ser zerado 
 
#INCLUDE P16F628A.INC 
 
MEM EQU 20H 
OPERACAO EQU 20H 
 
 ORG 000H 
 
 MOVLW 3AH 
 MOVWF MEM ; Carrega valor a ser alterado na subrotina ULA 
 MOVLW 0EH 
 MOVWF OPERACAO ; Indica a(s) operacão(ões) a serem realizadas em MEM 
 CALL ULA 
 
FIM: GOTO FIM 
 
ULA: BTFSS OPERACAO,0 ; Testa bit 0 
 GOTO TST_1 
 
 COMF MEM,F 
 INCF MEM,F ; Complemento de 2 
 
TST_1: BTFSS OPERACAO,1 ; Testa bit 1 
 GOTO TST_2 
 
 BCF STATUS,C 
 RRF MEM,F ; Divide por 2 
 
TST_2: BTFSS OPERACAO,2 ; Testa bit 2 
 GOTO TST_3 
 
 SWAPF MEM,F ; Inverte nibbles 
 
TST_3: BTFSS OPERACAO,3 ; Testa bit 3 
 GOTO TST_4 
 
 MOVLW B'00111110' 
 ANDWF MEM,F ; Zera bits 0, 6 e 7 
 
TST_4: BTFSS OPERACAO,4 ; Testa bit 4 
 GOTO SAI 
 
 BCF OPERACAO,7 ; Supõe que MEM não contém valor BCD válido 
 MOVLW 0FH 
 ANDWF MEM,W ; Mantém apenas nibble inferior (sem alterar MEM) 
 SUBLW 9 
 BTFSS STATUS,C ; O nibble inferiror de MEM é menor ou igual a 9? 
 GOTO SAI ; Não, então sai com o bit 7 zerado 
 
 SWAPF MEM,W ; Inverte os nibbles 
 ANDLW 0FH 
 SUBLW 9 
 BTFSC STATUS,C ; O nibble superior de MEM é menor ou igual a 9? 
 BSF OPERACAO,7 ; Sim, então seta o bit 7 de OPERACAO indicando essa condição 
 
SAI: RETURN 
 
 END 
 
13) Escreva três rotinas chamadas de LE_BIT, SET_BIT e ZERA_BIT que recebam um valor de 0 a 7 contido 
em uma posição de memória chamada de N_BIT e um ponteiro em PNT_MEM para uma posição de memória 
onde a rotina atuará. A rotina LE_BIT deve retornar o valor do bit indicado (0 ou 1) em W e as rotinas SET_BIT 
e ZERA_BIT devem colocar em 1 ou 0, respectivamente, o bit indicado em N_BIT na posição de memória 
apontada por PNT_MEM. (Dica: use uma tabela com os valores das máscaras) 
 
#INCLUDE P16F628A.INC 
 
MEM EQU 20H 
OPERACAO EQU 21H 
N_BIT EQU 22H 
PNT_MEM EQU 23H 
 
 ORG 000H 
 
 MOVLW 30H 
 MOVWF PNT_MEM 
 MOVLW 3 
 MOVWF N_BIT ; Indica a leitura do bit 3 da posição 30H 
 CALL LE_BIT 
 
 MOVLW 35H 
 MOVWF PNT_MEM 
 MOVLW 5 
 MOVWF N_BIT ; Indica que é para "setar" o bit 5 da posição 35H 
 CALL SET_BIT 
 
 MOVLW 38H 
 MOVWF PNT_MEM 
 MOVLW 6 
 MOVWF N_BIT ; Indica que é para zetar o bit 6 da posição 38H 
 CALL ZERA_BIT 
 
FIM: GOTO FIM 
 
LE_BIT: MOVFW PNT_MEM ; Pega ponteiro 
 MOVWF FSR ; Aponta a posição desejada 
 MOVFW N_BIT ; Pega número do bit a ser lido 
 CALL TAB_1 ; Pega a máscara adequada 
 ANDWF INDF,W ; Mantém apenas o bit desejado (não altera a posição de memória) 
 BTFSS STATUS,Z 
 MOVLW 1 ; Ajusta valor de W caso o bit seja igual a 1 
 RETURN 
 
SET_BIT:MOVFW PNT_MEM ; Pega ponteiro 
 MOVWF FSR ; Aponta a posição desejada 
 MOVFW N_BIT ; Pega número do bit a ser lido 
 CALL TAB_1 ; Pega a máscara adequada 
 IORWF INDF,F ; Seta o bit desejado 
 RETURN 
 
ZERA_BIT:MOVFW PNT_MEM ; Pega ponteiro 
 MOVWF FSR ; Aponta a posição desejada 
 MOVFW N_BIT ; Pega número do bit a ser lido 
 CALL TAB_2 ; Pega a máscara adequada 
 ANDWF INDF,F ; Zera o bit desejado 
 RETURN 
 
TAB_1: ADDWF PCL,F 
 RETLW B'00000001' 
 RETLW B'00000010' 
 RETLW B'00000100' 
 RETLW B'00001000' 
 RETLW B'00010000' 
 RETLW B'00100000' 
 RETLW B'01000000' 
 RETLW B'10000000' 
 
TAB_2: ADDWF PCL,F 
 RETLW B'11111110' 
 RETLW B'11111101' 
 RETLW B'11111011' 
 RETLW B'11110111' 
 RETLW B'11101111' 
 RETLW B'11011111' 
 RETLW B'10111111' 
 RETLW B'01111111' 
 
 END 
 
14) Crie um programa que simule as instruções de rotação à esquerda sem carry e rotação à direita sem carry, 
inexistentes no PIC. Para isso, devem ser criadas duas subrotinas: ROL e ROR, para as rotações à esquerda e 
à direita, respectivamente. Na chamada dessas rotinas o registrador W deve ser carregado com o valor 
desejado de rotações. Caso seu valor seja maior que 7, o número de rotações deve se limitar a 7. A flag 
CARRY deve voltar inalterada dessas subrotinas. 
 
#INCLUDE P16F628A.INC 
 
VALOR EQU 20H 
TEMP EQU 21H 
CONTA EQU 22H 
 
 ORG 000H 
 
 MOVLW B'10110101' 
 MOVWF VALOR ; Valor a ser rotacionado 
 MOVLW 6 ; Número de rotações 
 CALL ROR 
 
 MOVLW B'11101100' 
 MOVWF VALOR ; Valor a ser rotacionado 
 MOVLW 5 ; Número de rotações 
 CALL ROL 
 
FIM: GOTO FIM 
 
; -> Rotação à direita 
 
ROR: MOVWF CONTA ; Salva contador das rotações 
 
 BCF TEMP,0 ; Salva valor atual da flag C 
 BTFSC STATUS,C 
 BSF TEMP,0 
 
LOOP_R: BCF STATUS,C ; Altera a flag C de acordo com o bit 0 de VALOR 
 BTFSC VALOR,0 
 BSF STATUS,C 
 
 RRF VALOR,F ; Rotaciona à direita 
 DECFSZ CONTA,F 
 GOTO LOOP_R 
 
 BCF STATUS,C ; Restitui valor da flag C 
 BTFSC TEMP,0 
 BSF STATUS,C 
 
 RETURN 
 
; -> Rotação à esquerda 
 
ROL: MOVWF CONTA ; Salva contador das rotações 
 
 BCF TEMP,0 ; Salva valor atual da flag C 
 BTFSC STATUS,C 
 BSF TEMP,0 
 
LOOP_L: BCF STATUS,C ; Altera a flag C de acordo com o bit 7 de VALOR 
 BTFSC VALOR,7 
 BSF STATUS,C 
 
 RLF VALOR,F ; Rotaciona à esquerda 
 DECFSZ CONTA,F 
 GOTO LOOP_L 
 
 BCF STATUS,C ; Restitui valor da flag C 
 BTFSC TEMP,0 
 BSF STATUS,C 
 
 RETURN 
 
 END 
 
15) A Internet é utilizada amplamente para troca de informações. O problema é que muitas dessas informações 
são importantes e podem ser “capturadas” durante sua transmissão. Para isso, é necessário cifrar os dados 
antes de serem transmitidos. Sabe-se que se dois valores hexadecimais de 8 bits A e B obedecerem a regra A 
+ B = 100H, temos que, se somarmos A com um valor qualquer X de 8 bits, com a soma desprezando o “vai-
um”, obteremos um valor Y, também de 8 bits: A + X = Y. Se, em seguida, pegarmos o valor de Y e somarmos 
com B, também ignorando um possível “vai-um”, iremos obter de volta o valor X, na forma: Y + B = X. De forma 
similar, dados dois valores hexadecimais de 8 bits, K e X, temos que: K ⊕ X = M (com ⊕ representando a 
operação OU-Exclusivo ou XOR). Se agora fizermos a operação ⊕ entre M e K, o valor de X será obtido 
novamente, na forma: X = M ⊕ K. Percebe-se que, tanto na soma quanto no ou-exclusivo, o valor X foi 
recuperado. Essas duas operações, por serem reversíveis, são muito utilizadas em sistemas de criptografia. 
Dessa forma, a partir de uma mensagem original X, podem ser geradas mensagens cifradas M, que são 
transmitidas e, no sistema receptor, a mensagem original X pode ser recuperada a partir de M. Crie uma 
subrotina que receba um valor na posição de memória X e retorne um valor cifrado na posição de memória M, 
de acordo com o seguinte algoritmo: M = SWAP(X ⊕ K) + A, com o símbolo + representando uma soma na 
qual o “vai-um” é desprezado, o símbolo ⊕ representando a operação OU-Exclusivo ou XOR, e K e A sendo as 
chaves do algoritmo. Dados: K = D6H e A = ACH. 
 
- Resolução no exercício 17 
 
16) Os dados contidos em um região de memória que vai de 20H até 4FH devem ser cifrados de acordo com o 
algoritmo de cifragem da questão 15. Crie uma rotina que percorra essa região de memória, chame a subrotina 
anterior, e cifre os dados contidos nessa região. 
 
- Resolução no exercício 17 
 
17) Crie uma rotina que percorra a mesma região anterior e decifre os valores contidos nessas posições. 
 
#INCLUDEP16F628A.INC 
 
; Constantes: 
 
K1 EQU 0D6H 
VAL_A EQU 0ACH ; A + B = 100H 
VAL_B EQU 54H 
 
; Memória RAM: 
 
X EQU 70H 
M EQU 71H 
 
 ORG 000H 
 
; -> Cifra região de memória desejada 
 
 MOVLW 20H 
 MOVWF FSR ; Aponta primeira posição de memória 
 
LOOP_C: MOVFW INDF ; Pega dado a ser cifrado 
 MOVWF X 
 CALL CIFRA 
 MOVFW M ; Salva dado cifrado 
 MOVWF INDF 
 INCF FSR,F ; Incrementa ponteiro (próxima posição de memória) 
 MOVLW 50H 
 XORWF FSR,W ; Testa se ponteiro já chegou na última posição desejada 
 BTFSS STATUS,Z 
 GOTO LOOP_C ; Não, continua loop de cifragem 
 
; -> Decifra região de memória desejada 
 
 MOVLW 20H 
 MOVWF FSR ; Aponta primeira posição de memória 
 
LOOP_D: MOVFW INDF ; Pega dado a ser decifrado 
 MOVWF M 
 CALL DECIFRA 
 MOVFW X ; Salva dado decifrado 
 MOVWF INDF 
 INCF FSR,F ; Incrementa ponteiro (próxima posição de memória) 
 MOVLW 50H 
 XORWF FSR,W ; Testa se ponteiro já chegou na última posição desejada 
 BTFSS STATUS,Z 
 GOTO LOOP_D ; Não, continua loop de decifragem 
 
FIM: GOTO FIM 
 
; -> Rotina de cifragem: M = SWAP(X xor K1) + A 
 
CIFRA: MOVLW K1 
 XORWF X,F ; X xor K1 
 SWAPF X,W ; SWAP(X xor K1) 
 ADDLW VAL_A ; SWAP(X xor K1) + A 
 MOVWF M ; M = SWAP(X xor K1) + A 
 RETURN 
 
; -> Rotina de decifragem: X = SWAP(M + B) xor K1 
 
DECIFRA:MOVLW VAL_B 
 ADDWF M,F ; M + B 
 SWAPF M,W ; SWAP(M + B) 
 XORLW K1 ; SWAP(M + B) xor K1 
 MOVWF X ; X = SWAP(M + B) xor K1 
 RETURN 
 
 END 
 
 
18) Para gerar uma onda quadrada de determinada frequência em um dos pinos de saída do PIC é necessário 
colocar em nível alto esse pino, aguardar um tempo, depois colocar esse pino em nível baixo, e aguardar o 
mesmo tempo anterior, repetindo o ciclo enquanto se quiser continuar gerando esse sinal. Dado que a 
frequência do sinal a ser gerado deve ser de 1,25KHz, crie o laço de tempo necessário para que essa onda 
quadrada possa ser gerada. Dado: O PIC opera com um cristal de 5MHz. 
 
#INCLUDE P16F628A.INC 
; Com o PIC operando com um cristal de 5MHz: CM = 4 / Fcristal -> CM = 4 / 5 = 0,8 useg 
; Como a frequência do sinal a ser gerado é de 1,25KHz: T = 1/f -> T = 0,8 mseg ou 800 useg 
; A onda quadrada tem o seguinte formato: ___|--|___|--|___ 
; 
; |--T--| 
; 
; Ou seja, metade do período ela fica em nível baixo, e metade do período em nível alto 
; Dessa forma, a rotina de tempo deve durar T/2 -> 400 useg 
; DURACAO = 4 x K x CM -> 400 = 4 x K x 0,8 -> K = 125 
; Sinal será gerado no bit 0 da porta A 
 
CONTA EQU 20H 
 
 ORG 000H 
 
ONDA: BSF PORTA,0 ; Coloca sinal em nível alto 
 CALL LP400US ; Aguarda T/2 
 BCF PORTA,0 ; Coloca sinal em nível baixo 
 CALL LP400US ; Aguarda T/2 
 GOTO ONDA 
 
LP400US:MOVLW .125 ; Laço de tempo de 400 useg 
 MOVWF CONTA 
LOOP: NOP 
 DECFSZ CONTA,F 
 GOTO LOOP 
 RETURN 
 
 END 
 
19) Alguns PICs possuem internamente um conversor analógico/digital (conversor AD) que, como o próprio 
nome sugere, converte um valor analógico (tensão, corrente, temperatura, etc.) em um dado digital. Para iniciar 
uma conversão AD, é necessário setar o bit 3 do registrador ADCTRL, aguardar o tempo de conversão e 
depois ler o resultado da conversão no registrador ADRES. Obs.: Embora exista em outros PICs, o 
PIC16F628A não possui um conversor AD interno. Dessa forma, os registradores ADCTRL e ADRES devem 
ser definidos pelo seu programa em uma posição de memória à sua escolha. 
 
a) Crie uma subrotina de tempo que espere um tempo de 1,9 milisegundos para a conversão AD. O 
cristal de operação do PIC é de 2,5MHz; 
b) Elabore um programa que inicie uma conversão AD, chame a subrotina anterior para esperar o 
tempo de conversão, leia o resultado da conversão no registrador ADRES e escreva cada valor lido em 
uma posição de memória distinta, começando em 30H. Devem ser lidos os resultados de 32 
conversões. 
 
#INCLUDE P16F628A.INC 
; Com o PIC operando com um cristal de 2,5MHz: CM = 4 / Fcristal -> CM = 4 / 2,5 = 1,6 useg 
; Uma rotina básica de tempo utiliza uma instrução NOP e sua duração é calculada por: DURACAO = 4 x K x 
; CM. Então: 1900 useg = 4 x K x 1,6 -> K = 296,875 (maior que 255) 
; Adicionando uma instrução NOP ao laço de tempo: 1900 useg = 5 x K x 1,6 -> K = 237,5 
 
ADCTRL EQU 20H 
ADRES EQU 21H 
CONTA EQU 22H 
LEITURAS EQU 23H 
 
 ORG 000H 
 
 MOVLW 30H ; Aponta posição onde será guardado o primeiro resultado da conversão AD 
 MOVWF FSR 
 MOVLW .32 ; 32 resultados (conversões AD) a serem armazenados 
 MOVWF LEITURAS 
 
LE_AD: BSF ADCTRL,3 ; Inicia uma conversão AD 
 CALL LP_19MS ; Aguarda um tempo para que a conversão AD finalize 
 MOVFW ADRES ; Lê o resultado da conversão 
 MOVWF INDF ; Salva na memória 
 INCF FSR,F ; Incrementa ponteiro 
 DECFSZ LEITURA,F ; 32 valores já lidos? 
 GOTO LE_AD ; Não, efetua nova conversão 
 
FIM: GOTO FIM 
 
LP_19MS:MOVLW .237 ; 237 x 5 x 1,6 = 1896 useg 
 MOVWF CONTA 
LOOP: NOP 
 NOP 
 DECFSZ CONTA,F 
 GOTO LOOP 
 RETURN 
 
 END 
 
20) Crie um laço de tempo que demore 25 msegundos. Dado: O PIC opera com um cristal de 1,25MHz. 
 
#INCLUDE P16F628A.INC 
; Com o PIC operando com um cristal de 1,25MHz: CM = 4 / Fcristal -> CM = 4 / 1,25 = 3,2 useg 
; Laço de tempo de 25 mseg 
; DURACAO = 4 x K x CM -> 25.000 = 4 x K x 3,2 -> K = 1953,125 
; Como K é muito maior que 255, deve-se utilizar o esquema de laços aninhados 
; Então, faremos um laço de 1 mseg que será repetido 25 vezes 
; DURACAO = 4 x K x CM -> 1.000 = 4 x K x 3,2 -> K = 78,125 
 
CONTA1 EQU 20H 
CONTA2 EQU 21H 
 
 ORG 000H 
 
 CALL LP25MS ; Aguarda 25 mseg 
FIM: GOTO FIM 
 
LP25MS: MOVLW .25 ; 25 x 1 mseg = 25 mseg 
 MOVLW CONTA2 
 
LP_1MS: MOVLW .78 ; Laço de tempo de 1 mseg 
 MOVWF CONTA1 
LOOP: NOP 
 DECFSZ CONTA1,F 
 GOTO LOOP 
 
 DECFSZ CONTA2,F 
 GOTO LP_1MS 
 
 RETURN 
 
 END 
 
21) Crie um laço de tempo que demore 15 segundos. Dado: O PIC opera com um cristal de 3,2MHz. 
 
#INCLUDE P16F628A.INC 
; Com o PIC operando com um cristal de 3,2MHz: CM = 4 / Fcristal -> CM = 4 / 3,2 = 1,25 useg 
; Como o laço de tempo é de 15 segundos, deve-se utilizar o esquema de laços aninhados 
; Então, faremos um laço de 1 mseg, que será repetido 250 vezes (250 mseg), sendo esse último repetido 
; 60 vezes 
; DURACAO = 4 x K x CM -> 1.000 = 4 x K x 1,25 -> K = 200 
 
CONTA1 EQU 20H 
CONTA2 EQU 21H 
CONTA3 EQU 22H 
 
 ORG 000H 
 
 CALL LP_15S ; Aguarda 15 seg 
FIM: GOTO FIM 
 
 
LP_15S: MOVLW .60 ; 60 x 250 mseg = 15 seg 
 MOVLW CONTA3 
 
LP_200: MOVLW .250 ; 250 x 1 mseg = 250 mseg 
 MOVLW CONTA2 
 
LP_1MS: MOVLW .200 ; Laço de tempo de 1 mseg 
 MOVWF CONTA1 
LOOP: NOP 
 DECFSZ CONTA1,F 
 GOTO LOOP 
 
 DECFSZ CONTA2,F 
 GOTO LP_1MS 
 
 DECFSZ CONTA3,F 
 GOTO LP_200 
 
 RETURN 
 
 END 
 
22) O pequeno trecho de código abaixo deve percorrer as posições de memória de 30H a 5FH, inclusive, 
invertendo o bit 7 do valor contido em cada uma dessas posições. Em seguida, o valor resultante deve ser 
testado e se ele for menor do que 50, deverá ser multiplicado por 5 e somado com 3. Identifique e corrija os 
erros desse programa: 
 
MOVFW 30 MOVLW 30 
MOVWF FSR 
LOOP: MOVLW .127 MOVLW 80H (ou .128) 
IORWF INDF,F XORWF INDF,F 
MOVLW .50 
SUBWF INDF,F SUBWF INDF,W 
BTFSS STATUS,C BTFSC STATUS,C 
GOTO NAO_CALCULA 
BSF STATUS,C BCF STATUS,C 
MOVWF INDF MOVFW INDF 
RLF INDF,W RLF INDF,F 
RLF INDF,F 
ADDWF INDF,F ADDWF INDF,W 
ADDFW 3 ADDLW 3 
MOVWF INDF 
NAO_CALCULA: INCF FSR,F 
MOVLW 5F MOVLW 60H 
XORWF FSR,F XORWF FSR,W 
BTFSC STATUS,Z BTFSS STATUS,Z 
GOTO LOOP 
23) “Execute” o seguinte programa e, para cada linha do programa, preencha a tabela ao lado com os valores 
atuais dos registradores W e FSR, das flags C e Z e das posições de memória VALOR1, VALOR2 e VALOR3. 
Os valores iniciais desses registradores e bits são dados na tabela, bem como oconteúdo da memória RAM 
acessada (Dica: só preencha a tabela quando algum valor for alterado). 
 
#INCLUDE P16F84A.INC RAM 
 25H 18H 
VALOR1 EQU 0C 26H 6BH 
VALOR2 EQU 0D 27H 35H 
VALOR3 EQU 0E 28H 2AH 
 
 ORG 000H W FSR C Z VALOR1 VALOR2 VALOR3 
 00H 00H 0 0 00H 00H 00H 
 MOVLW .85 55H 
 ADDWF 25H,W 6DH 0 0 
 MOVWF VALOR1 6DH 
 RLF 26H,W D6H 0 
 ANDLW B’00101100’ 02H 0 
 MOVWF VALOR2 02H 
 MOVLW 35H 35H 
 IORLW B’10010110’ B7H 0 
 XORLW .144 27H 0 
 MOVWF FSR 27H 
 INCF FSR,F 28H 0 
 MOVF INDF,W 2AH 
 XORWF VALOR1,F 0 47H 
 BCF VALOR2,2 00H 
 MOVF VALOR2,F 1 00H 
 BTFSC STATUS,Z 
 MOVLW 0C8H C8H 
 XORWF FSR,F E0H 
 SWAPF FSR,F 0EH 
 MOVWF INDF C8H 
 GOTO $ 
 
 END 
 
24) Os algoritmos de ordenação são muito utilizados em diversas aplicações. Existem diversos algoritmos que 
se dividem entre a complexidade de implementação e a eficiência computacional. Embora não seja o mais 
eficiente, o método de ordenação simples é facilmente implementado e utilizado em situações onde não há um 
volume muito grande de dados. Suponha que deseje ordenar, em ordem crescente, um vetor com 5 posições, 
e vamos supor que os valores contidos nesse vetor são B, C, A, E e D, nesta ordem, com A < B < C < D < E. 
Pegue o valor da primeira posição (B) e compare com o valor da segunda posição (C). Como B < C, não é 
necessário fazer nada. Agora compare esse primeiro valor (B) com o valor da terceira posição do vetor (A). 
Nesse caso, como B > A, troca-se de posição os dois valores, com o vetor ficando da seguinte forma: A, C, B, 
E e D. Agora compara-se o primeiro valor novamente, que passou a ser A, com os valores da quarta e quinta 
posições. Se o valor for menor ou igual não faz nada, e se for maior, inverte-se as posições. No exemplo em 
análise, como A < E e A < D, não será necessário fazer nada. Após percorrer todo o vetor, o primeiro elemento 
estará ordenado. Passa-se agora para o segundo elemento do vetor, que deve ser comparado com os valores 
da terceira, quarta e quinta posições, seguindo a regra de que se o valor que está sendo comparado for menor 
ou igual, não faz nada, e se for maior, inverte-se as posições. Após comparar a segunda posição do vetor com 
as posições superiores, o vetor estará da seguinte forma: A, B, C, E e D, com os valores da primeira e segunda 
posições já ordenados. Toma-se agora o terceiro elemento e procede-se de maneira similar, sempre 
comparando com os elementos de índice superior. Esse procedimento é repetido até chegar na penúltima 
posição do vetor, que será comprado com a última, quando então teremos o vetor totalmente ordenado. 
Elabore um programa que ordene, em ordem crescente, os valores contidos na região de memória de 30H até 
4FH. 
 
#INCLUDE P16F628A.INC 
 
INI_TST EQU 20H ; Posição do vetor que será ordenada 
VAL_TST EQU 21H ; Valor contido na posição a ser ordenada 
TEMP EQU 22H ; Posição temporária para a troca de valores 
 
 ORG 000H 
 
 MOVLW 30H 
 MOVWF FSR ; Aponta início do vetor 
 
PROX: MOVFW FSR 
 MOVWF INI_TST ; Indica a posição que está sendo ordenada 
 MOVFW INDF 
 MOVWF VAL_TST ; Salva valor da posição 
 
TST_VETOR: INCF FSR ; Próxima posição do vetor 
 MOVFW VAL_TST 
 SUBWF INDF,W ; Testa se o valor atual é menor ou igual que os seguintes 
 BTFSC STATUS,C 
 GOTO NAO_TROCA 
 MOVFW INDF ; Se não for, efetua a troca 
 MOVWF TEMP 
 MOVFW VAL_TST 
 MOVWF INDF 
 MOVFW TEMP 
 MOVWF VAL_TST 
NAO_TROCA: MOVLW 4FH ; Verifica se o valor atual já foi comparado até a última 
 XORWF FSR,W ; posição do vetor 
 BTFSS STATUS,Z 
 GOTO TST_VETOR ; Se ainda não, continua comparação 
 
 MOVFW INI_TST 
 MOVWF FSR 
 MOVFW VAL_TST ; Pega valor comparado (e ordenado) 
 MOVWF INDF ; e atualiza o vetor 
 
 INCF FSR,F ; Próxima posição do vetor a ser comparada com o restante 
 MOVLW 4FH 
 XORWF FSR,W ; Verifica se já é a última posição do vetor 
 BTFSS STATUS,Z 
 GOTO PROX ; Se não for, efetua comparação com o restante do vetor 
 
FIM: GOTO FIM 
 
 END 
 
25) As centrais de alarme precisam de um teclado onde é digitada uma senha para ativar ou desativar o 
alarme. Suponha que um determinado alarme possua um teclado no padrão dos telefones, com teclas de 0 a 9, 
além de * e #. Para que o alarme seja armado ou desarmado, é necessário que 4 teclas sejam pressionadas, 
com cada valor sendo armazenado em uma posição de memória (de 20H até 23H). Como os valores são de 0 
a 9, ocupam apenas metade de um byte. A rotina que testa a senha digitada deve concatenar os dois primeiros 
valores digitados em um byte só, com o primeiro valor virando o nibble mais significativo e o segundo valor o 
nibble menos significativo. O mesmo deve ser feito para o terceiro e quarto valores digitados. Ou seja, após 
essa concatenação, serão gerados dois bytes (exemplo: suponha que tenham sido digitadas as teclas 4,7, 9, e 
5. Após a concatenação, teremos dois bytes: 47H e 95H). Após gerar os dois bytes, a rotina deve calcular a 
média desses 2 valores e testar se o resultado é igual a 5AH. Caso isso aconteça, o bit 3 da variável FLAGS 
deve ser setado indicando que o alarme pode ser armado ou desarmado. Elabore a rotina que testa a senha 
digitada no alarme. Para a concatenação dos bytes, as funções SWAP e OR deverão ser utilizadas. 
 
#INCLUDE P16F628A.INC 
 
VALOR1 EQU 20H ; Primeiro valor digitado no teclado 
VALOR2 EQU 21H ; Segundo valor digitado no teclado 
VALOR3 EQU 22H ; Terceiro valor digitado no teclado 
VALOR4 EQU 23H ; Quarto valor digitado no teclado 
FLAGS QUE 24H 
 
 ORG 000H 
 
 CLRF FLAGS ; Flags do sistema inicialmente zeradas 
 
 SWAPF VALOR1,W 
 IORWF VALOR2,F ; Concatena os 2 primeiros dígitos em VALOR2 
 
 SWAPF VALOR3,W 
 IORWF VALOR4,F ; Concatena os 2 últimos dígitos em VALOR4 
 
 CLRF VALOR3 ; Byte superior da soma de VALOR2 e VALOR4 
 MOVFW VALOR2 
 ADDWF VALOR4,F ; Soma os dois valores concatenados, com o resultado em VALOR4 
 BTFSC STATUS,C 
 INCF VALOR3,F ; Se houve carry, ajusta VALOR3 
 
 BCF STATUS,C 
 RRF VALOR3,F 
 RRF VALOR4,F ; Rotação à direita do resultado: divisão por 2 (média) 
 
 MOVLW 5AH 
 XORWF VALOR4,W ; Testa se o resultado das operações é igual a 5AH 
 BTFSC STATUS,Z 
 BSF FLAGS,3 ; Se sim, seta flag indicando que a senha está correta 
 
FIM: GOTO FIM 
 
 END

Outros materiais

Outros materiais