登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 红外通信

[复制链接]
发表于 2021-2-24 15:51:10 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机红外通信
学习安排: 单片机红外接收模块学习
开始时间: 2021-02-24
结束时间: 2021-02-24
     在编写红外接收程序时,遵循了NEC协议,而其表示数据时,依靠高低电平空闲的不同表示0和1,需要获取接受高低电平时间进行判断。需要用到两个定时器,开发板上红外接收用到了中断0,则需要用定时器1数码管扫描.
**************main.c**************
#include <reg52.h>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

unsigned char code LedChar[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,     
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};                //数码管显示字符转换表
unsigned char LedBuff[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

u8 T1RH = 0;
u8 T1RL = 0;

extern bit irflag;
extern u8 ircode[4];
extern void InitInfrared();
void ConfigTimer0(u16 ms);

void main()
{
        EA = 1;
        InitInfrared();
        ConfigTimer0(1);
        PT1 = 1;                                 //配置T0中断为高优先级,启用本行消除接收时的闪烁
       
        while(1)
        {
                if(irflag)
                {
                        irflag = 0;
                        LedBuff[5] = LedChar[ircode[0] >> 4];
                        LedBuff[4] = LedChar[ircode[0] & 0x0f];
                        LedBuff[1] = LedChar[ircode[2] >> 4];
                        LedBuff[0] = LedChar[ircode[2] & 0x0f];
                }
        }
}
/*配置T0*/
void ConfigTimer0(u16 ms)
{
        unsigned long temp;
        temp = 11059200 / 12;
        temp = (temp * ms) / 1000;
        temp = 65536 - temp;
        temp = temp + 13;
        T1RH = (u8)(temp >> 8);
        T1RL = (u8)temp;
        TMOD &= 0x0f;
        TMOD |= 0x10;
        TH1 = T1RH;
        TL1 = T1RL;
        ET1 = 1;
        TR1 = 1;
}

void LedScan()
{
        static u8 i = 0;
        P0 = 0x00;
        switch(i)
        {
                case 0SC = 0;LSB = 0;LSA = 0;i++0 = LedBuff[0];break;
                case 1SC = 0;LSB = 0;LSA = 1;i++0 = LedBuff[1];break;
                case 2SC = 0;LSB = 1;LSA = 0;i++0 = LedBuff[2];break;
                case 3SC = 0;LSB = 1;LSA = 1;i++0 = LedBuff[3];break;
                case 4SC = 1;LSB = 0;LSA = 0;i++0 = LedBuff[4];break;
                case 5SC = 1;LSB = 0;LSA = 1;i++0 = LedBuff[5];break;
                case 6SC = 1;LSB = 1;LSA = 0;i++0 = LedBuff[6];break;
                case 7SC = 1;LSB = 1;LSA = 1;i = 00 = LedBuff[7];break;
                default :break;
        }       
}
void interruptTimer0()interrupt 3
{
        TH1 = T1RH;
        TL1 = T1RL;
        LedScan();
}


************Infrared.c************


#include <reg52.h>


typedef unsigned char u8;
typedef unsigned int u16;


sbit IR_INPUT = P3^2;
bit irflag = 0;                                            //红外接收标志
unsigned char ircode[4];                        //红外接收代码缓冲区


void InitInfrared()
{
        IR_INPUT = 1;
        TMOD &= 0xf0;
        TMOD |= 0x01;
        TR0 = 0;                                                //禁止T1定时和中断
        ET0 = 0;
        IT0 = 1;                                            //设置INT1负边沿触发
        EX0 = 1;                                                 //使能
}
/*获取高电平持续时间*/
u16 GetHighTime()
{
        TH0 = 0;                                                   //清零计数值
        TL0 = 0;
        TR0 = 1;
        while(IR_INPUT)                                           //引脚为1时循环等待检测,变零时结束本次循环
        {
                if(TH0 >= 0x40)                                   //18ms时强制退出避免信号异常
                {
                        break;
                }
        }
        TR0 = 0;


        return (TH0 * 256 + TL0);
}


u16  GetLowTime()
{
        TH0 = 0;
        TL0 = 0;
        TR0 = 1;
        while(!IR_INPUT)
        {
                if(TH0 >= 0x40)
                {
                        break;
                }
        }
        TR0 = 0;
        return(TH0 * 256 + TL0);
}       
/*INT1中断服务函数,执行红外接收及其解码*/
void EXINT1_ISR()interrupt 0
{
        u8 i,j;
        u8 byt;
        u16 time;


        //接受并判断引导码的9ms低电平
        time = GetLowTime();
        if((time < 7833) || (time > 8775))
        {
                IE0 = 0;
                return;
        }
        //接受并判断引导码的4.5ms高电平
        time = GetHighTime();
        if((time < 3686) || (time > 4608))
        {
                IE0 = 0;
                return;
        }
        //循环并判定后续4字节
        for(i = 0;i < 4;i++)
        {
                for(j = 0;j < 8;j++)
                {
                        //接受判定bit的560us的低电平
                        time = GetLowTime();
                        if((time < 313)||(time > 718))
                        {
                                IE0 = 0;
                                return;
                        }
                        //接受每bit高电平时间,并判定该bit的值
                        time = GetHighTime();
                        if((time > 313) && (time < 718))
                        {
                                byt >>= 1;
                        }
                        else if((time > 1345) && (time < 1751))
                        {
                                byt >>= 1;
                                byt |= 0x80;
                        }
                        else
                        {
                                IE0 = 0;
                                return;
                        }


                }
                ircode = byt;
        }
        irflag = 1;
        IE0 = 0;
}                                           

好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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