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:
  • 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:
  1. DDRx define se o pino é entrada (0) ou saída (1).
  2. PINx lê o estado físico do pino.
  3. PORTx escreve no pino (saída) ou ativa pull-up (entrada).
  4. SBIC/SBIS pulam a próxima instrução dependendo do estado de um bit em um registrador I/O.
  5. 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:
DDRC = (1 ll PC0);lor;(1 ll PC7)
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:
  1. 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 e CBI PORTC, PC0 garantem que, se PD6 = 0, a gente limpe PC0.
  2. 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.

Passo 4

Explicando o laço infinito:
  • rjmp loop faz um “goto” para a label loop, 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.

Exercícios relacionados