UNIVASF Microprocessadores e Microcontroladores Conjunto de Instruções do PIC16F877A Prof. Rodrigo Ramos
[email protected]
Instruções de processamento de dados
addlw k −
Adiciona constante k a WREG e guarda em WREG.
−
Operação: w ← w + k
−
Ex.: addlw 55
addwf f,d Adiciona conteúdo do registrador f a WREG e guarda ou em WREG ou no próprio f. − −
Operação: d ← w + f
−
Ex.: addwf 0x20,f
Instruções de processamento de dados (cont.) Copie o seguinte trecho do programa e verifique os flags C e DC sendo modificados.
movlw movwf addwf
10 0x20 0x20, w
movlw 160 movwf 0x20 addwf 0x20, w goto $
; adiciona 0x0A a 0x0A ; e guarda em WREG/ Flag DC = 1
; adiciona 0xA0 a 0xA0 ; e guarda em WREG/ Flag C = 1
Instruções de processamento de dados (cont.)
subwf f, d Subtrai do conteúdo do registrador f o conteúdo de WREG e guarda ou em WREG ou no próprio f. − −
Operação: d ← f + (-w)
−
Na verdade: d ← f + [ (w ^ 0xFF) + 1 ]
XOR
Ex.: Se quiséssemos realizar a operação 1 – 2 no PIC, faríamos: −
movlw movwf movlw subwf
1 0x20 2 0x20, w
Carry: “empréstimo negativo” Resultado negativo: C = 0 Resultado positivo: C = 1
Instruções de processamento de dados (cont.)
sublw k −
Operação: w ← k + (-w)
−
Trabalha de modo similar a subwf.
Ex.: Se quiséssemos realizar as operações 1 – 2 e 2 – 1 no PIC, faríamos: −
movlw 2 sublw 1 movlw 1 sublw 2 −
O que faz a operação abaixo?
sublw −
0
O que fazer para subtrair um valor de WREG?
addlw
-45
Instruções de processamento de dados (cont.)
decf f, d
incf f, d
−
Operações de incremento e decremento de f.
−
Resultado é salvo em d (WREG ou f).
comf f, d Complementa (inverte logicamente) o conteúdo do um registrador f, com resultado salvo em d. − −
Complemento de 1.
−
Para complemento de 2, deve-se fazer: comf f, d incf f, d
Instruções de processamento de dados (cont.) Verifique o programa abaixo e tente prever o resultado final dos registradores 0x20 e WREG.
movlw 47 movwf 0x20 incf incf incf
0x20, f 0x20, f 0x20, f
decf decf decf
0x20, w 0x20, w 0x20, w
comf incf
0x20, f 0x20, f
goto
$
Instruções de processamento de dados (cont.)
andlw k
AND entre k e o conteúdo de WREG. andwf f, d
AND entre o conteúdo de f e o conteúdo de WREG. iorlw k
(Inclusive) OR entre k e o conteúdo de WREG. iorwf f, d
(Inclusive) OR entre o conteúdo de f e o conteúdo de WREG. xorlw k
XOR (ou exclusivo) entre k e o conteúdo de WREG. xorwf f, d
−
−
−
−
−
−
XOR entre o conteúdo de f e o conteúdo de WREG.
Instruções de processamento de dados (cont.)
rlf f, d Deslocamento à esquerda do conteúdo de f, salvando resultado em d (rotate left - rl). − −
Deslocamento com carry STATUS
rrf f, d Deslocamento à esquerda do conteúdo de f, salvando resultado em d (rotate right - rr). − −
Deslocamento com carry STATUS
Instruções de processamento de dados (cont.) Para que não se perca nenhum bit no processo de rotação, pode-se usar o seguinte trecho de código (chamado snippet - fragmento) rrf Reg, w rrf Reg, f
Na primeira instrução, o carry é carregado com o LSB de Reg (Reg<0>) e o resultado é salvo em WREG. Na segunda instrução, o carry é colocado no MSB de Reg (Reg<7>).
Instruções de processamento de dados (cont.) O código a seguir mostra o uso do snippet anterior para deslocar um bit do registrador 0x20 de 4 posições.
movlw b'00100000' movwf 0x20 rrf 0x20, w rrf 0x20, f rrf 0x20, w rrf 0x20, f rrf 0x20, w rrf 0x20, f goto $
Exercício 1 Escreva um programa que realize a multiplicação 9 x 5 (note que N x 5 = N x 4 + N x 1).
Lembrar que uma rotação à esquerda com um zero em LSB equivale a uma multiplicação por 2, uma segunda rotação equivale a multiplicar por 4 e assim por diante.
Não usar desvio condicional, apenas as operações de transferência e de processamento de dados.
Exercício 2 Escreva um programa para somar dois números de 16 bits.
DICA: Utilize labels para especificar os registradores que guardarão os valores a serem usados. Dica: use a diretiva CBLOCK para definir blocos de constantes.
CBLOCK 0x20 Var1, Var2, Var3, ..., VarN ENDC Não usar desvio condicional, apenas as operações de transferência e de processamento de dados.
Instruções de desvio
goto k −
Desvia programa para o ponto k (geralmente um label)
−
Desvio incondicional sem retorno.
−
Dois ciclos de máquina.
Lembrar que a instrução só consegue endereçar 211 bytes = 2048 bytes (0x800). Para valores de labels acima disso, devese usar os bits PCLATH<4:3>.
−
Organização da Memória (cont.)
Memória de programa −
13 bits para endereçamento
−
8k palavras x 14 bits
0x0800 = 0000 1000 0000 0000 0x1000 = 0001 0000 0000 0000 0x1800 = 0001 1000 0000 0000 HIGH
LOW
Instruções de desvio (cont.) Como exemplo do uso do goto, considere o código abaixo. Habilite a opção View → Program Memory do MPLAB.
goto movf
FirstLabel STATUS, w
; Instrução não executada
FirstLabel: movlw HIGH SecondLabel ; HIGH retorna o byte mais signif. movwf PCLATH goto SecondLabel org 0x376 movlw 40 org 0x1B76 SecondLabel: goto
$
; Endereco na pagina 3 ; Execução do goto $ abaixo
Instruções de desvio (cont.)
call k −
Chamada de subrotina especificada por k.
Operação idêntica à goto, com exceção de que PC é salvo na pilha.
− −
Dois ciclos de instrução.
Ao fim da sub-rotina, uma instrução return (ou equivalente) faz com que o fluxo retorne ao ponto seguinte à chamada.
−
Pilha (13-bits x 8) Topo da pilha
ULA
Instruções de desvio (cont.)
return −
Retorno de sub-rotina.
retlw k Retorno de sub-rotina, com valor k copiado em WREG, útil para criação de tabelas.
−
−
Equivalente a
movlw k return
retfie −
Retorno de interrupção. INTCON
= 1 (habilita interrupções) Pilha (13-bits x 8) Topo da pilha
ULA
Exercício Re-escreva o programa para somar dois números de 16 bits, utilizando agora uma sub-rotina, de forma a que seja possível realizar a soma diversas vezes a partir da chamadas à sub-rotina.
Instruções de desvio (cont.)
Desvios condicionais – só desviam fluxo se condição for verdadeira.
Instruções “skip on bit condition” - salta a próxima instrução dependendo da condição do bit testado.
btfsc f, b (bit test file-reg, skip if clear) −
btfss f, b (bit test file-reg, skip if set) −
Testa o bit b do registrador f e salta próxima instrução se b = 0. Testa o bit b do registrador f e salta próxima instrução se b = 0.
Tempo de execução: −
1 ciclo se condição for falsa (sem desvio)
−
2 ciclos se verdadeira (desvio)
Ex.: Saltar para um endereço se flag Z for 1. btfsc STATUS, Z goto Label
; Testa se Z = 0 e salta se V ; Se Z = 1, desvia para Label
Exercício Escreva um programa em assembly que compare dois valores vA e vB. Caso eles sejam iguais, escreva no registrador 0x25 o valor 0x0E. Caso sejam diferentes, escreva 0x0D.
Instruções de desvio (cont.) Desvios condicionais – de forma geral, desvios baseados na comparação de dois valores têm uma forma definida.
Pseudo-código: if (A condição B) then goto Label
Assembly: movf FirstValue, w subwf SecondValue, w btfs# STATUS, flag goto Label
Onde FirstValue, SecondValue e # são definidos na tabela a seguir.
Caso sejam usadas constantes, movf e subwf devem ser substituídas por molw e sublw.
Instruções de desvio (cont.)
Instruções de desvio (cont.)
Desvios condicionais
incfsz f, d Incrementa o registrador f, salva resultado em d e salta próxima instrução se o resultado do incremento for zero. −
decfsz f, d Decrementa o registrador f, salva resultado em d e salta próxima instrução se o resultado do decremento for zero. −
Tempo de execução: −
1 ciclo se resultado não for zero (não salta próxima instrução)
−
2 ciclos se for zero (salta)
São geralmente utilizados para controle de loops.
Instruções de desvio (cont.) O código a seguir pode ser usado para repetição de um trecho de programa 10 vezes.
movlw movwf
10 0x20
; carrega contador
Loop: ; Instruções a serem executadas repetidamente decfsz 0x20, f ; decrementa contador goto Loop ; se não é zero, repete ; caso contrário, continua
Exercício Escreva um programa em assembly para multiplicação de dois números de 8 bits.
Lembre que o resultado deve ser um número de 16 bits.
Tabelas Estruturas de dados para armazenamento de constantes e apontadas por um índice (banco de dados de uma coluna).
Ex.: Tabela de quadrados de números.
São usadas para retornar valores de acordo com o parâmetro ado à tabela.
A forma mais tradicional no PIC é com o uso de uma subrotina que adiciona uma constante ao PC, com o uso da instrução addwf PCL, f.
No novo endereço, uma instrução retlw é usada para salvar em WREG o valor a ser retornado.
IMPORTANTE: PC é incrementado antes da execução da instrução!!
Tabelas (cont.) Exemplo: Programa para determinar quadrado de um número entre 0 e 6.
Quadrado: addwf retlw retlw retlw retlw retlw retlw retlw main movlw call goto END
PCL,f 0 d'1' d'4' d'9' d'16' d'25' d'36' 0x05 Quadrado $
; PCL é incrementado antes da execução. ; Assim, PCL = 5 + 2 = 7
Tabelas (cont.) Deve-se ter o cuidado de não haver cruzamento de página na tabela. Se houver, PCLATH deve ser modificado.
Quadrado: movwf movlw movwf movf addlw btfsc incf movwf Quadrado2: retlw retlw ...
Temp HIGH Quadrado2 PCLATH Temp, w LOW Quadrado2 STATUS, C PCLATH, f PCL 0 1
Exercício Escreva um programa em assembly para acionamento de um display de 7 segmentos usando uma tabela. Os bits de acionamento dos números de 0 a 9 devem estar disponíveis em uma tabela.
Atrasos (Delays)
Unidade básica de tempo é o ciclo de instrução:
Ciclo de instrução = 4 / freqüência de clock
Ex.: Para um clock de 4 MHz: Ciclo
de instrução = 4 / 4 MHz = 1 us.
Atrasos de tempo podem ser convertidos em ciclos de instrução pela expressão:
Ciclos de instrução = Atraso de tempo * (Freq. Clock / 4)
Ex.: Para um atraso de 5 ms em um PIC rodando a 4 MHz, temos:
Ciclos de instrução = 5 x 10-3 (4 x 106 / 4) = 5.000
Assim, são necessários 5.000 ciclos de instruções para obter um atraso de 5 ms.
Atrasos (cont.) A maneira mais simples de criar atrasos é 'gastando tempo' com instruções.
Para isso, pode-se usar loops que decrementem um contador, podendo-se contar 256 vezes (ciclos de instrução).
Com um contador duplo, conta-se aproximadamente o quadrado disto. Ex. Contador de ~(200)2 = 400.000 ciclos = 0.4 s
delay: movlw .200 ; w = 200 decimal movwf j ; j = w jloop: movwf k ; k = w kloop: decfsz k,f ; k = k-1, pula se zero goto kloop decfsz j,f ; j = j-1, pula se zero goto jloop return
Atrasos (cont.)
Forma alternativa:
delay: movlw LOW Valor movwf DelayL movlw HIGH Valor movwf DelayH loop: decf DelayL, f btfsc STATUS, Z decfsz DelayH, f goto loop return
Valor = ((atraso * freqüência/4)/5) + 256 Ex.: 5 ms com clock 4 MHz Valor = ( (5 x 10-3 x 4 x 106) / 5) + 256 = 2.756 = 0x0AC4
Atrasos (cont.) Para atrasos maiores, usa-se loop externo.
Valor pode ir até 65.505 (0xFFFF). Porém, por facilidade, faz-se Valor máximo = 50.256 (0xC450), o que dá 250.000 ciclos (0.25 s com 4 MHz).
Para ~1 s, repete-se 4 vezes o loop.
Exercício: Testar código ao lado para que acenda e apague um led conectado ao pino RB0.
delay: movlw movwf loopExt: movlw movwf movlw movwf loop: decf btfsc decfsz goto decfsz goto return
4 ValorRep LOW Valor DelayL HIGH Valor DelayH DelayL, f STATUS, Z DelayH, f loop ValorRep loopExt
Exercício Escreva um programa em assembly que conte de 0 até 9, mostrando cada número da contagem em um display de 7 segmentos.
Cada número deve ser mostrado durante um intervalo de tempo de 0,5 s.
Bibliografia
MPASM 's Guide, Microchip Technology Inc., 2005.
PIC16F87xA Data Sheet, Microchip Technology Inc., 2003.
M. Predko, “Programming and Customizing the PIC Microcontroller”, 3rd. Ed., McGraw-Hill, 2008.
F. Pereira, “Microcontroladores PIC: Técnicas Avançadas – 16F627 e 16F628”, 5a. Ed., Érica, 2008.