xiaoyan911 发表于 2011-11-23 19:00:58

51单片机之红外通信

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

#define uint unsigned int               
#define uchar unsigned char
#define Baud0xfd                  //9600

//======================变量定义====================
uchar buf_dat={0};
uchar IRstart,IRtime,Receiveok,bitcount;
uchar IRdata;      
uchar byIRdata;

//======================函数声明==================
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('\r');           //回车
               UartSendByte('\n');           //换行
               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=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>6)                   //8次
                                        {
                                                dat=dat | 0x80;
                                        }
                                        k++;                       
                                }
                        byIRdata=dat;                                        //每收到的8位则保存
                }
                k=1;                                                                        //跳过IRdata(引导码)
                IRstart=0;
                Receiveok=0;
        }

        buf_dat=byIRdata/16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata%16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata/16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata%16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata/16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata%16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
    buf_dat=byIRdata/16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=0x30);
        buf_dat=byIRdata%16;
                buf_dat>=10?(buf_dat+=55):(buf_dat+=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 TIMER230

sbit ir = P1^0;       //红外发射
sbit test = P0^0;
          
uchar code ir_dat={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;
}

madswan 发表于 2012-2-7 13:03:46

mark....

kang732816702 发表于 2012-2-7 14:05:29

MARK

dongwei123 发表于 2012-3-26 16:47:14

学习了...

yanmylbh 发表于 2013-9-4 10:35:58

{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}
页: [1]
查看完整版本: 51单片机之红外通信