历史上的今天
返回首页

历史上的今天

今天是:2025年02月19日(星期三)

正在发生

2020年02月19日 | 关于用PIC单片机红外遥控的编码与解码的问题

2020-02-19 来源:eefocus

简介:一般常用的红外遥控器编码规则都差不多,基本上都同6221原理一样

接收时:


如果用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同时移位;我个人认为不太好,因为只要差一位没接收到,整个接收到的都是误码且浪费时间)


2在谈发送


原理是接收的逆过程


例程如下(用来发6221;分频比为256)


;///////////////////////////////////////////////////////////////////////////////////////////////

READDIGT:

MOVF SENDLOOP,0

ADDWF PC,1

GOTO SENDC4

GOTO SENDC3

GOTO SENDC2

GOTO SENDC1

GOTO SENDC0

;///////////////////////////////////

SENDC0:

MOVF C4COUNT,0;;读要发的数据(假设要发5个字)

RETURN

SENDC1:

MOVF C3COUNT,0

RETURN

SENDC2:

MOVF C2COUNT,0

RETURN

SENDC3:

MOVF C1COUNT,0

RETURN

SENDC4:

MOVF C0COUNT,0

RETURN

;///////////////////////////////////

SENDBIT:

CLRF TIME

BCF PORTB,1

SENDBIT1:

CLRWDT

MOVLW .35

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDBIT1

CLRF TIME

BSF PORTB,1

SENDBIT2:

CLRWDT

MOVLW .18

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDBIT2

CLRF SENDLOOP ;码头数据发送


//////////////////////////////////////////////

SENDBIT3:

CLRWDT

BCF INTCON,7

CALL READDIGT

MOVWF SENDCOUNT

BSF INTCON,7

CALL SENDDIGT

INCF SENDLOOP,1

MOVLW .5

SUBWF SENDLOOP,0

BTFSS STATUS,2

GOTO SENDBIT3

CLRF TIME

BCF PORTB,1

SENDDIGT5:

CLRWDT

MOVLW .2;;加发一个结束位

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDDIGT5

BSF PORTB,1

BSF STARTBIT

RETURN

;/////////////////////////////////////////////////////////////////////////////////////////

SENDDIGT:;;实现0和1的发送

MOVLW .8

MOVWF LOOPSENDCOUNT

SENDDIGTG

BTFSS SENDCOUNT,7

GOTO ZERSEND

CLRF TIME

SENDDIGT1:

CLRWDT

BCF PORTB,1

MOVLW .2

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDDIGT1

CLRF TIME

SENDDIGT2:

CLRWDT

BSF PORTB,1

MOVLW .6

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDDIGT2

GOTO SENDOVER

ZERSEND:

CLRF TIME

SENDDIGT3:

CLRWDT

BCF PORTB,1

MOVLW .2

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDDIGT3

CLRF TIME

SENDDIGT4:

CLRWDT

BSF PORTB,1

MOVLW .2

SUBWF TIME,0

BTFSS STATUS,2

GOTO SENDDIGT4

SENDOVER:

RLF SENDCOUNT,1

DECFSZ LOOPSENDCOUNT

GOTO SENDDIGTGO

RETURN


相应的C代码如下:(C5口是发送口)


#i nclude

#i nclude

#i nclude

unsigned char dispcount[5];//要发送的码值

unsigned char i,k,data,rfbit,zbit,rfgobit;

#pragma interrupt_level 1

interrupt 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的单片机来做)

推荐阅读

史海拾趣

ADTech公司的发展小趣事

AdTech公司深知人才是企业发展的核心动力。因此,公司一直致力于培养和引进高素质的人才,打造了一支具有丰富经验和专业技能的团队。公司通过提供良好的工作环境和福利待遇,吸引了一批优秀的研发、市场和管理人才。同时,公司还注重员工的培训和成长,为员工的职业发展提供了广阔的空间。这些措施使得公司的团队更加稳定和高效,为公司的持续发展提供了有力保障。

硕颉(BITEK)公司的发展小趣事

硕颉科技高度重视知识产权保护,积极申请专利。截至2015年10月,公司已取得台湾63件、美国52件、中国大陆24件、日本4件及韩国10件等共153件专利。这些专利的取得,不仅为公司的技术创新提供了法律保障,也进一步巩固了公司在行业内的竞争地位。

Data Device Corporation公司的发展小趣事

