Prévia do material em texto
DISCIPLINA: SISTEMAS MICROPROCESSADOS - DAE01228 - SEMESTRE: 2020.2 - ANO : 2021
Roteiro No 3
INTRODUÇÃO ÀS INSTRUÇÕES
LÓGICAS E ARITMÉTICAS
EGOAVIL, C. J.1, MEDEIROS, J. C.2
1Professor do Curso de Engenharia Elétrica - DAEE, Fundação Universidade Federal de Rondônia, Sala 314 - 4H, Porto Velho, Rondônia, Brasil (e-mail:
ciro.egoavil@unir.br).
2Monitor voluntário.
RESUMO Este roteiro apresenta às instruções lógicas e aritméticas na linguagem Assembly para o
microcontrolador PIC16F877A.
1 INTRODUÇÃO
O microcontrolador PIC16F877A possui um total de 35
instruções, podendo ser separado em três grupos: instruções
com registradores em nível de Bytes, instruções com registra-
dores em nível de Bit e operações com literais e de controle.
Dentre as instruções, existem as responsáveis por efetuarem
operações aritméticas - como soma e subtração - e também as
responsáveis por efetuarem operações lógicas - como AND e
OR.
2 OBJETIVOS
O objetivo deste roteiro é introduzir as operações lógicas
e aritméticas do PIC16F877A utilizando a linguagem de
programação Assembly.
3 PROCEDIMENTO
Um código em linguagem Assembly será desenvolvido
para realizar algumas operações de soma, subtração, mul-
tiplicação por 2 e divisão por 2. As operações serão ob-
servadas através da ferramenta de depuração do software
MPLAB X (DEBUG). Outro código na mesma linguagem
será desenvolvido para piscar um led por 10 vezes depois
de pressionar um botão. A contagem é realizada através de
instruções aritméticas.
4 SOFTWARES UTILIZADOS
• MPLAB X
• PICSimLab
5 OPERAÇÕES ARITIMÉTICAS
5.1 SOMA (INCF, INCFSZ, ADDWF E ADDLW)
Para operações de adição, o Assembler do PIC16F877A pos-
sui dois grupos de instruções, sendo um usado para adições
unitárias e o outro para adições diversas, sendo elas:
• INCF f,d: Incremento unitário do registrador f (f + 1
→ d).
• INCFSZ f,d: Incremento unitário do registrador sal-
tando a próxima instrução se o resultado for zero (f + 1
→ d).
• ADDWF f,d: Soma o valor de WREG ao registrador
f (f + WREG→ d).
• ADDLW k: Soma um número (k) ao valor de WREG
(WREG + k→WREG).
Od quer dizer destino. Se d=0, a operação é salva no regis-
trador WREG. Se d=1, a operação é salva no registrador f.
Essas instruções afetam os três flags relacionados a Uni-
dade Lógica Aritmética (ULA) do registrador de STATUS: Z,
DC e C. O aluno deve consultar o datasheet do PIC16F877A.
5.2 SUBTRAÇÃO (DECF, DECFSZ, SUBWF E SUBLW)
Assim como nas operações de soma, o assembler do
PIC16F877A possui quatro instruções de subtração:
• DECF f,d: Decremento unitário do registrador f (f - 1
→ d).
• DECFSZ f,d: Decremento unitário do registrador
saltando a próxima instrução se o resultado for zero (f
- 1→ d).
• SUBWF f,d: Subtrai o valor de WREG ao registrador
f (f - WREG→ d).
• SUBLW k: Subtrai do número (k) o valor de WREG
(k - WREG→WREG).
Ao contrário das instruções de adição, a ordem dos fatores
afeta diretamente o resultado. Em uma operação de subtra-
Roteiro 3, 2020.2 ANO 2021 1
ção, o valor resultante pode ser zero, positivo ou negativo.
Por meio da análise do flag de carry (bit 0) do registrador
STATUS, pode-se concluir o resultado correto da subtração:
• Valor negativo: neste caso, o carry será 0. Assim, o
valor da resposta não será o número negativo, e sim sua
diferença para 256.
• Valor positivo: sempre que o resultado for positivo, o
carry será 1.
• Zero: sempre que o resultado for zero, o carry será 1,
porém o flag Z (bit 2 indica se zero) será 1 também.
5.3 MULTIPLICAÇÃO E DIVISÃO POR 2
No PIC16F877A não existem instruções específicas para
multiplicação e divisão. Porém, estas funções podem ser
implementadas com as outras instruções aritméticas. Além
disso, existem as instruções RLF e RRL, que rotacionam um
bit do registrador para esquerda e direita, respectivamente.
Ao utilizar a instrução “RLF f,d”, desloca-se todos os bits
do registrador f para a esquerda (multiplica por 2), salvando
essa operação no destino d. Ao fazer isso, o valor do bit de
carry é transferido ao bit 0 do registrador, enquanto que o
valor do bit 7 do registrador é passado para o carry [1]. De
forma semelhante, o utilizar a instrução “RRF f,d”, desloca-
se todos os bits do registrador f para a direita (divide por 2).
6 OPERAÇÕES LÓGICAS
6.1 AND (ANDWF E ANDLW)
A operação AND é um “e lógico” entre dois bits. Para que
a saída seja 1, os bits comparados devem ser ambos iguais a
1, caso contrário a saída será 0. A instrução “ANDWF f,d”
executa a operação “E” entre o valor do registrador WREG
e o registrador f, guardando o resultado no destino d. A
comparação é feita bit a bit.
A instrução “ANDLW k” executa a operação “E” entre o
valor do número k e o registrador WREG. A operação é salva
no próprio WREG. Geralmente, a operação AND é utilizada
quando se quer forçar o valor de determinados bits para zero.
6.2 OR (IORWF E IORLW)
A operação OR é um “ou lógico” entre dois bits. Para que a
saída seja 1, ao menos um dos bits comparados deve ser igual
a 1, caso contrário a saída será 0.
A instrução “IORWF f,d” executa a operação “ou” entre
o valor do registrador WREG e o registrador f, guardando o
resultado no destino d.
A instrução “IORLW k” executa a operação “ou” entre o
valor do número k e o registrador WREG. A operação é salva
no próprio WREG. Geralmente, a operação OR é utilizada
quando se quer forçar o valor de determinados bits para um.
6.3 XOR (XORWF E XORLW)
A operação XOR é um “ou lógico exclusivo” entre dois
bits. Para que a saída seja 1, os bits comparados devem ser
diferentes entre si, caso contrário a saída será 0.
A instrução “XORWF f,d” executa a operação “ou ex-
clusivo” entre o valor do registrador WREG e o registrador
f, guardando o resultado no destino d.
A instrução “XORLW k” executa a operação “ou exclu-
sivo” entre o valor do número k e o registrador WREG. A
operação é salva no próprio WREG. Geralmente, a operação
XOR é utilizada quando se quer fazer uma comparação entre
dois números. Por exemplo, se os números forem iguais o
resultado sempre será 0.
6.4 COMPLEMENTO (COMF)
A instrução “COMF f,d” é semelhante ao “não lógico”. Ele
inverte os valores dos bits do registrador f e salva no destino
d.
7 EXEMPLO 1
Este exemplo tem como objetivo mostrar o que ocorre
com alguns registradores quando são executadas algumas
operações aritméticas, de maneira que se possa observar
passo a passo o que ocorre com os bits a eles atrelados
indicadores dos cálculos efetuados para que se possa ler o
resultado de maneira correta.
Um projeto no MPLAB X deve ser criado como mostrado
no roteiro Nº 2. Lembrar que na janela para selecionar o
compilador o mpasm deve ser selecionado. Crie o arquivo
principal selecionando a opção pic_8b_simple.asm e dê um
nome [2].
Configure os bits de configuração do microcontrolador
como mostrado na Figura 1 e clique em Generate Source
Code to Output. Copie o código gerado e cole no começo
do arquivo principal.
Figura 1: Configuration bits.
O link encaminha o usuário ao Datasheet do PIC16F887A.
Acesse o mesmo e procure o Registrador STATUS. Isso trará
uma compreensão das linhas códigos seguintes, pois, através
dele seleciona-se os bancos de memória.
Pré-defina os bancos de memória como:
#define bank0 bcf STATUS,RP0
2 Roteiro 3, 2020.2 ANO 2021
https://ww1.microchip.com/downloads/en/devicedoc/39582b.pdf
#define bank1 bsf STATUS,RP0
Por facilidade, crie uma constante F e uma W e dê os
valores 1 e 0 respectivamente. Isto facilitará o entendimento
no momento em que algumas operações forem salvas no
destino d.
F EQU 1
W EQU 0
Será utilizado dois registradores de uso geral. Acesse o
Datasheet para entender o porquê dos valores em hexade-
cimal [3]. Para criá-los, faça:
#define contador1 H’20’
#define contador2 H’21’
cblock
contador1
contador2
endc
contador1 equ H’20’
contador1 equ H’21’
Acesse o Datasheet para entender o porquê dos valores em
hexadecimal [3]. Configure o vetor Reset como:
org H’00’
goto inicio
Neste exemplo, será observado pelo DEBUG o que ocorre
com os bits dos registradoresAUX1, AUX2, WREG e STA-
TUS. Serão utilizadas algumas funções de soma e subtração,
além de multiplicação e divisão por 2.
O programa principal é dado por:
inicio: bank0
clrf AUX1
clrf AUX2
loop:
movlw 0x01 ;WREG = 0X01
addwf AUX1,F ;AUX1 = 0x01
rlf AUX1,W ;WREG = 0x02
addlw 0x0E ;WREG = 0x10
movwf AUX2 ;AUX2 = 0x10
rrf AUX2,W ;WREG = 0x08
sublw 0x08 ;WREG = 0x00
;STATUS Flag C=1 e Z=1
end
Compile e verifique se ocorreu algum erro.
8 SIMULAÇÃO NO MPLAB
No menu selecione Debug → Debug Main Project. Após
isso aperte no botão de pause ou dê o comando Ctrl+Alt+8.
Para conseguir observar o que acontece com os bits dos
registradores, deve ser criado um Watch, Debug → New
Watch ou usando o comando Ctrl+Shift+F9, existem outras
maneiras de criar Watch, o usuário escolha a que mais lhe
convenha ou convier. A tela mostrada na figura 2 aparecerá.
No campo em branco, digite o nome do registrador que deseja
observar. No caso, serão criados 4 pontos de observação
(AUX1, AUX2, WREG, STATUS).
Figura 2: Tela para selecionar o registrador que queira
observar.
Caso ocorra algum erro quando adicionar os watches dos
registradores AUX1 e AUX2, coloque no lugar apenas seu
respectivo endereço.
Figura 3: Seleção dos watches para os registradores.
Em cima do Name mostrado na Figura 3, clique com o
botão direito do mouse e habilite “Binary” e “Decimal”. Com
isso será mostrado os valores dos registradores em formato
hexadecimal (padrão), binário e decimal.
Após isso, aperte o comando Step Into ou apenas F7 e
observe a mudança dos bits de cada registrador conforme as
linhas do código.
O código completo deste exemplo está no Apêndice A.
9 EXEMPLO 2
Este exemplo tem como objetivo de fazer com que o led
L2 da placa McLab2 pisque 10 vezes com um intervalo de
tempo considerável (utilizando um clock de 4MHz) quando
o botão S1 for pressionado. Os exemplos 1 e 2 do roteiro 2
foram utilizados como base para a elaboração deste exemplo.
Crie um novo projeto em Assembly e faça a configuração
dos bits como mostrado no exemplo anterior. Faça também
as definições dos bancos de memória 0 e 1 e do vetor de
reinicialização.
Roteiro 3, 2020.2 ANO 2021 3
Acesse o Datasheet para entender o porquê dos valores em
hexadecimal [3]. Crie os seguintes registradores de uso geral:
cblock H’20’
TEMP1 ;Alocado em 0x20
TEMP2 ;Alocado em 0x21
CONTADOR ;Alocado em 0x22
endc
Além disso, defina as portas de entrada (botão) e saída
(led) como: Acesse o Datasheet para entender o porquê dos
valores em hexadecimal [3].
; --- Entradas ---
#define botao PORTB,RB0 ;botão no RB0
; --- Saidas ---
#define led PORTB,RB1 ;led no RB1
Na rotina de início, defina o modo de operação dos pinos
do PORTB. Faça:
inicio bank1
movlw 0xF1
movwf TRISB
bank0
movlw 0x00
movwf PORTB
A rotina de loop é o laço de verificação do estado do
botão. Dependendo deste estado, ele vai para a subrotina
“apaga_led” responsável por apagar o led ou chama a subro-
tina “pisca_led_aux1” responsável por manter um laço que
conta quantas vezes o led piscou. O laço “pisca_led_aux2”
é responsável por fazer o comando para o led piscar. A
subrotina delay é exatamente a mesma do roteiro 2.
O código completo com comentários deste exemplo está no
Apêndice B.
loop:
movlw .246
movwf CONTADOR
btfsc botao
goto apaga_led
call pisca_led_aux1
apaga_led:
bcf led
goto loop
pisca_led_aux1:
call pisca_led_aux2
incfsz CONTADOR,F
goto pisca_led_aux1
goto loop
pisca_led_aux2:
bsf PORTB,RB1
call delay
bcf PORTB,RB1
call delay
10 EXERCÍCIOS
Todos os códigos dos exercícios devem ser entregues
comentados. Os exercícios 1), 2), 3), 5), 6) e 7) devem ser
acompanhados pela ferramenta DEBUG do MPLAB X.
1) Implementar uma subtração sem utilizar os comandos
SUBLW ou SUBWF.(Dica: complemento de 2).
2) Fazer a multiplicação 5×5 de duas maneiras diferentes.
(Dica: somas sucessivas e/ou RLF).
3) Fazer a divisão 25 ÷ 5 de duas maneiras diferentes.
(Dica: subtrações sucessivas e/ou RRF).
4) Implemente de outro modo o label "pisca_led_aux1"do
Exemplo 2 de forma que se utilize o comando XOR
para contabilizar que o led piscou 10 vezes. Faça as
alterações necessárias em outros labels, se preciso.
Dica: utilize a verificação do bit Z do STATUS.
5) Seja um registrador F com valor qualquer. Qual(is)
operação(ões) deve(m) ser feita(s) para que se garanta
que o valor novo do registrador fique entre 0 e 14
(decimal) e seja par?
6) Seja um registrador F com valor qualquer. Qual(is)
operação(ões) deve(m) ser feita(s) para que se garanta
que valor novo do registrador seja sempre ímpar e fique
entre 17 e 31 (decimal)?
7) Faça um código simples de livre escolha que utilize as
outras instruções lógicas não utilizadas nos exemplos
e exercícios anteriores. Verifique o comportamento dos
registradores utilizados no DEBUG.
Referências
[1] J. D. de Souza, Desbravando o Pic - Baseado no Microcontrolador Pic16f84.
Saraiva Educação SA, Érica, 2006.
[2] E. W. Rambo, “Wrkits channel: Curso de assembly para pic.”
[3] MICROCHIP, “Pic16f87xa: Data sheet, 28/40/44-pin enhanced flash micro-
controllers.”
4 Roteiro 3, 2020.2 ANO 2021
APÊNCICE A - CÓDIGO COMPLETO DO EXEMPLO 1
1 ;--- Arquivos inclu{\’i}dos ---
2
3
4 list p=16f877a
5
6 #include <p16f877a.inc>
7
8 ; --- Configuraes ---
9 __CONFIG _FOSC_HS & _WDTE_ON & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF &
_CP_OFF
10
11 ; --- Memria ---
12 W EQU 0
13 F EQU 1
14
15 #define bank0 bcf STATUS,RP0 ;// Cria mneumnico para o banco 0 de memria
16 #define bank1 bsf STATUS,RP0 ;// Cria mneumnico para o banco 1 de memria
17
18 ; --- Registradores de uso geral ---
19 cblock H’20’
20 AUX1 ;Alocado em 0x20
21 AUX2 ;Alocado em 0x21
22 endc
23
24 ; --- Vetor reset ---
25 org H’00’
26 goto inicio
27
28 ; --- Programa principal ---
29
30 inicio:
31 bank0 ; Acessa o bank0
32 clrf AUX1 ; limpa os bits de AUX1
33 clrf AUX2 ; limpa os bits de AUX2
34
35 loop:
36 movlw 0x01 ;move o valor 0x01 para o WREG
37 addwf AUX1,F ;AUX1 = AUX1 + WREG = 0x00 + 0x01 = 0x01
38 rlf AUX1,W ;WREG = 2*AUX1 = 0x02
39 addlw 0x0e ;WREG = WREG + k = 0x02 + 0x0e = 0x10
40 movwf AUX2 ;AUX2 = WREG = 0x10
41 rrf AUX2,W ;WREG = AUX2/2 = 0x08
42 sublw 0x08 ;WREG = WREG - 0x08 = 0x00
43 ;STATUS Flag C=1 e Z=1
44 end
teste01.asm
Roteiro 3, 2020.2 ANO 2021 5
APÊNDICE B - CÓDIGO COMPLETO DO EXEMPLO 2
1 ; --- Arquivos includos ---
2 #include <p16f877a.inc>
3
4 ; --- Configuraes ---
5 __CONFIG _FOSC_HS & _WDTE_ON & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF &
_CP_OFF
6
7 ; --- Memria ---
8 W EQU 0
9 F EQU 1
10
11 #define bank0 bcf STATUS,RP0 ; Cria mneumnico para o banco 0 de memria
12 #define bank1 bsf STATUS,RP0 ; Cria mneumnico para o banco 1 de memria
13
14 ; --- Registradores de uso geral ---
15 cblock H’20’
16 TEMP1 ;Alocado em 0x20
17 TEMP2 ;Alocado em 0x21
18 CONTADOR ;Alocado em 0x22
19 endc
20
21 ; --- Entradas ---
22 #define botao PORTB,RB0 ; boto 1 ligado em RB0
23
24 ; --- Saidas ---
25 #define led PORTB,RB1 ; led no RB1
26
27 ; --- Vetor reset ---
28 org H’00’
29 goto inicio
30
31 ; --- Programa principal ---
32
33 inicio:
34 bank1 ; Seleciona bank1
35 movlw 0xF1 ; WREG = 0b11110001
36 movwf TRISB ; TRISB = WREG
37 bank0 ; Seleciona ban0
38 movlw 0x00 ; WREG = 0b00000000
39 movwf PORTB ; PORTB = WREG
40
41 loop:
42 movlw .246 ; WREG = 256 - 10 = 246
43 movwf CONTADOR ; Passa WREG para CONTADOR
44 btfsc botao ; Botao foi pressionado?
45 ; (Testa se bit 0, se sim, pula linha)
46 goto apaga_led ; N o , desvia para apagar led
47 call pisca_led_aux1 ; Sim, pisca 10 vezes o led
48
49 apaga_led:
50
51 bcf led ; Apaga led
52 goto loop ; Volta para loop
53
54 pisca_led_aux1:
55 call pisca_led_aux2 ; Chama a rotina aux2
56 incfsz CONTADOR,F ; Incrementa CONTADOR, se zero pula
57 goto pisca_led_aux1 ; Recomea a rotina aux1
58 goto loop ; CONTADOR=0x00, ir para loop
59
60 pisca_led_aux2:
61
62 bsf PORTB,RB1 ; Liga led
63 call delay
64 bcf PORTB,RB1 ; Desliga led
6 Roteiro 3, 2020.2 ANO 2021
65 call delay
66
67
68 delay:
69 movlw D’200’
70 movwf TEMP1 ; Armazenao valor 200
71 delay_aux1:
72 movlw D’250’
73 movwf TEMP2 ; Armazena o valor 250
74 delay_aux2:
75 nop ; Gasta 1 ciclo de m quina
76 nop
77 nop
78 nop
79 nop
80 nop
81 nop
82 decfsz TEMP2 ; Decrementa TEMP2 e testa se zero
83 ; Se for zero, pula a prxima i n s t r u
84 goto delay_aux2 ; Total de 2500 ciclos
85 decfsz TEMP1 ; Decrementa TEMP1 e testa se zero
86 ; Se for zero, pula a prxima i n s t r u
87 goto delay_aux1 ; Ao final 500000 ciclos
88 return
89 end
teste02.asm
Roteiro 3, 2020.2 ANO 2021 7
	Introdução
	Objetivos
	Procedimento
	Softwares Utilizados
	Operações Aritiméticas
	Soma (INCF, INCFSZ, ADDWF e ADDLW)
	SUBTRAÇÃO (DECF, DECFSZ, SUBWF e SUBLW)
	Multiplicação e divisão por 2
	Operações Lógicas
	AND (ANDWF e ANDLW)
	OR (IORWF e IORLW)
	XOR (XORWF e XORLW)
	COMPLEMENTO (COMF)
	Exemplo 1
	Simulação no MPLab
	Exemplo 2
	Exercícios
	Referências