找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC89C51红外遥控实验学习

[复制链接]
跳转到指定楼层
楼主
ID:127247 发表于 2016-6-19 12:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
抱着对电子的爱好,用朋友闲置的51实验板学习一下,初学者,不足之处多多见谅!

/*******************************************************************************
* 实验名         : 数码管显示红外线值实验
* 使用的IO         : 红外使用P3.2 数码管使用P0,P2.2,P2.3,P2.4
* 实验效果       : 数码管显示出读取到的红外线的值
*    注意                     :
*******************************************************************************/
#include<reg51.h>


#define GPIO_DIG P0

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char code DIG_CODE[18]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X71,0x76};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码
unsigned char DisplayData[8];

sbit IRIN=P3^2;

unsigned char IrValue[6];
unsigned char Time;
void IrInit();
void DelayMs(unsigned int );
void DigDisplay();
/*******************************************************************************
* 函数名         : main
* 函数功能           : 主函数
* 输入           : 无
* 输出              : 无
*******************************************************************************/

void main()
{
    IrInit();   
    while(1)
    {
        DisplayData[0] = DIG_CODE[17];
        switch(IrValue[2]){
            case 0x16:  
                DisplayData[1] = DIG_CODE[0];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x0c:  
                DisplayData[1] = DIG_CODE[1];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x18:  
                DisplayData[1] = DIG_CODE[2];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x5e:  
                DisplayData[1] = DIG_CODE[3];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x08:  
                DisplayData[1] = DIG_CODE[4];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x1c:  
                DisplayData[1] = DIG_CODE[5];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x5a:  
                DisplayData[1] = DIG_CODE[6];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x42:  
                DisplayData[1] = DIG_CODE[7];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x52:  
                DisplayData[1] = DIG_CODE[8];
                DisplayData[2] = DIG_CODE[0];
                break;
            case 0x4a:  
                DisplayData[1] = DIG_CODE[9];
                DisplayData[2] = DIG_CODE[0];
                break;
            default:
                DisplayData[1] = DIG_CODE[IrValue[2]%16];
                DisplayData[2] = DIG_CODE[IrValue[2]/16];

        }
   
   


        DigDisplay();
    }
}                                    
/*******************************************************************************
* 函数名         : DelayMs()
* 函数功能           : 延时
* 输入           : x
* 输出              : 无
*******************************************************************************/

void DelayMs(unsigned int x)   //0.14ms误差 0us
{
unsigned char i;
  while(x--)
{
  for (i = 0; i<13; i++)
{}
}
}


/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能           : 使用数码管显示
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
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[i];//发送段码
        j=10;                         //扫描间隔时间设定
        while(j--);   
        GPIO_DIG=0x00;//消隐
    }
}
/*******************************************************************************
* 函数名         : IrInit()
* 函数功能           : 初始化红外线接收
* 输入           : 无
* 输出              : 无
*******************************************************************************/

void IrInit()
{
    IT0=1;//下降沿触发
    EX0=1;//打开中断0允许
    EA=1;    //打开总中断

    IRIN=1;//初始化端口
}
/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能           : 读取红外数值的中断函数
* 输入           : 无
* 输出              : 无
*******************************************************************************/

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低电平过去
//                    while (!IRIN)
                    {
                        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;
        }
    }            
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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