搜索
bottom↓
回复: 4

51单片机之红外通信

[复制链接]

出0入0汤圆

发表于 2011-11-23 19:00:58 | 显示全部楼层 |阅读模式
#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('\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[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;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-2-7 13:03:46 | 显示全部楼层
mark....

出0入0汤圆

发表于 2012-2-7 14:05:29 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-3-26 16:47:14 | 显示全部楼层
学习了...

出0入0汤圆

发表于 2013-9-4 10:35:58 | 显示全部楼层
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 14:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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