#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;
}