📄 saa3010.h
字号:
/********************************************************************************************
* 功 能:红外解码。
* 硬件条件:1.CPU型号:AT89C8051
* 2.晶振:12.0000MHz
* 3.一体化红外接收头接P3.3
* 4.遥控器,型号为SAA-3010T。
*
* 下面是通过本程序解码SAA-3010T电视遥控器的键值表
* **********************************************************
* *[静音]7f2/ff2 [开/关」7f9/ff9
* *[1]7fe/ffe [2]7fd/ffd [3]7fc [4]7fb
* *[5]ffa [6]7f9 [7]ff8 [8]7f7
* *[9]7f6/ff6 [0]7ff/fff [单/双]ff5 [搜索]7e1
* *[频道+]7df [频道-]7de [微调+]7d4 [微调-]7d3
* *[音量VOL+]7ef [存储STORE]fdb [显示]ff0
* *[音量VOL- ]fee [设定]ff1 [定时]7d9
* *[亮度+]7ed [彩色+]feb [对比度+]fe3 [视频]7c7
* *[亮度-]7ec [彩色-]fea [对比度-]fe2 [转换]7c0
*********************************************************************************/
#ifndef __SAA3010__H__INCLUDED__
#define __SAA3010__H__INCLUDED__
//==============================================================================
#include <AT89X52.h>
#include "define.h"
// 定义红外接收的接口(根据实际的硬件接线进行修改)
//==============================================================================
sbit SAA3010_RECV = P3^3; // INT1 红外接收的接口
void SAA3010Init();
//==============================================================================
//
// 状态机的含义:
//
// 状态S0: 初始状态
// 状态S1: 1,1 状态,在两个bit中间触发中断
// 状态S2: 0 状态
//
// S1->S1: 1个周期
// S1->S2: 1.5个周期
// S2->S2: 1个周期或2个周期
// S2->S1: 1.5个周期
//
//==============================================================================
//==============================================================================
// 时间常数(使用晶震频率为12MHz,周期为1.688ms)
//==============================================================================
#define CYCLE_1_0 0x698 // 1688us
#define CYCLE_1_5 0x9E4 // 2532
#define CYCLE_2_0 0xD30 // 3376us
//#define CYCLE_5_0 0x20f8 //8440us
//#define TH_CYCLE_5_0 ( CYCLE_5_0 >> 8 )
#define TH_CYCLE_1_0 ( CYCLE_1_0 >> 8 )
#define TH_CYCLE_1_5 ( CYCLE_1_5 >> 8 )
#define TH_CYCLE_2_0 ( CYCLE_2_0 >> 8 )
bit ykok=0;
// 用于解码的变量
unsigned int SAA3010RecvCode = 0; // 保存解码数值(1个控制位 5个地址位 6个命令位)
unsigned char SAA3010BitCount = 0; // 记录已经解码的位数
unsigned char SAA3010State = 0; // 初始状态
// 初始化中断及定时器
void SAA3010Init()
{
// 允许中断
EA = 1;
// 定时器1
TMOD = 0x10; // T1工作于方式1,即16位定时器
ET1 = 1; // 关定时器0中断允许
TR1 = 1; // 关闭定时器0
TH1 = 0;
TL1 = 0;
// 外部中断源INT0
EX1 = 1; // 允许外部中断源INT1
PX1 = 1; // 外部中断源为高优先级
IT1 = 1; // 边缘触发
// 初始化变量
SAA3010BitCount = 0;
SAA3010RecvCode = 0;
SAA3010State = 0;
}
// 定时器T0的中断处理函数
void SAA3010Timer1(void) interrupt 3 using 3
{
// 出现了超时
if( SAA3010BitCount == 13 )
{
if( SAA3010State == 1 || // 1,1
SAA3010State == 2 ) // 0,1 //初始化状态为11或者01
{
SAA3010BitCount ++;
SAA3010RecvCode = SAA3010RecvCode << 1;
SAA3010RecvCode = SAA3010RecvCode + 1;//解码最后一位补1
SAA3010RecvCode=SAA3010RecvCode&0x0fff;
}
ykok=1; //遥控数据有效
}
// 检查是否有合理数据
else if( SAA3010BitCount == 14 )
{
// 停止中断0
EX1 = 0;
// 处理遥控命令
// SAA3010ProcessCommand((~SAA3010RecvCode) & 0x0FFF );
SAA3010RecvCode=SAA3010RecvCode&0x0fff;
ykok=1; //遥控数据有效
}
else EX1 = 1;
// 重新初始化初始化
SAA3010BitCount = 0;
SAA3010State = 0;
// 启用中断
}
// 外部中断1的处理函数
void SAA3010Int1(void) interrupt 2 using 2
{
// 保存计数器的高位,作为判断周期长短的依据
unsigned char HighTick = TH1;
// 重置计数器
TH1=0;TL1=0;TR1=1;ET1=1;
// 状态转移图
switch( SAA3010State )
{
case 0: // 第一个起始位
SAA3010State = 2;
SAA3010BitCount = 1;
SAA3010RecvCode = 0;
break;
case 1: // 状态1
if( HighTick == TH_CYCLE_1_0 ) // S1->S1
{
SAA3010State = 1;
SAA3010BitCount++;
SAA3010RecvCode = SAA3010RecvCode << 1;
SAA3010RecvCode = SAA3010RecvCode + 1;
}
else if( HighTick == TH_CYCLE_1_5 ) // S1->S2 ( 1,1,0 )
{
SAA3010State = 2;
SAA3010BitCount = SAA3010BitCount+2;
SAA3010RecvCode = SAA3010RecvCode << 1;
SAA3010RecvCode = SAA3010RecvCode + 1;
SAA3010RecvCode = SAA3010RecvCode << 1;
}
else // 错误状态
{
SAA3010BitCount = 0;
SAA3010State = 0;
}
break;
case 2: // 状态2
if( HighTick == TH_CYCLE_1_0 ) // S2->S2
{
SAA3010State = 2;
SAA3010BitCount++;
SAA3010RecvCode = SAA3010RecvCode << 1;
}
else if( HighTick == TH_CYCLE_1_5 ) // S2->S1
{
SAA3010State = 1;
SAA3010BitCount++;
SAA3010RecvCode = SAA3010RecvCode << 1;
SAA3010RecvCode = SAA3010RecvCode + 1;
}
else if( HighTick == TH_CYCLE_2_0 ) // S2->S2
{
// 0->1->0
SAA3010State = 2;
SAA3010BitCount = SAA3010BitCount+2;
SAA3010RecvCode = SAA3010RecvCode << 1;
SAA3010RecvCode = SAA3010RecvCode + 1;
SAA3010RecvCode = SAA3010RecvCode << 1;
}
// else if( HighTick >TH_CYCLE_5_0 ){EX1=1;}
else // 错误状态
{
SAA3010BitCount = 0;
SAA3010State = 0;
}
break;
}
}
unsigned char hget_Key()
{
if(SAA3010RecvCode==0x07fe||SAA3010RecvCode==0x0ffe)
{
return (1);
}
if(SAA3010RecvCode==0x07fd||SAA3010RecvCode==0x0ffd)
{
return (2);
}
if(SAA3010RecvCode==0x07fc)
{
return (3);
}
if(SAA3010RecvCode==0x07fb)
{
return (4);
}
if(SAA3010RecvCode==0x0ffa)
{
return (5);
}
if(SAA3010RecvCode==0x07f9)
{ return (6);
}
if(SAA3010RecvCode==0x0ff8)
{return (7);
}
if(SAA3010RecvCode==0x07f7)
{ return (8);
}
if(SAA3010RecvCode==0x07f6||SAA3010RecvCode==0x0ff6)
{ return (9);
}
if(SAA3010RecvCode==0x07ff||SAA3010RecvCode==0x0fff)
{ return (0);
}
if(SAA3010RecvCode==0x07f2||SAA3010RecvCode==0x0ff2) //静音 date and time
{
return (10);
}
if(SAA3010RecvCode==0x07ec) //亮度- close
{ return (11);
}
if(SAA3010RecvCode==0x0fea) //彩色- wind
{ return (12);
}
if(SAA3010RecvCode==0x0fe2) //对比度- default
{ return (13);
}
if(SAA3010RecvCode==0x07c0) //转换 enter
{ return (14);
}
//b=1;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -