红外通信[新版]
红外通信
/*********************广东工业大学电子科技协会
*******************************
作者: 洪
时间: 2011/4/10
说明: 红外接收实验,将接收到数据通过数码管显示出来,本次实验为延时方式
***********************************************************
********************/
#include
#define uchar unsigned char
#define uint unsigned int
sbit IR_spring=P3^3; //红外接收头所连IO口
uchar IR_data[4],disp[8]; //IR_data[4]接收到的红外数据存放处,disp[8]处理后可供数码管显示的数据存放处
uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//0~F代码
uint temp; //用于记录延时时间
//延时函数
void delay(uchar a) {
uchar i;
while(a--)
for(i=0;i<120;i++);
}
//初始化函数
void init()
{
TMOD=0x01; //定时器0工作方式1,用于计算高/低电平持续时间
IT1=1; //下降沿有效
EX1=1; //开外部中断
EA=1; //开总中断
}
//获取低电平时间函数
uint Low_Level_time()
{
TH0=0;
TL0=0; //定时器初值
TR0=1; //启动定时器
while(!IR_spring&&(TH0&0x80)==0); //定时器没有溢出且IR_spring为低电平时在此等待电平变化
TR0=0; //关闭定时器
return (TH0*256+TL0); //将含有时间信息的计数器数值返回
}
//获取高电平时间函数
uint High_Level_time()
{
TH0=0;
TL0=0;
TR0=1;
while(IR_spring&&(TH0&0x80)==0); //定时器没有溢
出且IR_spring为高电平时在此等待电平变化
TR0=0;
return (TH0*256+TL0); }
//数据处理函数
void date_dispose() {
disp[0]=IR_data[3]%16;
disp[1]=IR_data[3]/16;
disp[2]=IR_data[2]%16;
disp[3]=IR_data[2]/16;
disp[4]=IR_data[1]%16;
disp[5]=IR_data[1]/16;
disp[6]=IR_data[0]%16;
disp[7]=IR_data[0]/16;
}
//显示子函数
void display()
{
uchar i;
for(i=0;i<8;i++)
{
P0=table[disp[i]];
P1=i;
delay(1);
}
}
//主函数
void main()
{
init();
while(1)
{
date_dispose();
display();
}
}
//外部中断服务函数
void int1_isr() interrupt 2
{
uchar i,j;
temp=Low_Level_time();
if ((temp < 7833) || (temp > 8755)) //引导脉冲低电平
8500~9500us,不在这个范围的无效
return;
temp=High_Level_time();
if ((temp < 3686) || (temp > 4608)) //引导脉冲高电平
4000~5000us,不在这个范围的无效
return;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
IR_data[j]>>=1;
temp = Low_Level_time();
if ((temp < 184) || (temp > 737)) //数据低电平时间在200~800us之间,不在这个范围的无效
return;
temp =High_Level_time();
if ((temp < 184) || (temp > 1843)) //数据高电平时间在200~2000us之间,不在这个范围的无效
return;
if (temp > 1032) //数据为“0”时高电平时间为565us,为“1”时高电平时间为1690us,为了提高准确率,这里取两者平均值1132us
IR_data[j]|=0x80; //高电平时间大于1132us接收的数据为“1”
}
}
}
/**************************一下程序为定时器方式***************************************/
/*********************广东工业大学电子科技协会
*******************************
作者: 洪
时间: 2011/4/10
说明: 红外接收实验,将接收到的数据用数码管显示出来,本次实验采用定时器方式
***********************************************************
*******************/
#include
#define uchar unsigned char
#define uint unsigned int
sbit IR_spring=P3^3; //红外接收头所连IO口
uchar IR_Start,IR_Num,Sign_Data_Ok; uchar disp[8]; //IR_data[4]接收到的红外数据存放处,disp[8]处理后可供数码管显示的数据存放处 uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//0~F代码
unsigned long IR_data; //用于记录延时时间
//延时函数
void delay(uchar a) {
uchar i;
while(a--)
for(i=0;i<120;i++);
}
//初始化函数
void init()
{
TMOD=0x01; //定时器0工作方式1,用于计算高/低电平持续时间
IT1=1; //下降沿有效
EX1=1; //开外部中断
EA=1; //开总中断
}
//获取低电平时间函数
//数据处理函数
void date_dispose()
{
uint IR_data_H16,IR_data_L16;
if(Sign_Data_Ok==1) //为了保证显示的数据的有效性,等到数据转换完毕标志置位后才进行数据转换
{
IR_data_H16=IR_data>>16; //分离数据低16位
IR_data_L16=(IR_data<<16)>>16; //分离数据高16位
disp[0]=(IR_data_L16&0x00ff)%16;
disp[1]=(IR_data_L16&0x00ff)/16;
disp[2]=(IR_data_L16>>8)%16;
disp[3]=IR_data_L16>>12;
disp[4]=(IR_data_H16&0x00ff)%16;
disp[5]=(IR_data_H16&0x00ff)/16;
disp[6]=(IR_data_H16>>8)%16;
disp[7]=IR_data_H16>>12; //以上语句进行数据转换
Sign_Data_Ok=0; //转换结束后将数据接收完成标志清零
}
}
//显示子函数
void display() {
uchar i;
for(i=0;i<8;i++)
{
P0=table[disp[i]];
P1=i;
delay(1);
}
}
//主函数
void main()
{
init();
while(1)
{
date_dispose();
display();
}
}
//外部中断服务函数 void int1_isr() interrupt 2 {
uchar IR_Time_H,IR_Time_L;
uint IR_Time;
TR0=0;
IR_Time_H=TH0;
IR_Time_L=TL0; //读计数器的值
IR_Time=IR_Time_H*256+IR_Time_L; //数据转换
TH0=0;
TL0=0;
TR0=1;
if(IR_Time>10000) //如果时间间隔大于11ms,说明接收到启动码
{
IR_Start=1; //启动标志置一
IR_Num=0; //清零IR_Num,保证数据的准确性,该语句可以保证不会因为接收到部分数据而
} //导致数据不准确,原理是启动后必须接收到全部数据,数据才有效
if(IR_Time<900) //数据时间间隔大余1.05ms,故不在这个范围则说明不是数据,则返回
return;
if((IR_Start==1)&&IR_Time<2600) //如果已经收到启动代码,且数据在有效范围内
{
IR_data<<=1; //因为先发地址高位,所以要向右移动
if(IR_Time>1600) //如果数据间隔大于数据0和数据1中间数值,则认为收到数据1
{
IR_data|=1;
}
IR_Num++; //收到一位后IR_Num
加1
if(IR_Num>31) //如果IR_Num>31,即等于32(为保证可靠,用大于)时,说明数据已经收完
{
Sign_Data_Ok=1; //数据收完后接收结束标志置位
IR_Start=0; //启动标志清零
TR0=0; //收到全部数据后关闭定时器,可节能,也避免出错
}
}
}
本文档为【红外通信[新版]】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。