各位大佬,最近在做一个NEC格式的红外遥控器的接收项目,但是始终没能正确解析,请大佬们指正代码的问题,万分感谢。我的晶振是18.432MHz,定时器是200us,目前的结果是每次获取都是一堆7F,不知道问题出在哪里。
另外,想再问下各位大佬,红外遥控器有去抖的说法嘛?
1、单片机头文件的相关定义
- #define FOSC 18432000L
- #define T0US (65536 - (FOSC / 12 / 1000000 * 200)) //200us timer calculation method in 12T mode
- // 红外的时间
- extern BYTE Ir_Time;
- // 收到红外信号
- extern BYTE Ir_Start;
- // 收到红外信号头
- extern BYTE Ir_Header;
- // 红外数据
- extern BYTE Ir_Data[33];
- // 红外码
- extern BYTE Ir_Code[4];
- // 数据索引
- extern BYTE Data_Index;
- // 有新编码
- extern BYTE New_Code;
- // 红外初始化
- extern void IrInit(void);
- // 红外编码解析
- extern void IrDecode(void);
复制代码
2、红外初始化
- void IrInit(void) //100微秒@18.432MHz
- {
- // 打开红外接收中断
- IT1 = 1; // 外部中断1下降沿触发
- EX1 = 1; // 打开外部中断1
-
- //200us @18.432MHz
- TMOD |= 0x01; //set timer0 as mode1 (16-bit)
- TL0 = T0US; //initial timer0 low byte
- TH0 = T0US >> 8; //initial timer0 high byte
- ET0 = 1; //enable timer0 interrupt
- }
复制代码
3、红外编码解析
- // 红外编码的解析
- void IrDecode(void)
- {
- BYTE i = 0, j = 0, time = 0, ir_tmp_code = 0;
- for(i = 0; i < 4; i++) // 处理开头的两个字节
- {
- for(j = 0; j < 8; j++)
- {
- time = Ir_Data[i * 8 + j + 1];
- if(time > 5) // 大于1.125ms表示1,否则就为0
- {
- ir_tmp_code |= 0x80;
- }
- ir_tmp_code = ir_tmp_code >> 1;
- }
-
- Ir_Code[i] = ir_tmp_code;
- ir_tmp_code = 0;
- }
- }
复制代码
4、中断处理
- // 遥控器接收中断,外部中断1
- void Ir_Isr(void) interrupt 2 using 2
- {
- TR0 = 1; // 启动定时器0
-
- if(Ir_Start) // 判断是否遥控器接收已经启动
- {
- if(Ir_Time >= 40 && Ir_Time < 75) // 引导码大于4.5ms小于90
- {
- Ir_Data[Data_Index++] = Ir_Time; // 保存时间
- Ir_Time = 0; // 重置时间
- Ir_Header = 1;
- }
- else
- {
- if(Ir_Header)
- {
- Ir_Data[Data_Index++] = Ir_Time;
- if(Data_Index == 34) // 保存了4个字节的信息
- {
- New_Code = 1; // 数据填满
- TR0 = 0; // 暂停定时器0
- Ir_Start = 0; // 重置遥控器接收启动位
- Data_Index = 0; // 重置数据索引
- Ir_Header = 0;
- }
- Ir_Time = 0; // 重置脉宽时间
- }
- }
- }
- else
- {
- // 接收遥控器发送启动
- Ir_Start = 1;
- // 定时器归位
- Ir_Time = 0;
- }
- }
复制代码
5、定时器处理
- // 遥控器接收定时器
- void Ir_Timer_Isr(void) interrupt 1 using 1
- {
- TL0 = T0US; //initial timer0 low byte
- TH0 = T0US >> 8; //initial timer0 high byte
-
- if(count >= 5000)
- {
- LED = !LED;
- count = 0;
- }
- count++;
-
- Ir_Time++; // 红外时间以200us累加
- }
复制代码
|