Baixe o app para aproveitar ainda mais
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
Compartilhar