红外接收程序讲解Word格式.docx
《红外接收程序讲解Word格式.docx》由会员分享,可在线阅读,更多相关《红外接收程序讲解Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
对于红外线遥控对于很多电子爱好者来讲,都感觉到非常神奇,看不到,摸不着,但能实现无线遥控,其实控制的关键就是我们要用单片机芯片来识别红外线遥控器发出红外光信号,即我们通常所说的解码。
单片机得知发过来的是什么信号,然后再做出相应的判断与控制,如我们按电视机遥控器的频道按钮,则单片机会控制更换电视频道,如按的是遥控器音量键,则单片机会控制增减音量。
解码的关键是如何识别“0”和“1”!
!
从位的定义我们可以发现“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同!
,“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。
如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。
根据码的格式,应该等待9ms的起始码和4.5ms的结果码完成后才能读码。
5、实例代码:
注意一下几点:
1.从上面“红外接收头与单片机连接原理图”来看,红外接收头的型号脚是与51的int0相连,所以需要使用INT0(外部中断0).
2.由于解码过程中涉及到延时,为精确起见,我们选择使用定期时1来计时。
实例代码:
[C++]
viewplaincopy
1.#include
2.#include
3.
4.//
函数原型
5.void
SystemInit(void);
6.void
Delay_840us(void);
7.void
Delay_2400us(void);
8.void
LedDisp();
9.unsigned
char
GetCode(void);
//获得码
10.void
delay(unsigned
loop);
11.
12.//
位变量
13.sbit
IRIN
=
P3^2;
14.sbit
BEEP
P1^6;
15.sbit
swch
P1^7;
16.
17.//
变量
18.unsigned
KeyValue;
//机器码
19.unsigned
MaValue;
//键值码;
20.unsigned
disbuf[4];
//数码管显示缓冲
21.unsigned
scan[4]={0x04,0x08,0x10,0x20};
//p2位选择
22.unsigned
code
table[16]
//共陰碼
23.{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71};
24.
25./**
26.
*
延时
27.
*/
28.void
loop)
29.{
30.
unsigned
i;
31.
for(i=0;
i>
8);
32.
TR1=1;
33.
while(!
TF1);
34.
TF1=0;
35.
TR1=0;
36.}
37.
38./**
39.
延时9ms
40.
41.void
Delay_9000us(void)
42.{
43.
TL1
153.6;
44.
TH1
223.6;
45.
TR1
1;
46.
47.
TF1
0;
48.
49.}
50.
51./**
52.
延时4.5ms
53.
54.void
Delay_4500us(void)
55.{
56.
239.8;
57.
204.8;
58.
59.
60.
61.
62.}
63.
64./**
65.
系统初始化
66.
67.void
SystemInit(void)
68.{
69.
70.
IT0
//INT0负跳变触发
71.
TMOD
0x10;
//定时器1工作在方式1
72.
EA
73.
EX0
74.}
75.
76./**
77.
读码
78.
79.unsigned
GetCode()
80.{
81.
n;
82.
83.
static
temp
84.
85.
for(
n
<
8;
n++
)
86.
{
87.
IRIN);
//
等待高电平,开始解码
88.
89.
Delay_840us();
延时0.84ms
90.
91.
if(IRIN)
若仍然为高电平,则为1,否则为0
92.
93.
(0x80|(temp>
>
1));
1
94.
while(IRIN);
//等待跳变成低电平
95.
}
96.
else
97.
temp=(0x00|(temp>
0
98.
99.
100.
101.
return
temp;
102.}
103.
104./**
105.
数码管显示
106.
107.void
LedDisp()
108.{
109.
110.
i<
4;
i++)
111.
112.
P0=table[disbuf[i]];
113.
P2
scan[i];
114.
delay(50);
115.
P0=0x00;
116.
117.}
118.
119.void
main(void)
120.{
121.
SystemInit();
122.
123.
while
(1)
124.
125.
//以下是查表显示
126.
disbuf[0]=(((KeyValue&
0xf0)>
4)&
0x0f);
127.
disbuf[1]=KeyValue&
0x0f;
128.
disbuf[2]=(((MaValue&
129.
disbuf[3]=MaValue&
130.
131.
132.}
133.
134.
135.void
interr_ir(void)
interrupt
136.{
137.
/**
138.
用户码和机器码
139.
140.
addrl,addrh,num1,num2;
141.
142.
//先关闭外部中断0
143.
144.
Delay_9000us();
检测9ms开始码
145.
146.
if
(IRIN)
检测是否为干扰信号
147.
重新开启外部中断0
148.
;
退出解码
149.
150.
151.
等待跳为高电平
152.
153.
Delay_4500us();
检测4.5ms结果码
154.
155.
156.
157.
158.
159.
160.
161.
addrl=GetCode();
用户编码高位
162.
addrh=GetCode();
用户编码低位
163.
num1=GetCode();
机器码
164.
num2=GetCode();
机器码反码
165.
166.
//校验是否为错码
167.
if(num1!
=~num2)
168.
169.
KeyValue=14;
170.
EA=1;
171.
return;
172.
173.
174.
KeyValue=num2;
175.
MaValue=addrh;
176.
177.
178.}
代码分析(只分析关键部位):
1.系统初始化SystemInit()
系统初始化时,我们设置IRIN为高电平,同时把IT0设置成1,即下降沿(负跳变)触发中断。
这是用于接收波形的引导码是从低电平开始的(如上面接收波形所示)。
这样,当按下按键时,红外接收到信号,IRIN则发生从预先设置的高电平跳为低电平,从而产生中断。
2.解码--中断程序
interr_ir(void)
首先,第一步把EX0关中断,这步至关重要,因为一个接收波形许多的下降沿,这样会产生干扰中断。
接下来,使用定期时0延时9ms,跳过开始码。
注意,延时后,需要检测一下干扰信号。
下一步,while(!
等待4.5ms高电平的到来,再延时4.5ms,跳过结果。
引导码过后,
开始读码,执行GetCode():
32位数据码,分4次读取,所以执行4次GetCode(),读取一个字节数据过程如下:
1.unsigned
2.{
4.
5.
6.
7.
8.
9.
10.
12.
13.
14.
15.
17.
18.
19.
20.
21.
22.
23.
24.}
1.从上述位定义看,位0和位1都是0.56ms的低电平过后,高电平开始延时。
所以,读码的第一步while(!
是等待这个0.56ms的低电平之后的高电平。
2.从高定平到后开始延时0.84ms
3.判断0.84ms的波形高电平还是低电平。
若仍然是高电平证明,该位为“1”,否则为“0”。
到这里读码结束。
3.校验
由于32位数据码中,后两个字节是键数据码和健数据反码。
可以通过这两个字节数来实行校验。
即,把前一个字节去反判读是否等于后一字节。