单片机红外通信

基于单片机的红外通信
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下是一个红外遥控小车的程序

#include <reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit P10=P1^0;
sbit P11=P1^1;
sbit IN1 = P1^2;
sbit IN2 = P1^3;
sbit IN3 = P1^6;
sbit IN4 = P1^7;
sbit EN1 = P1^4;
sbit EN2 = P1^5;
uchar IRtime,t;    //储存检测红外高低电平持续时间
uchar IRcord[4]; //储存解码后的4个字节数据
uchar IRdata[33];//包含起始码在内的33位数据
bit IRpro_ok;    //解码后4个字节数据接收完成标志位
bit IRok;        //33位数据接收完成标志位
uchar zz=0,yz=0;
void delay(uint z)
{
 uint i,j;
 for(i=z;i>0;i--)
 for(j=114;j>0;j--);
}
void init()
{
    TMOD|=0x02;//设置定时器0工作模式2,8位自动重装
    TL0=TH0=0;//初始化定时器0寄存器,定时器0溢出一次时间为256个机器周期
    EA=1;
    ET0=1;
    TR0=1;
    
    IT0=1;//设置外部中断0跳边沿触发方式
    EX0=1;
    }
```c
void time0() interrupt 1
{
    IRtime++;//277.76us
 t++;
  if(t==200)
  t=EN1=EN2=0;
     if(zz==t)
  EN1 = 1;
  if(yz==t)
  EN2 = 1;
}
//外部中断0存入33次脉宽
void int0() interrupt 0
{
    static uchar i;//静态变量用于存入33次数据计数
    static bit startflag;//开始储存脉宽标志位
    if(startflag)//标志被置1则开始存储33次脉冲宽度,一位一位存
    {
        if((IRtime<53)&&(IRtime>=32))i=0;//判断引导码,如果是引导码则从起始码开始存
        IRdata[i]=IRtime;//以T0溢出的次数来计算脉宽把这个时间存放在数组
        IRtime=0;//计数清零
        i++;//计数脉宽存入次数自加
        if(i==33)//i=33就表示已经存入了33次脉宽
        {
            IRok=1;//脉宽检查完成
            i=0;//把脉宽计数清零准备下次存入
        }
    }
    else
    {
        IRtime=0;//定时器0计数清零,因为初始化时就启动了,即使没有收到红外数据也再加
        startflag=1;//开始处理标志位置1
    }
}
//把提取的33次脉宽解码 NEC协议
void IRcordpro()
{
    uchar i;//计数处理4个字节
    uchar j;//用于处理1个字节的8位数据
    uchar k;//用于计数处理33次脉宽
    k=1;//从第一位脉宽开始处理,丢掉起始码
    for(i=0;i<4;i++)
    {
        for(j=0;j<8;j++)
        {
            if(IRdata[k]>5)    IRcord[i]|=0x80;//如果脉宽大于数据0标准的1125us那么就判断为数据1
            
            if(j<7)    IRcord[i]>>=1;//只能移动7次,防止最后一位移出
            k++;//处理下一次脉宽
        }
    }
    IRpro_ok=1;//解码完成
}
void run()
{
   if(IRcord[2]==0x1c)
   {
    IN1 = 0;
    IN2 = 1;
    IN3 = 1;
    IN4 = 0;
    delay(100);
       IN1 = 0;
          IN2 = 0;
           IN3 = 0;
            IN4 = 0;
            }
            if(IRcord[2]==0x08)
   {
    P11=0;
    IN1 = 0;
    IN2 = 0;
    IN3 = 1;
    IN4 = 0;
    delay(100);
    delay(100);
    P11=1;
    IN1 = 0;
      IN2 = 0;
    IN3 = 0;
    IN4 = 0;
   }
   if(IRcord[2]==0x5a)
   {
       P10=0;
    IN1 = 0;
    IN2 = 1;
    IN3 = 0;
    IN4 = 0;
    delay(100);
     P10=1;
    IN1 = 0;
    IN2 = 0;
    IN3 = 0;
    IN4 = 0;
   }
    if(IRcord[2]==0x52)
   {
       P10=0;
    IN1 = 1;
    IN2 = 0;
    IN3 = 0;
    IN4 = 1;
    delay(200);
     P10=1;
    IN1 = 0;
    IN2 = 0;
    IN3 = 0;
    IN4 = 0;
   }
}
void main()
{
    init();
    while(1)
    {
        if(IRok)//判断33次脉宽是否提取完成
        {
            IRcordpro();//根据脉宽解码出4个字节数据
            IRok=0;//清零脉宽检查完成标志位等待下一次脉宽检查
            if(IRpro_ok)//判断是否解码完成
            {
       run();
                IRpro_ok=0;//清零解码完成标志位
            }
        }
    }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值