Escreva um programa em assembly para transferir os valores lidos em PD6 e PD7 e escrevê-los em PC 0 e PC7, respectivamente.
Passo 1
O exercício pede: “Escrever um programa em Assembly (AVR) que leia os bits PD6 e PD7 do PORTD e escreva esses valores em PC0 e PC7 do PORTC, respectivamente.”
Conteúdo envolvido:
Conteúdo envolvido:
- Registradores DDRx, PINx e PORTx (configurar direção e ler/escrever pinos)
- Instruções de manipulação de bit: SBI, CBI, SBIS, SBIC
- Laço infinito com RJMP
O que você precisa saber:
- DDRx define se o pino é entrada (0) ou saída (1).
- PINx lê o estado físico do pino.
- PORTx escreve no pino (saída) ou ativa pull-up (entrada).
- SBIC/SBIS pulam a próxima instrução dependendo do estado de um bit em um registrador I/O.
- CBI/SBI limpam ou setam um bit em um registrador I/O.
Passo 2
Configurar direções de pino:
- Queremos PC0 e PC7 como SAÍDA → DDRC deve ter bits 0 e 7 em ‘1’.
- PD6 e PD7 como ENTRADA → DDRD deixa bits 6 e 7 em ‘0’ (valor reset é 0).
Em Assembly fica assim:
; vamos colocar 1 em PC0 e PC7:
ldi r16, (1<<PC0)|(1<<PC7) ; r16 = 0b1000_0001
out DDRC, r16 ; DDRC = 0b1000_0001
; garantir que não há pull-up em PD6/PD7 (opcional)
ldi r16, 0x00
out PORTD, r16
Teoria aplicada:
•
•
(1<<PC0)|(1<<PC7)
é a operação lógica em LaTeX:•
out DDRC, r16
grava no registrador de direção.Passo 3
Fazer o loop que copia PD6→PC0 e PD7→PC7, bit a bit, sem mexer nos demais bits de PORTC:
-
Testar PD6:
- SBIC PIND, PD6 → se PD6 = 0, pula o próximo comando;
- se PD6 = 1, executa
SBI PORTC, PC0
(seta PC0); - depois,
SBIS PIND, PD6
eCBI PORTC, PC0
garantem que, se PD6 = 0, a gente limpe PC0.
-
Mesmo para PD7→PC7.
Em Assembly:
loop:
; PD6 -> PC0
sbic PIND, PD6 ; se PD6==0, pula o próximo
sbi PORTC, PC0 ; senão (PD6==1), seta PC0
sbis PIND, PD6 ; se PD6==1, pula o próximo
cbi PORTC, PC0 ; senão (PD6==0), limpa PC0
; PD7 -> PC7
sbic PIND, PD7
sbi PORTC, PC7
sbis PIND, PD7
cbi PORTC, PC7
rjmp loop ; volta e repete
Teoria das instruções:
• SBIC (Skip if Bit in I/O Cleared) → pula a próxima instrução se o bit for 0.
• SBIS (Skip if Bit in I/O Set) → pula a próxima instrução se o bit for 1.
• SBI e CBI setam e limpam bits diretamente no registrador PORTx.
• SBIC (Skip if Bit in I/O Cleared) → pula a próxima instrução se o bit for 0.
• SBIS (Skip if Bit in I/O Set) → pula a próxima instrução se o bit for 1.
• SBI e CBI setam e limpam bits diretamente no registrador PORTx.
Passo 4
Explicando o laço infinito:
rjmp loop
faz um “goto” para a labelloop
, garantindo que a cada ciclo o programa releia PD6/PD7 e atualize PC0/PC7 em tempo real.
Resposta
;------------------------------------------------
; Programa AVR: copia PD6->PC0 e PD7->PC7
;------------------------------------------------
.include "m8def.inc" ; define nomes de registradores (ex: DDRC, PIND, etc)
.cseg
.org 0
rjmp start
start:
; Passo 2: configuração de pinos
ldi r16, (1<<PC0)|(1<<PC7) ; PC0 e PC7 como saída
out DDRC, r16
ldi r16, 0x00 ; garantir sem pull-up em PDx
out PORTD, r16
loop:
; Passo 3: leitura de PD6 e atualização de PC0
sbic PIND, PD6
sbi PORTC, PC0
sbis PIND, PD6
cbi PORTC, PC0
; leitura de PD7 e atualização de PC7
sbic PIND, PD7
sbi PORTC, PC7
sbis PIND, PD7
cbi PORTC, PC7
rjmp loop ; repete para sempre
Pronto! Esse código configura os pinos direitinho e, dentro do laço, lê PD6/PD7 e reflete o estado em PC0/PC7 sem mexer nos outros bits de PORTC.