Jag har en kodsnutt i AVR assembler jag skrev för att ta emot signaler från en IR-fjärr.
Mest bara för att se om det gick. Ska se om jag hittar den...
Det är "RC5" du ska googla.
EDIT:
Jag hittade den.
Tänk nu på att det här är gammal kod som jag knackade när jag höll på att lära mig AVR så det finns säkerligen mycket som kan förbättras.

Jag tror att det fungerar så att den tar emot ett kommando och skickar ut den på serieporten, jag har inte tokgranskat koden och det var LÄNGE sedan jag skrev den.
De rutiner som är intressanta är interruptrutinen som tar emot datat från ir-sensorn. OUT från sensorn kopplas till IRQ0. Och sedan "scan rc5"- rutinen som på något sätt tar hand om datat. Det borde man väl rimligtvis lägga in i irq-rutinen även det.
Det finns även en lysdiod på PortB 4 som blinkar när den tar emot data - som visuell indikering.
Skrivet för en 8515 på 8MHz
Kod: Markera allt
;******* miljövariabler ******
.include "8515def.inc"
.def Temp =R16
;.def =R17
.def OldAd =R18
.def Key =R19
.def UtData =R20
.def Data =R21
.def Temp2 =R22
.def bitcnt =R23
.def SysAd =R24
.def SysCmd =R25
;.def =R26 ;res
;.def =R27 ;res
;.def =R28 ;res
;.def =R29 ;res
;.def =R30 ;res
;.def =R31 ;res
;******* vektorer ******
.cseg
.org $00
rjmp Reset ;RESET
rjmp IRQ0 ;IRQ 0
reti ;IRQ 1
reti ;Timer/Counter 1 Capture Handler
reti ;Timer/Counter 1 Compare A Handler
reti ;Timer/Counter 1 Compare B Handler
reti ;Timer/Counter 1 Overflow Handler
reti ;Timer/Counter 0 Overflow Handler
reti ;SPI Serial transfer complete interrupt.
rjmp RS232Rec ;Uart RX complete.
reti ;Uart TX data register empty.
reti ;Uart TX complete.
reti ;Analogue comparator interrupt.
;*************************************************************************
;* INITIERINGAR
;*************************************************************************
Reset:
; **** Stack Pointer Setup Code ****
ldi r16, $02 ; Stack Pointer setup
out SPH,r16 ; Stack Pointer High Byte
ldi r16, $5F ; Stack Pointer setup
out SPL,r16 ; Stack Pointer Low Byte
; **** UART Setup Code
ldi r16,$33 ;=> 9600 vid 8MHz
out ubrr,r16 ;till UART baudrate register
ldi r16,0b10011010 ;RX interrupt
out ucr,r16 ;till UART control register
; **** Sleep Mode And SRAM ****
ldi r16,0b00000010 ; Falling edge of IN0-> irq
out MCUCR, r16 ;
; **** Comparator Setup Code ****
ldi r16,$80 ;
out ACSR,r16 ; Comparator Disabled to save power
; **** Port A Setup Code ****
ldi r16,0b11111111 ; I/O direction values
out DDRA,r16 ; Port A Direction Register
ldi r16,$FF ; Init value
out PORTA,r16 ; Port A value
; **** Port B Setup Code ****
ldi r16,0b11111111 ; I/O Direction Values
out DDRB,r16 ; Port B Direction Register
ldi r16,0b11111111 ; Init value
out PORTB,r16 ; Port B value
; **** Port C Setup Code ****
ldi r16,0b11111111 ; I/O direction values
out DDRC,r16 ; Port C Direction Register
ldi r16,$FF ; Init value
out PORTC,r16 ; Port C value
; **** Port D Setup Code ****
ldi r16,0b00001011 ; I/O direction values
out DDRD,r16 ; Port D Direction Register
ldi r16,$00 ; Init value
out PORTD,r16 ; Port D value
; **** Interrupt Setup Code ****
ldi r16,0b01000010 ;Int0 External Interrupt
out GIMSK,r16
ldi r16,0b0000000 ;No Timer/Counter Interrupt
out TIMSK,r16
sei ;Enable gobal iterrupt
clr SysAd
clr OldAd
clr SysCmd
clr Key
ldi UtData,$00 ;Startläge för utdata
rjmp main
;*************************************************************************
;* Interrupt0
;*************************************************************************
IRQ0:
rcall Delay450us ;Vänta 1/4 bit
sbic PIND,2 ;kontrollera att det fortfarande är en nolla in
reti ;om inte så var det nog bara brus => Hoppa tillbaka
cbi PORTB,4 ;Tänd "IR mottagningsdiod"
rcall Delay1800us ;Vänta annars in första "riktiga" biten
ldi bitcnt,7 ;Labba bitcnt för att läsa in de första 7 bitarna
clr SysAd ;Nollställ "system"
SysLoop:
lsl SysAd ;Rotera "system" vänster
sbis PIND,2 ;Testa INPINNE
sbr SysAd,1 ;Set bit 0 i "system" (inverterad)
rcall Delay1800us ;Vänta i 1.8mS
dec bitcnt ;Räkna ner antal bitar
brne SysLoop ;Loopa tills du hämtat 6
clr SysCmd ;Nollställ "command"
ldi bitcnt,6 ;Labba bitcnt för att läsa in de nästa 6 bitarna
CmdLoop:
lsl SysCmd ;Rotera "command" vänster
sbis PIND,2 ;Testa INPINNE
sbr SysCmd,1 ;Set bit 0 i "command" (inverterad)
rcall Delay1800us ;Vänta i 1.8mS
dec bitcnt ;Räkna ner antal bitar
brne CmdLoop ;Loopa tills du hämtat 6
rcall Delay1800us ;Vänta ut eventuella kvarvarande halva bitar
sbi PORTB,4 ;Släck "IR mottagningsdiod"
reti ;Återgå
;*************************************************************************
;*RS232Send
;*************************************************************************
RS232Send:
sbis usr,udre ;Vänta tills UART är redo
rjmp RS232Send
out udr,Data ;Kopiera "Data" till sendregistret
ret ;Återgå
;*************************************************************************
;* MAIN
;*************************************************************************
main:
rcall ScanRC5 ;Läs av kommando från fjärr
out PORTA,UtData
rjmp main
;*************************************************************************
;* ScanRC5
;*************************************************************************
ScanRC5:
cp SysAd,OldAd ;Jämför tidigare adress med ny (ny knapp?)
brne NewRC5 ;är de olika -> nytt kommando
ret ;är de inte olika så återgå
NewRC5:
mov OldAd,SysAd ;Spara undan nya adressen
cpi SysCMD,$01 ;är kommandot "1"
breq RC5_1 ;så hoppa till 1
cpi SysCMD,$02 ;osv
breq RC5_2
cpi SysCMD,$03
breq RC5_3
ret ;inget giltigt kommando -> återhopp
RC5_1:
andi UtData,$F0 ;Nollställ 4LSB (Peka ut adress "0")
ret ;återgå
RC5_2:
andi UtData,$F0 ;Nollställ 4LSB
ori UtData,$01 ;Peka ut adress "1"
ret ;återgå
RC5_3:
andi UtData,$F0 ;Nollställ 4LSB
ori UtData,$02 ;Peka ut adress "2"
ret ;återgå
;*************************************************************************
;* Delay - rutiner KLOCKADE i simulatorn för 8MHz (ej 1, 1800 & 450)
;*************************************************************************
Delay1us:;***********************************************
ldi r16,$03 ;Ladda r16 med 3 varv
LoopAV:
dec r16 ;Minska r16
brne loopAV ;Loopa till r16 nått 0
ret
Delay40us:;***********************************************
ldi r16,$6A ;Ladda r16 med 106 varv
Loop3:
dec r16 ;Minska r16
brne loop3 ;Loopa till r16 nått 0
ret ;Därefter återgå
Delay50us: ;*********************************************
ldi r16,$85 ;Ladda r16 med 133 varv
Loop:
dec r16 ;Minska r16
brne loop ;Loopa till r16 nått 0
ret ;Därefter återgå
Delay450us: ;***********************************************
ldi r22,$09 ;Ladda r22 med 9 yttervarv
LoopC:
ldi r16,$85 ;Ladda r16 med 133 varv
LoopD:
dec r16 ; Minska r16
brne loopD ; loopa till r16 nått 0
dec r22 ; Minska r22
brne loopC ;Loopa till r22 nått 0
ret ;Därefter återgå
Delay1800us: ;***********************************************
ldi r22,$24 ;Ladda r22 med 36 yttervarv
LoopA:
ldi r16,$85 ;Ladda r16 med 133 varv
Loop4:
dec r16 ; Minska r16
brne loop4 ; loopa till r16 nått 0
dec r22 ; Minska r22
brne loopA ;Loopa till r22 nått 0
ret ;Därefter återgå
Delay4ms: ;***********************************************
ldi r22,$2A ;Ladda r22 med 42 yttervarv
Loop1:
ldi r16,$00 ; Nollställ r16 (256 innervarv)
Loop2:
dec r16 ; Minska r16
brne loop2 ; loopa till r16 nått 0
dec r22 ; Minska r22
brne loop1 ;Loopa till r22 nått 0
ret ;Därefter återgå
RC5 fungerar så att den först skickar en adress. Som berättar vilken pryl som ska lyssna (TV, VCR, DVD, PVR)... och sedan data om vilken knapp som är nedtryckt.