关于用PIC单片机红外遥控的编码与解码的问题

来源:本站
导读:目前正在解读《关于用PIC单片机红外遥控的编码与解码的问题》的相关信息,《关于用PIC单片机红外遥控的编码与解码的问题》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《关于用PIC单片机红外遥控的编码与解码的问题》的详细说明。
简介:一般常用的红外遥控器编码规则都差不多,基本上都同6221原理一样

接收时:

如果用54,57这类片子做的话有一定的难度(假如要做成实时控制的;比如说你还要驱动显示,驱动步进电机,在加上几个按键)原因就是这类片子没有中断

例程如下(用来解6221;分频比为256)RF:BTFSC PORTB,2;;B2口用做接收口GOTO RF1BTFSS DOWNBIT;;检测下降沿标制CLRF RTCCOUNTBSF DOWNBIT;制下降沿标制BTFSS UPBIT;;检测上升沿标制RETLW 0BTFSC IDBIT;;检测码头标制GOTO RF3MOVLW 2AHSUBWF RTCCOUNT,0BTFSS STATUS,0GOTO RF2MOVLW 36HSUBWF RTCCOUNT,0BTFSC STATUS,0GOTO RF2BTFSC IDBITGOTO RF3MOVLW .8MOVWF LOOPMOVLW .3MOVWF LOOPCOUNTCLRF DATACOUNTBSF IDBITBSF DOWNBITBCF UPBITCLRF RTCCOUNTRETLW 0RF1:BTFSS DOWNBITRETLW 0BSF UPBITRETLW 0RF2:BCF DOWNBITBCF UPBITBCF IDBITCLRF RTCCOUNTRETLW 0 ;遥控接收RF3:MOVLW 02HSUBWF RTCCOUNT,0BTFSS STATUS,0GOTO RF4MOVLW 0CHSUBWF RTCCOUNT,0BTFSS STATUS,0GOTO RF4GOTO RF2RF4:MOVLW 08HSUBWF RTCCOUNT,0BTFSC STATUS,0BSF 3H,0MOVLW 07HSUBWF RTCCOUNT,0BTFSS STATUS,0BCF 3H,0RLF DATACOUNT,1BSF DOWNBITBCF UPBITCLRF RTCCOUNTDECFSZ LOOP,1RETLW 0MOVLW .8MOVWF LOOPDECFSZ LOOPCOUNTRETLW 0BSF RFBIT;;制接收完标制BCF DOWNBITBCF UPBITBCF IDBITCLRF RTCCOUNTRETLW 0//////////////////////////////////////////////////////////TIME:BTFSC TIMEPD1GOTO TIME1MOVF RTCC,0;;(MOVWF TIMEONEBSF TIMEPD1RETLW 0 ;定时查寻TIME1:MOVF RTCC,0SUBWF TIMEONE,0BTFSC STATUS,2RETLW 0BCF TIMEPD1INCF RTCCOUNT,1RETLW 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同时移位;我个人认为不太好,因为只要差一位没接收到,整个接收到的都是误码且浪费时间)

2在谈发送

原理是接收的逆过程