随着电子技术的不断发展,DDC也积极投入研发,寻求技术突破。在数据接口技术方面,DDC不断推陈出新,研发出了一系列高性能、高可靠性的产品。同时,DDC还拓展了业务领域,将产品应用于更广泛的领域,如地面保障、高速串行通信等。这些举措使得DDC的产品线更加丰富,市场竞争力也得到了进一步提升。

American Electric公司的发展小趣事

在发展过程中,American Electric公司也面临过各种挑战和危机。例如,XXXX年,公司遭遇了一次严重的自然灾害,导致部分电力设施受损。然而,公司迅速启动了应急响应机制,组织抢修队伍进行抢修,并在最短时间内恢复了供电。此外,在面对政策调整、市场竞争等挑战时,公司也能够灵活应对,通过调整战略、优化管理等方式保持稳健发展。

Daburn公司的发展小趣事

随着公司规模的不断扩大,Daburn开始积极拓展国际市场。公司通过参加国际展览、与国外企业建立合作关系等方式,将产品推向全球市场。同时,Daburn还注重与当地企业的合作,共同开发符合当地市场需求的产品。这种市场拓展策略让Daburn在国际舞台上获得了更多的机会和挑战。

EETools公司的发展小趣事

面对快速变化的市场环境和不断涌现的新技术,EETools始终保持开放和创新的姿态。公司不仅持续关注行业动态和技术趋势,还积极探索新的业务领域和增长点。例如,EETools正在研发基于人工智能和物联网技术的嵌入式开发工具,以满足未来市场的需求。同时,公司还计划进一步拓展海外市场,提升品牌在国际市场的竞争力。这些举措将为EETools的未来发展奠定坚实的基础。

问答坊 | AI 解惑

SHOW MY CAR(飞思卡尔智能车大赛)

本帖最后由 paulhyde 于 2014-9-15 08:59 编辑 前一段时间,参加了飞思卡尔智能车大赛,华北赛区一等奖,也来SHOW一下  …

查看全部问答>

epw9

674654394友情链接QQ号码  密码9982499824 http://www.admin5.com/站长网 用户名:njhuisi 密码:9982499824 邮件:chinagoogleweb@163.com http://bbs.admin5.com交易论坛 用户名:njhuisi 密码:9982499824 邮件:nanjingmaste ...…

查看全部问答>

MCU解密全攻略

知道怎么解密才能更好的加密!!!…

查看全部问答>

关于上拉电阻的问题

请问高手为什么有的24c02电路图上有上拉电阻,而有的没有啊??还有就是什么时候需要在外电路中接入上拉电阻啊。具体怎么选阻值啊?? 这两个图为什么一个不接上拉电阻,一个接上拉电阻啊??? SCL接P1.1 SDA接P1.2 SDA接P2.0 SCL接P2 ...…

查看全部问答>

请教vxworks启动问题

我是vxworks的初学者,我想从优盘引导并通过网络下载vxworks,但在引导过程中出现了以下问题: 0x2906d0 (tBoot): dosFsLib.c : ERROR reading the device boot sector 0x2906d0 (tBoot): dosFsLib.c : media not formatted or not present 0x29 ...…

查看全部问答>

如何在PC机上显示WinCE平台的显示屏的画面啊?

我的环境是S3C2440+WinCE5.0,现在想从PC机上观看液晶屏上的内容怎么办啊,因为要写论文,想截个图什么的,谢谢大家了。。。…

查看全部问答>

IImage::Draw的问题

调用IImage :: Draw时, 如果传递了第3个参数, 老是出错, 怎么回事? HRESULT Draw(   HDC                  hdc,   const RECT*      &nb ...…

查看全部问答>

我考研方向是:高速数据采集,这个方向是干什么的?工作的月薪高吗?

大家好!     我是电子商务专业的本科生,我对编程特别感兴趣,以前从事过PHP、ASP等网络编程。通过以前的学习我觉得编程可以让我变得更喜欢学工科,让我觉得学程序非常有意思。我们考的研究生专业课有:数据库系统概论、数据结构、C语 ...…

查看全部问答>

请问Windows CE操作系统哪里有下载啊!!

不知道网上到底有没有Windows CE下载,如果有的话麻烦告诉一下下载地址. 谢谢!!!,在线等哦,,,,,,,,,,,,,,,,,,…

查看全部问答>

sd卡驱动中的模块之间调用的问题

mmcsd.h #ifndef MMCSD_MMCSD_H #define MMCSD_MMCSD_H struct mmc_slot {          int (*transfer1b)(struct mmc_slot *slot, int rd, u_long from,             &nbs ...…

查看全部问答>