一般常用的红外遥控器编码规则都差不多,基本上都同6221原理一样(可在网上找到)
PIC单片机接收时:
如果用54,57这类片子做的话有一定的难度(假如要做成实时控制的;比如说你还要驱动显示,驱动步进电机,在加上几个按键)原因就是这类片子没有中断
例程如下(用来解6221;分频比为256)
- RF:
- BTFSC PORTB,2;;B2口用做接收口
- GOTO RF1
- BTFSS DOWNBIT;;检测下降沿标制
- CLRF RTCCOUNT
- BSF DOWNBIT;制下降沿标制
- BTFSS UPBIT;;检测上升沿标制
- RETLW 0
- BTFSC IDBIT;;检测码头标制
- GOTO RF3
- MOVLW 2AH
- SUBWF RTCCOUNT,0
- BTFSS STATUS,0
- GOTO RF2
- MOVLW 36H
- SUBWF RTCCOUNT,0
- BTFSC STATUS,0
- GOTO RF2
- BTFSC IDBIT
- GOTO RF3
- MOVLW .8
- MOVWF LOOP
- MOVLW .3
- MOVWF LOOPCOUNT
- CLRF DATACOUNT
- BSF IDBIT
- BSF DOWNBIT
- BCF UPBIT
- CLRF RTCCOUNT
- RETLW 0
- RF1:
- BTFSS DOWNBIT
- RETLW 0
- BSF UPBIT
- RETLW 0
- RF2:
- BCF DOWNBIT
- BCF UPBIT
- BCF IDBIT
- CLRF RTCCOUNT
- RETLW 0 ;遥控接收
- RF3:
- MOVLW 02H
- SUBWF RTCCOUNT,0
- BTFSS STATUS,0
- GOTO RF4
- MOVLW 0CH
- SUBWF RTCCOUNT,0
- BTFSS STATUS,0
- GOTO RF4
- GOTO RF2
- RF4:
- MOVLW 08H
- SUBWF RTCCOUNT,0
- BTFSC STATUS,0
- BSF 3H,0
- MOVLW 07H
- SUBWF RTCCOUNT,0
- BTFSS STATUS,0
- BCF 3H,0
- RLF DATACOUNT,1
- BSF DOWNBIT
- BCF UPBIT
- CLRF RTCCOUNT
- DECFSZ LOOP,1
- RETLW 0
- MOVLW .8
- MOVWF LOOP
- DECFSZ LOOPCOUNT
- RETLW 0
- BSF RFBIT;;制接收完标制
- BCF DOWNBIT
- BCF UPBIT
- BCF IDBIT
- CLRF RTCCOUNT
- RETLW 0
- //////////////////////////////////////////////////////////
- TIME:
- BTFSC TIMEPD1
- GOTO TIME1
- MOVF RTCC,0;;(
- MOVWF TIMEONE
- BSF TIMEPD1
- RETLW 0 ;定时查寻
- TIME1:
- MOVF RTCC,0
- SUBWF TIMEONE,0
- BTFSC STATUS,2
- RETLW 0
- BCF TIMEPD1
- INCF RTCCOUNT,1
- RETLW 0
- ////////////////////////////////////////////////
在这里我是用查询的方式来定时的(RTCCOUNT)只是在解码时不需要去追求时间精度;我是去查RTCC有没有发生跳变如有则表示时间过了 256US---RTCCOUNT加一;这样做有一个好处---你不必去管RTCC具体的值是多少,(RTCC去做精确的时钟定时;在这个查询的子程序中你可以去判断键扫,显示刷新,驱动步进电机等等)
相应的C代码如下:
- unsigned char rfcount,
- loop,
- rftime,//查询定时器
- k;
- bit rfbit, //接收完标制
- lowbit1,
- lowbit2,
- downbit,
- rfgobit;
- unsigned char dispcount[5];//结果
- #define rfin RC6
- ////////////////////////////////////////////////////////////////////////////////
- rf( )//遥控接收
- {
- if(rfbit==0)
- {
- if((lowbit1==0)&&(rfin==0))
- {
- downbit=1;
- rftime=0;
- lowbit1=1;
- return;
- }
- if((lowbit1==1)&&(rfin==1))
- {
- lowbit2=1;
- return;
- }
- if((lowbit1==1)&&(lowbit2==1)&&(RC6==0))
- {
- lowbit1=0;
- lowbit2=0;
- if((rftime>=40)&&(downbit==1))//遥控接收;
- {
- rfgobit=1;
- loop=0;
- rfcount=0;
- k=1;
- rftime=0;
- return;
- }
- rfcount=rfcount+1;
- loop=loop+1;
- if(rfcount>=31)
- {
- rfgobit=0;
- downbit=0;
- rfcount=0;
- rfbit=1;
- loop=0;
- return;
- }
- if((rftime>=7)&&(rfgobit==1))
- {
- dispcount[k]=dispcount[k]|0x80;
- rftime=0;
- if(loop==8)
- {
- k=k+1;
- loop=0;
- return;
- }
- dispcount[k]=dispcount[k]>>1;
- return;
- }
- if((rftime<5)&&(rfgobit==1))
- {
- dispcount[k]=dispcount[k]&0x7f;
- rftime=0;
- if(loop==8)
- {
- k=k+1;
- loop=0;
- return;
- }
- dispcount[k]=dispcount[k]>>1;
- return;
- }
- }
- }
- }
(查询子程序同汇编)
假如用中断的话也可用时间查询的方法,只是接收口改用带中断的口线;RB4--RB7,CCP1,CCP2,都可以。建议不要用RB0(他当按键输入最好用);
还有就是解码时的容陷和误码处理(有一种写法是在解码移位时利用进位标制C同时移位;我个人认为不太好,因为只要差一位没接收到,整个接收到的都是误码且浪费时间)