例程如下(用来发6221;分频比为256);///////////////////////////////////////////////////////////////////////////////////////////////READDIGT:MOVF SENDLOOP,0ADDWF PC,1GOTO SENDC4GOTO SENDC3GOTO SENDC2GOTO SENDC1GOTO SENDC0;///////////////////////////////////SENDC0:MOVF C4COUNT,0;;读要发的数据(假设要发5个字)RETURNSENDC1:MOVF C3COUNT,0RETURNSENDC2:MOVF C2COUNT,0RETURNSENDC3:MOVF C1COUNT,0RETURNSENDC4:MOVF C0COUNT,0RETURN;///////////////////////////////////SENDBIT:CLRF TIMEBCF PORTB,1SENDBIT1:CLRWDTMOVLW .35SUBWF TIME,0BTFSS STATUS,2GOTO SENDBIT1CLRF TIMEBSF PORTB,1SENDBIT2:CLRWDTMOVLW .18SUBWF TIME,0BTFSS STATUS,2GOTO SENDBIT2CLRF SENDLOOP ;码头数据发送//////////////////////////////////////////////SENDBIT3:CLRWDTBCF INTCON,7CALL READDIGTMOVWF SENDCOUNTBSF INTCON,7CALL SENDDIGTINCF SENDLOOP,1MOVLW .5SUBWF SENDLOOP,0BTFSS STATUS,2GOTO SENDBIT3CLRF TIMEBCF PORTB,1SENDDIGT5:CLRWDTMOVLW .2;;加发一个结束位SUBWF TIME,0BTFSS STATUS,2GOTO SENDDIGT5BSF PORTB,1BSF STARTBITRETURN;/////////////////////////////////////////////////////////////////////////////////////////SENDDIGT:;;实现0和1的发送MOVLW .8MOVWF LOOPSENDCOUNTSENDDIGTGBTFSS SENDCOUNT,7GOTO ZERSENDCLRF TIMESENDDIGT1:CLRWDTBCF PORTB,1MOVLW .2SUBWF TIME,0BTFSS STATUS,2GOTO SENDDIGT1CLRF TIMESENDDIGT2:CLRWDTBSF PORTB,1MOVLW .6SUBWF TIME,0BTFSS STATUS,2GOTO SENDDIGT2GOTO SENDOVERZERSEND:CLRF TIMESENDDIGT3:CLRWDTBCF PORTB,1MOVLW .2SUBWF TIME,0BTFSS STATUS,2GOTO SENDDIGT3CLRF TIMESENDDIGT4:CLRWDTBSF PORTB,1MOVLW .2SUBWF TIME,0BTFSS STATUS,2GOTO SENDDIGT4SENDOVER:RLF SENDCOUNT,1DECFSZ LOOPSENDCOUNTGOTO SENDDIGTGORETURN相应的C代码如下:(C5口是发送口)#i nclude#i nclude#i ncludeunsigned char dispcount[5];//要发送的码值unsigned char i,k,data,rfbit,zbit,rfgobit;#pragma interrupt_level 1interrupt adint(void){if(TMR1IF==1){TMR1IF=0;TMR1H=0b11111100;TMR1L=0b00010111;rfbit=rfbit+1;//发送指针加一send( );}}//////////////////////////////////////////send( ){if(rfgobit==0){switch(rfbit){case 1 :RC5=0;break;case 6 :RC5=1;break;case 7 :RC5=0;rfgobit=1;//制发送完标制rfbit=0;break;default :break;}}if(rfgobit==1){zbit=dispcount[i]&0b00000001;switch(rfbit){case 1:RC5=1;break;case 2 :if(zbit==0){RC5=0;rfbit=0;rf( );}break;case 3 :if(zbit==1){RC5=0;rfbit=0;rf( );}break;default :break;}}}//////////////////////////////////////////////rf( ){k=k+1;if(k==8){i=i+1;k=0;if(i==6){i=1;rfgobit=0;TMR1H=0;TMR1L=0;RC5=1;dispcount[1]=0xaa;dispcount[2]=0xbb;dispcount[3]=0xcc;dispcount[4]=0xdd;dispcount[5]=0xee;}return;}dispcount[i]=dispcount[i]>>1;}//////////////////////////////////////main( ){di( );TRISC=0b11011111;TRISA=0b111111;TRISB=0b11111111;i=1;k=0;TMR1H=0b11111100;TMR1L=0b00010111;T1CON=1;TMR1IE=1;RC5=1;PEIE=1;ei( );dispcount[1]=0xaa;dispcount[2]=0xbb;dispcount[3]=0xcc;dispcount[4]=0xdd;dispcount[5]=0xee;while( 1 ){;}}

这两个程序只是一个演示例程

在实际运用中可变通的把这种发送与接受用于两机之间的通讯(好处是移植性好,抗干扰好且一发一收只要两根线或一根线)另外如要产生载波(38KHZ)的话可用其输出口去调制38KHZ发生源(比如555电路,PWM)来得到,或干脆用软件来实现(不过难度较大;不如用带38KHZ的单片机来做)

提醒:《关于用PIC单片机红外遥控的编码与解码的问题》最后刷新时间 2024-03-14 01:10:21,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《关于用PIC单片机红外遥控的编码与解码的问题》该内容的真实性请自行鉴别。