51单片机之红外通信

2020-01-27 11:21发布

#include<reg52.h>
#include"MyFun.h"

#define uint unsigned int               
#define uchar unsigned char
#define Baud  0xfd                  //9600

//======================变量定义====================
uchar buf_dat[9]={0};
uchar IRstart,IRtime,Receiveok,bitcount;
uchar IRdata[33];      
uchar byIRdata[4];

//======================函数声明==================
void IRinit();          //初始化定时器0和外部中断0
void IRprocess();                                        //红外处理,由中断时间间隔的不同来判断接受的为1还是为0,解码
void UartSendByte(uchar dat);           //串口发送函数
void UartPutStr(uchar *str);          //串口发送字符串

void main()
{
        IRinit();

        while(1)
        {
                 IRprocess();                                                //红外处理,由中断时间间隔的不同来判断接受的为1还是为0,解码
                 UartPutStr(buf_dat);                           //串口发送函数
                 UartSendByte(' ');           //回车
                 UartSendByte(' ');           //换行
                 delayms(1000);          

        }               
}

void IRinit()          //初始化定时器0和外部中断0
{
        TMOD=0x22;                //定时器0为工作方式2,定时器1为工作方式2
        TH0=0x00;                //每中断一次0.256MS
        TL0=0x00;
        TH1=Baud;                //9600
        TL1=Baud;

        ET0=1;
        TR0=1;

        TR1=1;
        SCON=0X50;             //10位异步收发,波特率可变,启动串口。
        ES=1;

        EX0=1;
        IT0=1;                   //外部中断负跳变沿触发

        EA=1;                //开总中断
}                                                                                 

void Uart()  interrupt 4    //串口中断服务程序
{
        uchar dat;
        dat=SBUF;
        if(RI)              //等待串口接受完毕
        {
                if(dat=='s')
                {
                        RI=0;
                        UartPutStr("准备好了!");          //串口发送字符串
                }       
        }                   
}

void Timer0()  interrupt 1
{
        IRtime++;       
}

void Exter0()  interrupt 0
{
        if(IRstart)                                  //IRstart的初值为0,开始进入中断不执行,计数器清0,等第二次进入中断时就能知道引导时间
        {
                if(IRtime>43)                 //如果检测前有波形变化,即bitcount发生变化则不要紧,可在接下来清0,检测完引导码开始接受地址码
                {
                        bitcount=0;       
                }         
                IRdata[bitcount]=IRtime;        //保存位与位之间的时间,即两次中断的定时器中断次数
                IRtime=0;                                        //IRtime清0
                bitcount++;               
                if(bitcount==33)                //说明32位已全部接受完毕
                {
//                        bitcount=0;                   //????
                        Receiveok=1;           //设置接受完毕的标志

                }

        }
        else
        {
                IRstart=1;
                IRtime=0;
        }       
}


void IRprocess()                                        //红外处理,由中断时间间隔的不同来判断接受的为1还是为0,解码
{
        uchar k=1,i,j,dat=0;
        if(Receiveok==1)                           //如果接受完毕,则开始解码
        {
                for(i=0;i<4;i++)
                {
                                for(j=0;j<8;j++)
                                {
                                        dat=dat>>1;                           //7次,右移,因为数据是总地位开始发送的
                                        if(IRdata[k]>6)                   //8次
                                        {
                                                dat=dat | 0x80;
                                        }
                                        k++;                       
                                }
                        byIRdata=dat;                                        //每收到的8位则保存
                }
                k=1;                                                                        //跳过IRdata[0](引导码)
                IRstart=0;
                Receiveok=0;
        }

        buf_dat[0]=byIRdata[0]/16;
                buf_dat[0]>=10?(buf_dat[0]+=55):(buf_dat[0]+=0x30);
        buf_dat[1]=byIRdata[0]%16;
                buf_dat[1]>=10?(buf_dat[1]+=55):(buf_dat[1]+=0x30);
        buf_dat[2]=byIRdata[1]/16;
                buf_dat[2]>=10?(buf_dat[2]+=55):(buf_dat[2]+=0x30);
        buf_dat[3]=byIRdata[1]%16;
                buf_dat[3]>=10?(buf_dat[3]+=55):(buf_dat[3]+=0x30);
        buf_dat[4]=byIRdata[2]/16;
                buf_dat[4]>=10?(buf_dat[4]+=55):(buf_dat[4]+=0x30);
        buf_dat[5]=byIRdata[2]%16;
                buf_dat[5]>=10?(buf_dat[5]+=55):(buf_dat[5]+=0x30);
    buf_dat[6]=byIRdata[3]/16;
                buf_dat[6]>=10?(buf_dat[6]+=55):(buf_dat[6]+=0x30);
        buf_dat[7]=byIRdata[3]%16;
                buf_dat[7]>=10?(buf_dat[7]+=55):(buf_dat[7]+=0x30);
}

void UartSendByte(uchar dat)           //串口发送函数
{
        SBUF=dat;
        while(!TI);              //等待串口发送完毕
        TI=0;                   
}

void UartPutStr(uchar *str)          //串口发送字符串
{
        uchar i=0;
        while(str)
        {
                UartSendByte(str);           //串口发送函数
                i++;       
        }
}




#include<reg52.h>
#include"myfun.h"

#define OpenT0()                 {ET0=1;TR0=1;EA=1;}        //开定时器0
#define CloseT0()                 {ET0=0;TR0=0;EA=0;}        //关定时器0

#define TIMER1        9
#define TIMER2  30

sbit ir = P1^0;       //红外发射
sbit test = P0^0;
          
uchar code ir_dat[4]={0x00,0xff,0x01,0x02};

void Init()
{
        ir=1;

        TMOD=0X01;                 //定时器0工作方式1
        TH0=0XFF;                 //13US中断1次
        TL0=0XF3;

        EA=1;       
}

void SendByte(uchar dat)           //发送一个字节
{
        uchar i,x=0;
        for(i=0;i<8;i++)  
        {
                dat>>=1;
                x=CY;
                if(x)
                {
                        OpenT0();                
                        delay_50us(TIMER1);                //延时约0.56ms
                        CloseT0();
                        ir=1;
                        delay_50us(TIMER2);                //延时约1.68ms
                }
                else
                {
                        OpenT0();                
                        delay_50us(TIMER1);                //延时约0.56ms
                        CloseT0();
                        ir=1;
                        delay_50us(TIMER1);       
                }
        }       
}

void IRPutStr()                                  //发送一次数据
{
        uchar i=0;
        OpenT0();           //开定时器0
        delay_50us(180);          //延时约9MS
        CloseT0();                //关定时器0
        ir=1;                        //关红外
        delay_50us(95);         //延时约4.5MS

        for(i=0;i<4;i++)
        {
                SendByte(ir_dat);
        }       
                       
        OpenT0();                
        delay_50us(TIMER1);                //延时约0.56ms
        CloseT0();
        ir=1;               
}

void main(void)
{

        Init();
        test = 1;
        while(1)
        {
         //        IRPutStr();
                test = ~test;
                delay_50us(1);  //做成按键时可以不要
        }
                       
}

void timer0() interrupt 1          //定时器0中断服务程序
{
        TH0=0XFF;                 //13US中断1次
        TL0=0XF3;
        ir=~ir;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。