找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1326|回复: 0
打印 上一主题 下一主题
收起左侧

单片机红外实验

[复制链接]
跳转到指定楼层
楼主
ID:263302 发表于 2017-12-18 19:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实验报告
一、 实验名称
红外接收试验
二、 实验原理以及要求
1.红外线原理
红外线是波长在760nm~1mm之间的非可见光。红外通信装置由红外发射管和红外接受管组成,红外发射管是能发射出红外线的发光二极管,发射强度随着电流的增大而增大;红外接受管是一个具有红外光敏感特征的PN节的光敏二极管,只对红外线有反应,产生光电流。
产生下降沿,进入外部中断0的中断函数,延时一下之后检IO口是否还是低电平,是就等待9ms的低电平过去。等待完9ms低电平过去,再去等待4.5ms的高电平过去。接着开始接收传送的4组数据先等待560us的低电平过去检测高电平的持续时间,如果超过1.12ms那么是高电平(高电平的的持续时间为1.69ms,低电平的持续时间为565us。)检测接收到的数据和数据的反码进行比较,是否等到的数据是一样的。
2.信号调制原理
基带信号:从信号源发出没有经过调制的原始信号,特点是频率较低,信号频率从0开始,频谱较宽。
调制:就是用待传送信号去控制某个高频信号的幅度、相位、频率等参量变化的过程,即用一个信号去装载另一个信号。
红外遥控器使用38KB的载波对原始信号进行解调,原理如下
file:///C:\Users\WANGYA~1\AppData\Local\Temp\ksohtml\wpsF2FC.tmp.jpg
调制后产生一定频段的高低电平,但红外接收头接受到的信号和调制后的信号电平相反。
3.NEC协议
红外遥控由多种协议控制,这里介绍最主要,应用最广的NEC协议。NEC数据格式:引导码、用户码、用户码(或者用户码反码)、按键键码和键码反码,最后一个停止位。
引导码:9ms的载波+4.5ms的空闲。
比特值“0”560us的载波+560us的空闲。
比特值“1”560us的载波+1.68ms的空闲。
file:///C:\Users\WANGYA~1\AppData\Local\Temp\ksohtml\wpsF2FD.tmp.jpg
协议规定低位首先发送。一串信息首先发送9msAGC(自动增益控制)的高脉冲,接着发送4.5ms的起始低电平,接下来是发送四个字节的地址码和命令码。如果你一直按那个按键,一串信息也只能发送一次,一直按着,发送的则是以110ms为周期的重复码。
4.实验原理图
file:///C:\Users\WANGYA~1\AppData\Local\Temp\ksohtml\wpsF30E.tmp.jpg
三、实验步骤:
1本实验通过单片机控制红外接受设备接受红外发送设备发送的信号,并通过数码管的显示判断是否接受到信号。实验接线为JP10J12,J6A,B,C分别接P2.2P2.3P2.4
2)在完成实验代码后将代码烧进单片机内。通过红外遥控检验实验是否正确。
实验代码
#include<reg51.h>
#define GPIO_DIG P0
sbit LSA  = P2^2;
sbit LSB  = P2^3;
sbit LSC  = P2^4;
sbit IRIN = P3^2;                           //红外接收器位声明
unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char DisplayData[8];               //用来存放要显示的8位数的值
unsigned char IrValue[6];                   //用来存放读取到的红外值
unsigned char Time;
void DigDisplay();                          //动态显示函数
void IrInit();
void DelayMs(unsigned int);
void main()
{
    IrInit();
    while(1)
    {
        IrValue[4]=IrValue[2]>>4;           //高位
        IrValue[5]=IrValue[2]&0x0f;         //低位
        DisplayData[0] = 0x00;
        DisplayData[1] = DIG_CODE[IrValue[4]];
        DisplayData[2] = DIG_CODE[IrValue[5]];
        DisplayData[3] = 0x76;   
        DisplayData[4] = 0x00;
        DisplayData[5] = DIG_CODE[IrValue[4]];
        DisplayData[6] = DIG_CODE[IrValue[5]];
        DisplayData[7] = 0x76;
        DigDisplay();   
    }
}
void DelayMs(unsigned int x)                 //0.14ms误差 0us
{
    unsigned char i;
    while(x--)
    {
        for (i = 0; i<13; i++);
    }
}
void IrInit()
{
    IT0=1;                                   //下降沿触发
    EX0=1;                                   //打开中断0允许
    EA=1;                                    //打开总中断
    IRIN=1;                                  //初始化端口
}
void ReadIr() interrupt 0
{
    unsigned char j,k;
    unsigned int err;
    Time=0;                  
    DelayMs(70);
    if(IRIN==0)                             //确认是否真的接收到正确的信号
    {   
        err=1000;                          //1000*10us=10ms,超过说明接收到错误的信号
        while((IRIN==0)&&(err>0))            //等待前面9ms的低电平过去        
        {           
            DelayMs(1);
            err--;
        }
        if(IRIN==1)                          //如果正确等到9ms低电平
        {
            err=500;
            while((IRIN==1)&&(err>0))        //等待4.5ms的起始高电平过去
            {
                DelayMs(1);
                err--;
            }
            for(k=0;k<4;k++)                 //共有4组数据
            {               
                for(j=0;j<8;j++)             //接收一组数据
                {
                    err=60;     
                    while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
                    {
                        DelayMs(1);
                        err--;
                    }
                    err=500;
                    while((IRIN==1)&&(err>0))//计算高电平的时间长度。
                    {
                        DelayMs(1);          //0.14ms
                        Time++;
                        err--;
                        if(Time>30)
                        {
                            EX0=1;
                            return;
                        }
                    }
                    IrValue[k]>>=1;          //k表示第几组数据
                    if(Time>=8)              //如果高电平出现大于565us,那么是1
                    {
                        IrValue[k]|=0x80;
                    }
                    Time=0;                  //用完时间要重新赋值                           
                }
            }
        }
       if(IrValue[2]!=~IrValue[3])          //反码取反后与原码相同则说明信号接受正确
        {
            return;
        }
    }           
}
void DigDisplay()
{
    unsigned char i;
    unsigned int j;
    for(i=0;i<8;i++)
    {
        switch(i)                           //位选,选择点亮的数码管
        {
            case(0):
                LSA=0;LSB=0;LSC=0; break;   //显示第0
            case(1):
                LSA=1;LSB=0;LSC=0; break;   //显示第1
            case(2):
                LSA=0;LSB=1;LSC=0; break;   //显示第2
            case(3):
                LSA=1;LSB=1;LSC=0; break;   //显示第3
            case(4):
                LSA=0;LSB=0;LSC=1; break;   //显示第4
            case(5):
                LSA=1;LSB=0;LSC=1; break;   //显示第5
            case(6):
                LSA=0;LSB=1;LSC=1; break;   //显示第6
            case(7):
                LSA=1;LSB=1;LSC=1; break;   //显示第7
        }
        GPIO_DIG=DisplayData;            //发送段码
        j=10;                               //扫描间隔时间设定
        while(j--);
        GPIO_DIG=0x00;                      //消隐
    }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表