51单片机IrLink红外的使用
- 元器件
- 原理图部分
- 代码
- 单片机1发送main.c
- 单片机2接受main.c
- 工程文件
元器件
元器件 | 名称 |
---|---|
51单片机 | AT89C51 |
红外收发 | IRLINK |
按键 | BUTTON |
发光二极管 | LED-RED |
时钟激励源 | DCLOCK |
与门 | 74LS08 |
示波器 |
原理图部分
关于IRLINK的使用:
在Proteus上就是一个红外的发射接受一体的一个模块,另外在该模块红外接受上有一个解调的功能。如下图,1区域就是红外的发射区域,2区域就是红外的接受区域,3区域就是红外接受后进行解调的区域。
然后关于载波的频率,在IRLINK是可以选择对载波频率的要求的,双击元件。默认是40KHz。
这里频率采用的是Proteus激励源然后与单片机发出的信号经过们与门调制出来。下图是示波器观察信号的结果。
关于的发射的协议采用的网上说索尼的SonySIRC协议。本次实验采用类似的,以2.4ms的高电平加600us低电平为起始信号,600us为间隔,600us为高电平表示0,1200us为间隔,600us为高电平表示1,数据帧为:帧头为0x80,数据帧为0x40,帧尾为0x20,如果接受到0x40,且帧头帧尾不错误就点灯。本次irlink载波频率为20kHz。
代码
本次实验由单片机通过按键控制IrLink红外来进行通信点灯。
单片机1发送main.c
代码如下:
#include "reg51.h"
#include "intrins.h"
typedef unsigned char uint_8;
typedef unsigned int uint_16;
sbit TX=P2^0;
sbit KEY=P1^0;
//600us
#define High_Low_Wide_H 0XFD
#define High_Low_Wide_L 0xA8
//600us
#define Low_Gap_H 0XFD
#define Low_Gap_L 0xA8
//1200us
#define High_Gap_H 0xFB
#define High_Gap_L 0x50
//2400us
#define Start_High_H 0xF6
#define Start_High_L 0xA0
void scan_Key(void); //按键扫描函数
void Ir_Send_Bit(uint_16 us_h,uint_16 us_l,bit Status);
void Ir_Send_Data(uint_8 Data);
void TimerInit(void);
void main(void)
{
bit key=0;
TimerInit();TX = 0;
while(1)
{
scan_Key();
}
}
//按键扫描函数
void scan_Key(void)
{
if(KEY==0)
{
TX = 0;
Ir_Send_Bit(Start_High_H,Start_High_L,1); //起始信号2.4ms
Ir_Send_Bit(Low_Gap_H,Low_Gap_L,0); //间隔输出0.6ms
Ir_Send_Data(0x80);//起始帧0x80
Ir_Send_Data(0x40); //数据
Ir_Send_Data(0x20);//终止帧
}
}
//一位发送
void Ir_Send_Bit(uint_16 us_h,uint_16 us_l,bit Status)
{
TH0 = us_h; //设置定时初值
TL0 = us_l; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
if(Status==1)
{
TX = 1;
while(TF0==0);
}
else if(Status==0)
{
TX = 0;
while(TF0==0);
}
TF0 = 0;
TR0 = 0; //关闭定时器
TX = 0;
}
//八位发送 从最低位往高位发送
void Ir_Send_Data(uint_8 Data)
{
uint_8 i=0;
for(i=0;i<8;i++)
{
if(Data&0x01) //高电平
{
Ir_Send_Bit(High_Low_Wide_H,High_Low_Wide_L,1); //脉宽输出
Ir_Send_Bit(High_Gap_H,High_Gap_L,0); //间隔输出
}
else
{
Ir_Send_Bit(High_Low_Wide_H,High_Low_Wide_L,1); //脉宽输出
Ir_Send_Bit(Low_Gap_H,Low_Gap_L,0); //间隔输出
}
Data >>=1;
}
}
void TimerInit(void) //12微秒@12.000MHz
{
TMOD=0X01; //设置定时器模式
}
单片机2接受main.c
#include "reg51.h"
#include "intrins.h"
typedef unsigned char uint_8;
typedef unsigned int uint_16;
sbit RX=P2^1;
sbit LED=P1^0;
void Ir_Receive(void);
uint_8 Ir_Receive_8Bit(void);
void TimerInit(void);
uint_8 All_Data[3]={0,0,0};
uint_16 time=0;
void main(void)
{
TimerInit();
while(1)
{
if((All_Data[1]==0x40)&&(All_Data[0]==0x80)&&(All_Data[2]==0x20))LED=1;
else LED=0;
Ir_Receive();
}
}
//接受数据
void Ir_Receive(void)
{
uint_8 i=0;
if(RX==0)
{
time=0;
TR0 = 1; //定时器0开始计时
while(RX==0);
time=TH0*256+TL0; //计算时间
TR0 = 0;
if((time>2000)&&(time<3000))
{
TH0=0;TL0=0;
time=0;
TR0 = 1; //定时器0开始计时
while(RX==1);
time=TH0*256+TL0; //计算时间
TR0 = 0;
if((time>300)&&(time<1000))
{
time=0;
while(i<3)
{
All_Data[i]=Ir_Receive_8Bit();
i++;
}
}
}
}
}
//8位接受
uint_8 Ir_Receive_8Bit(void)
{
uint_8 Data=0;
uint_8 i=0;
while(i<8)
{
if(RX==1)
{
TH0=0;TL0=0;
time=0;
TR0=1;
while(RX==1);
time=TH0*256+TL0; //计算时间
TR0 = 0;
TF0=0;
if((time>300)&&(time<1000)) Data>>=1;
else if(time>1000) Data |=0x80;
i+=1;
}
}
return Data;
}
void TimerInit(void) //12微秒@12.000MHz
{
TMOD=0X01; //设置定时器模式
TH0=TL0=0;
TR0 = 0;
}
运行效果如图,led被正常点亮:
工程文件
工程文件