红外线发射和接收
红外线发射与接收基础实验这个实验是红外发射和接收的一个基础实验。该实验讲了如何用红外线发射管发射38K红外线信号,然后让38K的红外线一体化接收头接收所发送的红外线信号。用示波器来查看红外发射端和接收端的电平信号。实验目的是让接收头收到一个10毫秒的低电平,接着10毫秒高电平,最后依次是8个脉宽为5毫秒周期的高低电平。
(1)实验电路图
电路图如下图21-3所示。左边①部分是红外线信号发射部分,LED1是红外线发射管。通过单片机的P1.0端口去控制NPN三极管的基极。当P1.0端口为高电平时,三极管的发射极和集电极导通,红外线发射管就会导通,发射红外信号。三极管集电极和发射极的电压为0.3V,D1压降为1.4V,那么通过D1的电流为:I=U/R=(5-0.3-1.4)/150=0.022A。
图21-3中的②部分是红外线芯片的接收部分。红外线接收部分用的是红外线一体化接收头PC838作的接收电路。PC838的1端是红外线信号接收和处理后,得出的红外线数据输出端和单片机的P3.2端口相连。2端是接的电源地。3端接的是电源正极,我们从+5V串联了一个330欧姆的电阻到VCC,并且在VCC端并联了0.1UF和22UF的电容,这样可以降低电源的干扰。
①红外线发射电路 ②红外线接收电路
图21-3 红外线发射和接收电路图
(2)实验原理分析:
红外线发射电路中,我们让单片机的P1.0端口输出一个38K的占空比为1/2的方波信号。1秒等于1000000微秒,那么方波的高低电平的时间t=1000000/38000/2≈13微秒。如果要用单片机来产生13微秒的高低电平信号,最好是用单片机的定时器来处理,定时器的方式2适合用于这样比较精确的脉冲信号发生器。
方式2计算初值X:
X=256-t*fosc/12(或6)
12和6是分频,我们这里选择12;t为所设计时时间单位为26微秒;fosc为晶振单位为11.0592MHz。
X=256-0.000013*11059200/12≈244
我们已经算出了要得到13微秒的方波,我们给定时器方式2的初始为244(F4H),下面我们写要满足实验目的的代码就很简单了。
(3)实验程序代码
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uintunsigned int
sbit IR_TX = P1^0; //红外信号发射端
sbit IR_OUT = P3^2; //红外信号接收端
/*********************************
函数:Delay_1ms()
参数:t
返回:无
功能:延时子程序,延时时间为 1ms * del。
使用晶振是11.0592M。
**********************************/
void Delay_1ms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
{
for(j=0;j<=100;j++)
{
_nop_();
}
}
}
/*********************************
函数:Time0Init
参数:无
返回:无
功能:定时器的初始化,11.0592MZ晶振,
定时器0设置为方式2,定时溢出时间为13微秒
**********************************/
void Time0Init()
{
TMOD = 0x02; //设置定时器0为方式2
TH0= 0xF4; //设置定时时间
TL0= 0xF4;
ET0 = 0; //打开定时器0中断
EA = 1; //打开总中断
}
/*********************************
函数:Time0Int
参数:无
返回:无
功能:定时器0中断,让IR_TX变量高低电平转换
**********************************/
void Time0Int() interrupt 1
{
IR_TX = !IR_TX;
}
/*********************************
函数:Main
参数:无
返回:无
功能:主函数
**********************************/
void Main()
{
uchar i;
Time0Init(); //初始化定时器0
TR0 = 1; //打开定时器0
Delay_1ms(10);
TR0 = 0; //关闭定时器0
Delay_1ms(10);
for(i=0;i<8;i++)
{
TR0 = 1; //打开定时器0
Delay_1ms(5);
TR0 = 0; //关闭定时器0
Delay_1ms(5);
}
while(1)
{
}
}
(4)实验现象
单片机通过定时器0的方式2产生了一个38K的方波信号,从P1.0端口输出。通过图21-4所示,方波的脉宽约为13微秒。
图21-4 红外线发射控制端P1.0端口发送的38K红外线信号
图21-5是红外线发射管所发射的红外线信号波形。在定时器0运行期间,P1.0口会一直产生38K的方波信号。在定时器1停止期间,P1.0端口则不会产生38K方波信号。在前面的程序代码中,我们可以看到我们让定时器工作10毫秒,然后停10毫秒,最后再依次每隔5毫秒让定时器工作和停止。但是我们可以看到在前面我们让定时器工作10毫秒的地方,实际工作时间在15毫秒左右。造成时间不准的原因是定时器在工作的时候,每个13微秒进行一次中断,主函数的那个延时函数在工作的过程中被定时器打算了。这里,我们不对延时不准的情况进行深究,我们这里主要来分析红外线的工作原理。
图21-5 红外线发射管发射的红外线信号
图21-6是在单片机的P3.3端口测得的经过红外线一体化接收头处理后的红外线信号图。图21-6和图21-5进行对比,可以得出这样的结果:当红外线发射管发出38K的红外线信号时,红外线一体化接收头为低电平;而红外线发射管没有发送红外线信号时,红外线一体化接收头为高电平。
图21-6 经过红外线一体化接收头处理后的红外信号
经过这一节的学习可以让大家对红外线的发射和接收基础有一定的了解。在这一节讲了38K的红外线信号该如何产生,红外线信号要如何进行发射和接收等等。另外,红外线信号的发送是必要要有间隔的,每一组红外线信号最好要间隔100毫秒以上再发送一次,否则红外线一体化接收头会接受不了红外线信号。 求大侠指导 谢谢!下载学习,学习。 每一组红外发射信号最好隔100ms发射一次
那么每一次发射红外信号的时间最大值是多少呢 有没有试过 number007cool 发表于 2013-6-18 19:44 static/image/common/back.gif
每一组红外发射信号最好隔100ms发射一次
这个早都做完了,需要的话我可以给你所有的文档. 没有仔细看过这个时间。 谢谢楼主, 资料能不能共享下, 我准备用STM32做个红外接收, 正在找资料. andy520 发表于 2013-6-19 00:19 static/image/common/back.gif
这个早都做完了,需要的话我可以给你所有的文档.
好啊哪谢谢你了
number007cool@163.com 学习了 最终版的红外发射与接收 number007cool 发表于 2013-6-19 10:41 static/image/common/back.gif
好啊哪谢谢你了
不好意思,最经没时间来看。刚刚发给你了。有什么问题给我发邮件. andy520 发表于 2013-6-25 09:07 static/image/common/back.gif
不好意思,最经没时间来看。刚刚发给你了。有什么问题给我发邮件.
多谢你了 我回去看看 正在学习红外遥控的东西,感谢楼主了。。 楼主分享的好东西,讲的简单易懂 qq511153186 发表于 2013-6-28 09:59 static/image/common/back.gif
楼主分享的好东西,讲的简单易懂
呵呵,有吗?
这个是我实际做过的东西,有亲身体会的。 很好的资料,下载学习。 学习啦谢谢LZ共享 这个不难,时间算的准就可以了 #ifndef ______IRSEND_H_______
#define ______IRSEND_H_______
#include "Typedef.h"
#define IRSENDPORT P0
#define TIMER9000US (65536-8294) //9mS
#define TIMER4500US (65536-4147) //4.5mS
#define TIMER1650US (65536-1520) //1.65mS
#define TIMER0560US (65536-516) //0.56mS
#define TIMER40000US (65536-36863) //40mS
#define TIMER56000US (65536-51609) //56mS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Function :
* Description : 函数功能、性能描述
* Calls : 被本函数调用的函数清单
* Called By : 调用本函数的函数清单
* Table accessed: 被访问的表(数据库操作用)
* Tabled Updated: 被修改的表(数据库操作用)
* Input : 输入参数、取值说明与关系
* Output : 输出参数、类型说明
* Return : 函数返回值说明
* Others : (Screen sequence)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void IrUserTimerConfiguration(void)
{
TMOD |= 0x01;
IRSENDPORT = 0XFF;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Function :
* Description : 函数功能、性能描述
* Calls : 被本函数调用的函数清单
* Called By : 调用本函数的函数清单
* Table accessed: 被访问的表(数据库操作用)
* Tabled Updated: 被修改的表(数据库操作用)
* Input : 输入参数、取值说明与关系
* Output : 输出参数、类型说明
* Return : 函数返回值说明
* Others : (Screen sequence)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void IRWriteOneBit(BIT send_Mode,unsigned int TimerInitValue,unsigned char PassageNumer)
{
unsigned char NumBer = 1 << PassageNumer;
unsigned char onlyOnePassageorAllChang = 20;
if (PassageNumer < 8 && PassageNumer >= 0) onlyOnePassageorAllChang = 0; //单独通道发送
else if (255 == PassageNumer) onlyOnePassageorAllChang = 1; //所有通道都发送
TH0 = TimerInitValue >> 8;
TL0 = TimerInitValue;
TF0 = 0; //清TF0
TR0 = 1; //启动定时器0
if (send_Mode == 0) while(!TF0);
else while(1)
{
if (0 == onlyOnePassageorAllChang) IRSENDPORT &= ~NumBer; //置位相应的通道
else if (1 == onlyOnePassageorAllChang) IRSENDPORT = 0xff;
if (TF0) break; if (TF0) break;
if (0 == onlyOnePassageorAllChang) IRSENDPORT |= NumBer; //CLR相应通道
else if (1 == onlyOnePassageorAllChang) IRSENDPORT = 0x00;
if (TF0) break; if (TF0) break; if (TF0) break; if (TF0) break; if (TF0) break;
if (TF0) break; if (TF0) break; if (TF0) break; if (TF0) break; if (TF0) break;
}
TR0 = 0;
if (0 == onlyOnePassageorAllChang) IRSENDPORT |=NumBer;
else if (1 == onlyOnePassageorAllChang) IRSENDPORT = 0xff;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Function :
* Description : 函数功能、性能描述
* Calls : 被本函数调用的函数清单
* Called By : 调用本函数的函数清单
* Table accessed: 被访问的表(数据库操作用)
* Tabled Updated: 被修改的表(数据库操作用)
* Input : 输入参数、取值说明与关系
* Output : 输出参数、类型说明
* Return : 函数返回值说明
* Others : (Screen sequence)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void IRWriteOneChar(unsigned char ircode,unsigned char PassageNumer)
{
unsigned char I = 0x00;
for (I = 0;I < 8;I++)
{
IRWriteOneBit(1,TIMER0560US,PassageNumer);
if (ircode & 0x01)
{
IRWriteOneBit(0,TIMER1650US,PassageNumer);
}
else
{
IRWriteOneBit(0,TIMER0560US,PassageNumer);
}
ircode >>= 1;
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Function :
* Description : 函数功能、性能描述
* Calls : 被本函数调用的函数清单
* Called By : 调用本函数的函数清单
* Table accessed: 被访问的表(数据库操作用)
* Tabled Updated: 被修改的表(数据库操作用)
* Input : 输入参数、取值说明与关系
* Output : 输出参数、类型说明
* Return : 函数返回值说明
* Others : (Screen sequence)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void IrPortWriteIrcode(unsigned char *Ir_Point,unsigned char PassageNumer)
{
IRWriteOneBit(1,TIMER9000US,PassageNumer);
IRWriteOneBit(0,TIMER4500US,PassageNumer);
IRWriteOneChar(*(Ir_Point+0),PassageNumer);
IRWriteOneChar(*(Ir_Point+1),PassageNumer);
IRWriteOneChar(*(Ir_Point+2),PassageNumer);
IRWriteOneChar(*(Ir_Point+3),PassageNumer);
IRWriteOneBit(1,TIMER0560US ,PassageNumer);
IRWriteOneBit(0,TIMER40000US,PassageNumer);
}
#endif
哈哈,这个是参照论坛的,比较好理解! HeP028 发表于 2013-7-4 23:25 static/image/common/back.gif
哈哈,这个是参照论坛的,比较好理解!
没发现,主函数都没找到?? 保存 mark! 之前搞了一下 不太难 WM_CH 发表于 2013-7-17 21:42 static/image/common/back.gif
之前搞了一下 不太难
搞懂了肯定不难。 采用中断接收方式一类做红外接收,如果你采用4位数码显示(或做别人工作)时,出现程序跑慢显示器出现闪烁等现象。最好采用定时扫描的方式来做,这样MCU的得利用率也高此。只是提个见意,要求不高的方式,楼主这样做也是可以的。红外接收和发射我07年做过,当时也是有闪烁的现象。 忘记买红外线接收了 红外接收不经过三极管放大,单片机能不能识别? 手机mark一下。 yy12651 发表于 2013-7-18 21:06 static/image/common/back.gif
红外接收不经过三极管放大,单片机能不能识别?
如果你购买的接收头是一体化接收头,内部集成有信号放大。不然就要自己放大。我当时买的是一体化的。一体化接收头接收的信号可以直接给单片机,单片机可以识别。 非常支持楼主,这般慷慨开班!{:smile:} 资料收下了 红外的 用了又忘了 mark 路过路过了顺便看看 非常有用。
多谢了 涨姿势了 很好很强大 迟早能用到的 非常支持楼主,这般慷慨开班!
页:
[1]