Escreva um programa em assembly para monitorar o bit PC3. Quando o bit estiver com valor alto, escrever 0x55 em PORTD.
Passo 1
Beleza, manda ver: a questão pede um programa em Assembly (vamos assumir AVR, tipo ATmega328P) que fique monitorando o bit PC3. Sempre que esse bit estiver em nível lógico alto (1), a gente deve colocar o valor 0x55 em PORTD.
Matéria envolvida: configuração de registradores de direção (DDR), leitura de pinos (IN), teste de bit (SBRC) e escrita em porta (OUT). Vamos precisar entender como configurar DDRx, ler PINx, usar instruções de teste/branch e carregar constantes em registradores.
Matéria envolvida: configuração de registradores de direção (DDR), leitura de pinos (IN), teste de bit (SBRC) e escrita em porta (OUT). Vamos precisar entender como configurar DDRx, ler PINx, usar instruções de teste/branch e carregar constantes em registradores.
Passo 2
Configurar os registradores de direção:
- DDRC define se cada pino de PORTC é entrada (0) ou saída (1). Como queremos ler PC3, deixamos esse bit como 0.
- DDRD define porta D como saída se 1. Vamos mandar 0x55 para PORTD, então configuramos todos ou só os pinos que interessam como saída (por simplicidade, vamos setar todo o DDRD para 1).
Em Assembly AVR, fazemos assim:
ldi r16, 0x00 ; r16 = 0x00
out DDRC, r16 ; todos PCx como entrada
ldi r16, 0xFF ; r16 = 0xFF
out DDRD, r16 ; todos PDx como saída
Passo 3
Agora precisamos de um loop infinito que:
- Leia o registrador PINC (estado atual dos pinos C).
- Teste o bit 3 (PC3).
- Se estiver alto, escreva 0x55 em PORTD.
- Volte pro início e repita.
Para ler PINC:
loop:
in r17, PINC ; traz em r17 o estado de todos os pinos C
Passo 4
Teste de bit PC3 em r17. Usamos SBRC (Skip if Bit in Register is Cleared), que pula a próxima instrução se o bit especificado estiver em 0. Ou seja:
sbrc r17, 3 ; se bit 3 de r17 (=PC3) for 0, pula o próximo rjmp
rjmp write55 ; se não pulou, significa que PC3=1, então vai pro label write55
rjmp loop ; PC3=0, volta ao início do loop sem escrever nada
Passo 5
No label
write55
, carregamos 0x55 em um registrador e escrevemos em PORTD, depois voltamos ao loop:write55:
ldi r18, 0x55 ; r18 = 0x55
out PORTD, r18 ; escreve 0x55 em PORTD
rjmp loop ; volta pra ler PINC de novo
Resposta
Segue o programa completo em AVR Assembly:
;--------------------------------------------------
; Programa: Monitora PC3 e escreve 0x55 em PORTD
;--------------------------------------------------
.include "m328pdef.inc" ; nome do header para ATmega328P (ajuste conforme o MCU)
.cseg
rjmp start
start:
; 1) Configurações iniciais
ldi r16, 0x00
out DDRC, r16 ; DDRC = 0x00 -> PC3 como entrada
ldi r16, 0xFF
out DDRD, r16 ; DDRD = 0xFF -> todos PDx como saída
loop:
; 2) Leitura de PINC
in r17, PINC ; r17 = estado dos pinos C
; 3) Teste do bit PC3 (bit 3)
sbrc r17, 3 ; se PC3 == 0, pula próximo rjmp
rjmp write55 ; se PC3 == 1, vai escrever 0x55
rjmp loop ; se PC3 == 0, volta pro início
write55:
; 4) Escreve 0x55 em PORTD
ldi r18, 0x55
out PORTD, r18
rjmp loop ; repete indefinidamente