|
如何用PIC做红外线遥控接收?
============================
先用20106之类的片子解调后,你用示波器挂在20106的输出端就可以查看遥控波形。
=============================
NEC遥控接收第一次正常,以后就不行了(附遥控子程序)请指正。
不才是PIC领域的新手,最近写了一个关于NEC遥控接收解码的测试程序,下面是此程序的遥控解码部分但是它只能第一次正确判断出接收码,以后就不行了请高手指点
我知道遥控码的连发情况,但我已经设置了32位接收码的计数器,应该不会有问题的
我判断0(1.125ms)和1(2.25ms) 由于我用的是C57,只能通过查询方式来确定.通过高电平的时间(以下程序中延时0.9MS)不同来决定0或1的。
;NEC格式遥控码的接收与解码子程序
;本程序中采用PORTA 0口接收红外遥控,地址码为00H,高位FFH,数据码为00H,反码为FFH,接收到的依次存放到 25H ADD8L, 26H ADD8H,DAT8 27H ,
28H DAT8F寄存器中。
;第一次接收到此信号即关机.
;============ GOOD ========================
REMOTE_RECEIVER
CLRF 20H ;20H的第0位遥控接收正确与否标志位
BTFSC PORTA,0 ;RA0=0接收到信号
GOTO BACK ;判断9MS低电平和4.5MS高电平。
;----5ms delay----------------
MOVLW 06H ;防止抖动,延时5ms
MOVWF 30H
LOOP4 MOVLW 0FFH
MOVWF 31H
LOOP5 DECFSZ 31H,1
GOTO LOOP5
DECFSZ 30H,1
GOTO LOOP4
;-----------------------------
BTFSC PORTA,0
GOTO BACK ;遥控接收无效。
LOOP0 BTFSS PORTA,0 ;遥控接收,等待高电平出现,约9-5ms
GOTO LOOP0
;------------测一个脉冲接收-----
STEP MOVLW D'32' ;设置32位接收码的计数器.
MOVWF BIT32
STEP1 BTFSC PORTA,0 ;等待4.5ms
GOTO STEP1
STEP2 BTFSS PORTA,0
GOTO STEP2
;-----------------------------
MOVLW D'180' ;延时0.9ms,测试高电平的脉宽。
MOVWF 29H
BCF STATUS,C
WAIT NOP
NOP
DECFSZ 29H,1
GOTO WAIT
;-----------------------------
BTFSS PORTA,0 ;PA0 TO C
GOTO C0
GOTO C1
C0 BCF STATUS,C
GOTO STEP3
C1 BSF STATUS,C
STEP3 MOVLW D'4'
MOVWF 2AH
MOVLW 28H ;28H是DAT8F的地址
MOVWF FSR ;利用FSR进行间接寻址。
STEP4 RLF INDF,1
DECF FSR,1
DECFSZ 2AH,1
GOTO STEP4
DECFSZ BIT32,1
GOTO STEP1
MOVF ADD8L,0
XORLW 00H
BTFSS STATUS,Z
GOTO BACK ;低8位地址码不对,返回
MOVF ADD8H,0
XORLW 0FFH
BTFSS STATUS,Z
GOTO BACK
MOVF DAT8,0 ;8位数据码不对,返回
XORLW 00H
BTFSS STATUS,Z
GOTO BACK
MOVF DAT8F,0 ;8位数据反码不对,返回
XORLW 0FFH
BTFSS STATUS,Z
GOTO BACK
GOTO REM_OK ;代码接收正确
BACK BSF 20H,0
REM_OK RETURN
回复 先清32位数据再接收.
然后每接收完8位后,RAM要清0
如;**************RAM移位***************************
j1 incf jsp1 ;8位计数寄存器
incf jsp2 ;32位数,计存器.
btfss jsp1,3 ;是否有8位
goto js
clrf jsp1
movf sj,0 ;移8位数到W
movwf ** ;W到DATA
incf f ;RAM地址加1
clrf sj ;注意这里!!!!!!!!!!!!!!!
;*****************************
btfss jsp2,5 ;检测是否接收完32位.
goto js ;否,再检测.
这是6122和6121 IC的接收程序.
发表于:2003-03-04 17:34:51
小宝:很高兴看到你的提示,不过我的程序不是按照每8位接收后经过RAM放入寄存器中,而是每位都经过4次循环移位后直接放入存放数据的寄存器中(参见接收程序中的STEP4),所以不可能按昭你所说的那样清0。
你的程序单独看是没有问题的。我想关键在于发射编码究竟如何?你所谓“第一次可以,以后就不行了”,是不是每次复位后的第一次发射和接受是正常的?如果是这样的,说明还是连发的处理不是很合适。发生连发时,应该将25H-28H清空。否则第二次发射时,25H-28H已经有了部分不完整的数据,造成移位过程中的错误数据,接受失败。
我的意见不一定正确,仅供参考。
NEC遥控接收问题
NEC遥控接收问题出错在位接收上。
我看程序有点问题,主要是在接收位上,应该是每接受8位后才把FSR-1,在回到接受程序上。如此进行4次可以接受32位的数据。
发表于:2003-03-04 20:46:38
并不是位接收问题
我那程序的位接收问题不是先接收8位再保存的,那个4次循环指的是每接收一位后即改变STATUS标志位C,同时4个接收寄存器依次带C位移位,等到接收32位后(即第1位移位32次后恰好保存到了第一个接收寄存器的第7位,第2位移到了第6位)你可以自己演示一下,这样32位正好保存到了4个寄存器中。
可以参见我那段程序的STEP3,STEP4。
很感谢有这么多热心的朋友关心这个问题!
=========================
红外线遥控编码有几种类型
类型不知道,但格式有上千种
我要做个通用型的红外接收器, 就是不管遥控器发送什么码,反正照收不误, 然后按原样把它发送出去, 我想用PIC做,你看要用哪种型号的控制器做较好!
既然是转发你管他格式干什么?
你又不解码,只要检测联接红外管的PIC的I/O口的电压变化就行了,再在另一个脚把他发送出去。送你一个检测红外的小程序。只不过要自己做一点电路。点击浏览该文件
最后一位数据位的宽度如何检测!!
以红外接收器为准,如果没有遥控信号的情况下,接收器的输出端是不是高电平,如果是,最后一位码,0.56ms低电平过后,接着是出现高电平对吧,那高电平的宽度如何确定就不好办了!请教老兄!
红外接收目前用的比较多的有三种方法.
1,查询法,既软件不停地查询是否为低(遥控信号)然后通过精确延时读头码.和
数据0或1码.
2,读到有信号输入时开打开定时计数器,然后通过读定时器的中断次数,来判定头码和0,1的.
3 RB0或RB4-RB7加定时器(或软件延时)利用输入中断的好处是可做实时控制.
如下:
;***发射为6221,把接收到的码值送到ICD的PORTC口显示******
;**************** ***************
org 0000h
nop
goto start
org 0004h
goto serv
;**************************************************
start
bsf status,rp0 ;体1
movlw 0000h
movwf trisc ;C口输出
movlw 0ffh ;B口RB0输入
movwf trisb
movlw B'00000100' ;1:64
movwf option_reg ;TMR0定时器
bcf status,rp0 ;体0
clrf intcon ;10010000
bsf intcon,7 ;开放INT下降沿中断
bsf intcon,4
bcf intcon,1
clrf portc
loop
sleep
nop
goto loop
;*************现场保护********************************
serv
movwf w_temp
swapf status,0
clrf status
movwf status_temp
movf pclath,0
movwf pclath_temp
clrf pclath
;***************遥控处理.******************************
bcf intcon,1
btfsc portb,0 ;检测RB0是否为0.
goto zdhh ;RB0不为0,误中断.反回
call delay8 ;调用8MS延时.头码检测.
btfsc portb,0 ;检测头码
goto zdhh ;不是中断反回
call delay5 ;延时5MS后进行数据检测.
btfss portb,0 ;检测RB0是否为高电平.
goto zdhh ;不是继续检测.
;*********************************************
clrf data1 ;20H
clrf data2 ;21H
clrf data3 ;22H
clrf data4 ;24H
clrf jsp2 ;32位计数器
clrf sj ;接收的数据寄存器
clrf jsp1 ;8位计数器
movlw 0x20 ;20H寄存器送W
movwf fsr ;由W送20H到FSR
jc btfsc portb,0 ;检测RB0是否为低电平.
goto jc ;不是继续检测.
;**************0和1数据检测****************************
js call delay1 ;延时1.3MS
btfsc portb,0 ;检测头码过后是0还是1,
goto s1 ;检测的数据不"1"
;*************0数据处理*****************************
bcf sj,c ;数据是"0"
rrf sj,1 ;0数据右移到SJ寄存器
goto j1
;**************1数据处理.*************************
s1 bsf sj,c
rrf sj,1
ddp btfsc portb,0
goto ddp
;**************RAM移位***************************
j1 incf jsp1 ;8位计数寄存器
incf jsp2 ;32位数,计存器.
btfss jsp1,3 ;是否有8位
goto js
clrf jsp1
movf sj,0 ;移8位数到W
movwf indf ;W到DATA
incf fsr ;RAM地址加1
clrf sj
;*****************************
btfss jsp2,5 ;检测是否接收完32位.
goto js ;否,再检测.
movlw B'10001111' ;送IC高8位码
xorwf data1,0 ;相减(Z:1=结果为0;0=结果不为0)
btfss status,2 ;结果为0则下一步.
goto zdhh ;相减结果不为0中断返回
movlw B'101010101' ;低8位IC码检测
xorwf data2,0
btfss status,2
goto zdhh
;comf data4,0 ;数据反码检测.暂不用.
;subwf data3,0
;btfss status,2
;goto zdhh
movf data3,0 ;送数码到C口
movwf portc
goto zdhh ;接收完32位则中断返回
;****************zdhh中断返回程序*********************
zdhh
movf pclath_temp,0
movwf pclath
swapf status_temp,0 ;交换STATUS与W内容,将体选还原.
movwf status ;将W内容送STATUS寄存器
swapf w_temp,1 ;交换w_temp
swapf w_temp,0 ;交换w_temp与w内容,将w_temp内?
bcf intcon,1
retfie ;中断返回,
;****************8ms*********************************
delay8 bcf intcon,5
bcf intcon,2
movlw D'15'
movwf tmr0
loop1 btfss intcon,2
goto loop1
return
;****************5ms*********************************
delay5 bcf intcon,5
bcf intcon,2
movlw D'120'
movwf tmr0
loop2 btfss intcon,2
goto loop2
return
;****************1.3ms*******************************
delay1 bcf intcon,5
bcf intcon,2
movlw D'240'
movwf tmr0
loop3 btfss intcon,2
goto loop3
return
;*************
end
错码的可能有两种
一个是字头对不好
一个是数据传输有错误 特别是时序错误
后面的可以用软件校验
字头不好确认 最好可以在软件规定上连续多发几个 然后用移位方法判断有多次连续相同子头出现 对齐字头 比如连续出现20个1 0转换后 表示准备发送数据 然后等待1 0 传输结束后 跟着有一个字头 如11110000 这样 后面就可以接数据了
A 我在外面买了一个万能遥控器,他就是用pic16c57c作的,那就说明它是没有中断的,我真搞不懂他是怎么做的,它是没有解码芯片的,请问有谁知道,我现在也在做这个,有谁能提示一下,谢谢。
B 这很容易
上次我用两片PIC16C57C作了一个发射与一个接收的小模块。有效控制,没能出现乱码,但有一缺点就是会受到其它红外线产品的干扰!!
C 红外接受
用外中断,加定时,即可检测出编码,非常准确。我用的是PIC16F72芯片。
D 我使用红外线接受管加两级放大,看红外线的输出波形,用长虹的遥控器当信号源,在示波器上要打到10ms才能看到完整的信号波形,像个稳压后的波形一样的东西,我看了有关方面的书说,红外线信号时调制在38khz的信号上的,那我将示波器打到50ns上为什么看不到波形,这样的话程序不是没有办法编了,望哪位高人帮帮我,谢谢
E 可以用CCP中的input capture(输入捕捉)功能,很好用的,仔细阅读一下input capture有关内容,很容易的
在CCP的引脚上若有事件发生(可设置为上升沿,下降沿或其他方式),TMR1的内容背记录,这样很准确的,即使中断响应较慢也没问题的,这样的功能来做红外遥控最恰当不过!!
F 回复红外定时接收原理
用RB0做中断(FIRST:RISING TRIG,SECOND:FALLING TRIG),同时启动TIMER2定时100US)计数.当下一个中断来临时,由TIMER2有88个数,9MS就检测出来。其余时间,
类推。注意,RBO的中断沿,要根据时序,来改变。据此原理,很容易编出代码。
还有一个地方值得注意 ; 红外信号的衰减很厉害的,所以一定要考虑它的接受范围的选择
其实用那种方法都可以,在接收数据时时间方面留够余量,这样对正确接收数据有好处
关于红外线接收的一点思路
我现在在做电视机红外线接受,发射器,看了一些书,书上说信号被调制在38khz的调制信号上,但我通过一颗红外接收管加两级放大后看红外线波形,示波器要打到10ms档上才能看到完整波形,照书上说的话应该打到50us档上就能看到波形了,而且这个波形像梯形波,请问这是怎么一回是,我用的红外线源就是长虹电视机的遥控器,这样的话我的接收程序怎么写呢?
你不用管他怎么调制的,你只需要用一个接收头就可以了,出来的就是方波,根据两个下降沿来判断信号就行了(空闲状态为高电平),我当初用示波器观察了一天才了解是怎么回事
那如果有人一直按着遥控器,单片机不是会当一个信号并记录下来,而且我用的是pic16c57的片子,没有中断的,两个下降沿的时常如何判断,而且如何确定一个信号已经结束了呢,
如果你没做过红外遥控接受,建议你先用带中断的片子来搞,用57是有一定难度的
看了你写的红外线接收的程序,有点问题
你写的接收程序第二条就用goto转跳到rf1,而在rf1上用了retlw 0这个指令,但这个指令不是要使用call指令返回时才用的吗,如果goto指令用了retlw 0,那返回到哪里去,
这个和遥控器使用的芯片有关,你可以了解一下有关这个遥控器按键的定义,也可用示波器观察。最好你先写一段程序来读码,观察一下按键定义和规律。
红外传输一般分为两种:
1。有载波:就是把基带信号(就是“0”,“1”)调制到38k的载波上去,由红外发光管发射(同发光二极管)出去;
然后在接收端用红外光敏二极管(或三极管)或者红外一体化接收头接收。
用光敏二极管或三极管接收需要用程序或ic(如:cx20106等)解调。然后再对基带信号进行处理。这种方法主要用于载波需要有多种频率的场合。
用一体化接收头的灵敏度比较高,体积相对比较小,内部集成了38k解调、低通滤波和其他一些抗干扰电路。这种接收头使用比较简单,不过据我使用过的情况来看,灵敏度越高抗干扰性能就越差,常常伴有脉冲干扰,用程序还是可以解决的。
基带信号最好使用编码、调整占空比等以加强抗干扰性能。
2。直接用0,1信号发送:在距离比较近(cm级别),环境干扰比较小的情况下使用。
我的想法是直接将遥控器的信号经过两级放大,是三极管放大后输出,但我现在就是不知道,38khz的信号如何记入单片机,我想不用解码芯片
好呀,发射一个9013就够了,假如买不到距离不够而且买不到大功率发射管的话可以把两个发射管串联起来。
为什么要把38k信号输入单片机呢?你用红外光敏三极管接收?成本倒是低了好多。工艺要求就比较高了。