51单片机红外遥控解码

#include <reg52.h>

// 定义红外遥控解析状态机
typedef enum {
  IR_STATE_IDLE,        // 空闲状态
  IR_STATE_START,       // 红外信号开始状态
  IR_STATE_DATA,        // 红外信号数据状态
  IR_STATE_TIMEOUT      // 接收超时状态
} IR_State;

// 定义红外遥控解析结构体
typedef struct {
  IR_State state;       // 状态机状态
  unsigned char data;   // 红外信号数据
  unsigned char timeout;   // 接收超时标志位
} IR_Receiver;

// 定义红外遥控解析函数
void IR_Decode(unsigned char data) {
  switch (data) {
    case 0x00:
      // 红外码为0x00时执行的代码
      break;
    case 0x01:
      // 红外码为0x01时执行的代码
      break;
    case 0x02:
      // 红外码为0x02时执行的代码
      break;
    default:
      // 其他红外码时执行的代码
      break;
  }
}

void main() {
  // 初始化外部中断0
  IT0 = 1;   // INT0设为边沿触发
  EX0 = 1;   // 允许INT0中断

  // 初始化红外遥控解析结构体
  IR_Receiver ir_receiver = {
    .state = IR_STATE_IDLE,
    .data = 0,
    .timeout = 0
  };

  while (1) {
    switch (ir_receiver.state) {
      case IR_STATE_IDLE:
        // 空闲状态,等待红外信号开始
        ir_receiver.timeout = 0;
        break;
      case IR_STATE_START:
        // 红外信号开始状态,等待红外信号数据
        ir_receiver.timeout = 0;
        break;
      case IR_STATE_DATA:
        // 红外信号数据状态,解析红外码
        IR_Decode(ir_receiver.data);
        ir_receiver.timeout = 0;
        break;
      case IR_STATE_TIMEOUT:
        // 接收超时状态,清除超时标志位
        ir_receiver.timeout = 0;
        break;
      default:
        break;
    }

    // 判断接收超时
    if (ir_receiver.timeout) {
      ir_receiver.state = IR_STATE_TIMEOUT;
    }
  }
}

// 定义外部中断0处理函数
void INT0_ISR() interrupt 0 {
  static unsigned char timer = 0;

  // 判断红外信号是否正确
  if (IR_IN == 0) {
    timer = 0;
    ir_receiver.state = IR_STATE_START;
  } else if (ir_receiver.state == IR_STATE_START) {
    if (++timer >= 200) {   // 接收超时时间为2ms
      ir_receiver.state = IR_STATE_TIMEOUT;
      ir_receiver.timeout = 1;
      timer = 0;
    }
  } else if (ir_receiver.state == IR_STATE_DATA) {
    if (++timer >= 200) {   // 接收超时时间为2ms
      ir_receiver.state = IR_STATE_TIMEOUT;
      ir_receiver.timeout = 1;
      timer = 0;
    } else {
      ir_receiver.data <<= 1;
      if (IR_IN == 1) {
        ir_receiver.data |= 0x01;
        timer = 0;
      }
    }
    if (timer == 16) {   // 接收完整个红外码
      ir_receiver.state = IR_STATE_IDLE;
      timer = 0;
    }
  }

  // 清除中断标志位
  INT0 = 0;
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值