irrxj: rcall irrxd jbrc ttlcnt,7,cmp_rdata ret cmp_rdata: clr irdataj cmp_loop1: ldiw Z,irtab_start*2 add ZL,irdataj brcc PC+2 inc ZH add ZL,irdataj brcc PC+2 inc ZH add ZL,irdataj brcc PC+2 inc ZH add ZL,irdataj brcc PC+2 inc ZH add ZL,irdataj brcc PC+2 inc ZH adiw ZL,1 ;Z=irtab_start*2+irdataj*5+1 ldiw X,rxd mov cntr2,ttlcnt ;rxdから最大4バイト比較 mov acc,cntr2 blei acc,4,cmp_loop2 adiw XL,2 ;PANA(6Byte)は先頭の0x0220をスキップ dec cntr2 dec cntr2 cmp_loop2: ld acc,X+ lpmr r17 bne acc,r17,cmp_next ;not matched(goto cmp_next) djnz cntr2,cmp_loop2 rcall beep ret ;matched(received data is in irdataj) cmp_next: inc irdataj blti irdataj,(irtab_end-irtab_start)/5*2,cmp_loop1 mvi ttlcnt,0x80 ;no data matched ret irrxd: ldiw X,rxd mvi rxdcnt,RXDLEN clriow TCNT1 ;TCNT1H:TCNT1L=0 wbc pIRIN,IRIN ;~|____| low:?ms in acc,TCNT1H tst acc jnz kaden ;6.5ms(25us*256)以上(9ms typ)ならばkaden in acc,TCNT1L andi acc,0xc0 jnz sony_light ;1.6ms(25us*64)以上(2.6ms typ)ならばsonyまたはlight ;*********** ; goto irrx_err ;SHARP(No START bit, 2 byte + 2 byte)*********************************** sharp0: mov acc,rxdcnt blti acc,RXDLEN-3,sharp6 ;if(rxdcnt<3) goto sharp6 ...4Byteで終了 bgei acc,RXDLEN-1,sharp1 ;if(rxdcnt>=5) goto sharp1 ...1st,2nd Byte blei acc,RXDLEN-3,sharp1 ;if(rxdcnt<=3) goto sharp1 ...4th Byte wbs pIRIN,IRIN ;if(rxdcnd==4) ...3rd Byte clrio TCNT1L ;TCNT1L=0 wbc pIRIN,IRIN sharp1: clr rxdbuf mvi cntr3,8 ;1バイトは8ビット sharp2: in acc,TCNT1L bgei acc,105,sharp5 ;dur:2.75ms(25us*105)以上ならばチェック jbis pIRIN,IRIN,sharp2 ;~|__|~~ high:1ms(0)/2ms(1) in acc,TCNT1L ldi r17,60 cp r17,acc ;if(TCNT1L(dur)>1.5ms) C=1 else C=0 ror rxdbuf clrio TCNT1L ;TCNT1L=0 wbc pIRIN,IRIN ;~|_|~~~~|_| sharp4: djnz cntr3,sharp2 st X+,rxdbuf ;rxdbufをrxdに転送 djnz rxdcnt,sharp0 sharp6: mvi cntr3,8 ;1バイトは8ビット goto irrx_end sharp5: mov acc,cntr3 bgti acc,1,irrx_err ;エラー clc ror rxdbuf goto sharp4 ;家電協(START:9ms typ)**************************************** kaden: clrio TCNT1L ;TCNT1L=0 kaden1: in acc,TCNT1L jgei acc,235,irrx_err ;high:6ms(25us*235)以上ならばエラー jbis pIRIN,IRIN,kaden1 ;~|____|~~| high:3ms(typ) jlei acc,59,irrx_err ;high:1.5ms(25us*59)以下ならばエラー kaden2: clr rxdbuf mvi cntr3,8 ;1バイトは8ビット kaden3: clrio TCNT1L ;TCNT1L=0 kaden4: in acc,TCNT1L jgei acc,59,irrx_err ;low:1.5ms(25us*59)以上ならばエラー jbic pIRIN,IRIN,kaden4 ;~|____|~~|__| low:0.5ms(typ) jlei acc,16,irrx_err ;low:0.4ms(25us*16)以下ならばエラー mov buf1,acc ;buf1=TCNT1L lsr buf1 add buf1,acc ;buf1=TCNT1L+TCNT1L/2...low時間x1.5 clrio TCNT1L ;TCNT1L=0 kaden5: in acc,TCNT1L bgei acc,156,irrx_end ;high:4ms(25us*156)以上ならば終了 jbis pIRIN,IRIN,kaden5 ;~|____|~~|__|~~| high:0.5ms/1.6(typ) blei acc,8,irrx_err ;high:0.2ms(25us*8)以下ならばエラー cp buf1,acc ;if(TCNT1L(high)>?ms) C=1 else C=0 ror rxdbuf djnz cntr3,kaden3 st X+,rxdbuf ;rxdbufをrxdに転送 djnz rxdcnt,kaden2 mvi cntr3,8 ;1バイトは8ビット goto irrx_end ;lowの時間でon判定(START:2.6ms typ)*************************************** sony_light: clr rxdbuf mvi cntr3,8 clrio TCNT1L ;TCNT1L=0 sony_light1: in acc,TCNT1L bgei acc,59,kaden1 ;high:1.5ms(25us*59)以上ならばkaden1へ jbis pIRIN,IRIN,sony_light1 goto sony3 sony: clr rxdbuf mvi cntr3,8 sony1: clrio TCNT1L ;TCNT1L=0 sony2: in acc,TCNT1L bgei acc,235,irrx_end ;6ms(25us*235)以上ならば終了 jbis pIRIN,IRIN,sony2 ;~|____|~~| high:0.6ms(typ) sony3: mov buf1,acc ;buf1=TCNT1L lsr buf1 add buf1,acc ;buf1=TCNT1L+TCNT1L/2...high時間x1.5 clrio TCNT1L ;TCNT1L=0 wbc pIRIN,IRIN ;~|____|~~|__| low:0.6ms(typ) in acc,TCNT1L cp buf1,acc ;if(TCNT1L(low)>0.9ms) C=1 else C=0 ror rxdbuf djnz cntr3,sony1 st X+,rxdbuf ;1バイトデータをバッファへ djnz rxdcnt,sony mvi cntr3,8 ;受信終了*************************************************** irrx_err: ;受信Error wbc pIRIN,IRIN ;___| highを待つ mvi ttlcnt,0x80 ret irrx_end: ;Byte数算出 mvi cntr2,RXDLEN sub cntr2,rxdcnt ;ttlcnt=cntr2=RXDLEN-rxdcnt mov ttlcnt,cntr2 mvi cntr1,8 sub cntr1,cntr3 ;端数bit... cntr1=8-cntr3 rz tst rxdcnt rz irrx_end2: clc ;C=0 ror rxdbuf djnz cntr3,irrx_end2 st X+,rxdbuf ;端数bitを格納 inc ttlcnt ret