|
以下为本人改编某个网址(具体的网址我忘了)的SAA-3010T解码程序所得,已经测试成功,希望可供大家参考,觉得不错的话就帮忙顶一下!如有疑问,可加本人QQ:175070658 讨论。
/********************************************************************************************
* 功 能:红外解码。
* 硬件条件:1.CPU型号:AT89S52
* 2.晶振:11.0592MHz
* 3.一体化红外接收头接P3.2
* 4.遥控器,型号为SAA-3010T。
*
* 下面是通过本程序解码SAA-3010T电视遥控器的键值表
* **********************************************************
* *[开关PWOER]12 [静音MUTE]13
* *[1]01 [2]02 [3]03 [4]04
* *[5]05 [6]06 [7]07 [8]08
* *[9]09 [0]00 [单/双 _/__]10 [搜索]30
* *[节目PROG+]32 [节目PROG-]33 [微调+]43 [微调-]44
* *[音量VOL+]16 [存储STORE]41 [屏显]15
* *[音量VOL- ]17 [预调]14 [睡眠]38
* *[对比+]18 [色彩+]20 [亮度+]28 [录像AV]56
* *[对比-]19 [色彩-]21 [亮度-]29 [电视TV]63
* *********************************************************
*
* 作 者:LI RU-xiao
* 日 期:2008年5月6日
//==============================================================================
// 定义红外接收的接口(根据实际的硬件接线进行修改)
//==============================================================================
sbit SAA3010_RECV = P3^2; // INT0
//==============================================================================
//
// 状态机的含义:
//
// 状态S0: 初始状态
// 状态S1: 1,1 状态,在两个bit中间触发中断
// 状态S2: 0 状态
//
// S1->S1: 1个周期
// S1->S2: 1.5个周期
// S2->S2: 1个周期或2个周期
// S2->S1: 1.5个周期
//
//==============================================================================
//==============================================================================
// 时间常数(使用晶震频率为11.0592MHz)
//==============================================================================*/
#include <reg52.h>
#include <D:\C51_H\LCD1602.H> //我的LCD1602库
//#define CYCLE_1_0 0x60A // 1688us
//#define CYCLE_1_5 0x910 // 2532us
//#define CYCLE_2_0 0x0C15 // 3376us
#define CYCLE_1_0 0x65B // 1776us
#define CYCLE_1_5 0x989 // 2664us
#define CYCLE_2_0 0x0CB7 // 3552us
#define TH_CYCLE_1_0 (CYCLE_1_0>>8) //提取定时器高8位值
#define TH_CYCLE_1_5 (CYCLE_1_5>>8)
#define TH_CYCLE_2_0 (CYCLE_2_0>>8)
// 用于解码的变量
unsigned int SAA3010RecvCode=0; // 保存解码数值(1个开始位 1个控制位 5个地址位 6个命令位)
unsigned char SAA3010BitCount=0; // 记录已经解码的位数
unsigned char SAA3010State=0; // 初始状态
unsigned char buffer;
// 初始化中断及定时器
void SAA3010Init()
{
// 定时器0
TMOD=0x01; // T0工作于方式1,即16位定时器
ET0=0; // 关定时器0中断允许
TR0=0; // 关闭定时器0
TH0=0;
TL0=0;
// 外部中断源INT0
EX0=1; // 允许外部中断源INT0
PX0=1; // 外部中断源为高优先级
IT0=1; // 边缘触发
// 允许中断
EA=1;
}
// 处理红外命令
void SAA3010ProcessCommand(int remotecode)
{
buffer=(unsigned char)(remotecode&0xFF);
speaData(buffer,2); //我的自定义拆字子程序,提供给LCD1602显示
}
// 外部中断0的处理函数 SAA_3010T 解码程序
void SAA3010Int0(void) interrupt 0
{
// 保存计数器的高位,作为判断周期长短的依据
unsigned char HighTick=TH0;
// 重置计数器
TH0=0;TL0=0;TR0=1;ET0=1;
// 状态转移图
switch( SAA3010State )
{
case 0: // 第一个起始位
SAA3010State=2;
SAA3010BitCount=1;
SAA3010RecvCode=0;
break;
case 1: // 状态1
if(HighTick==TH_CYCLE_1_0) // S1->S1 (持续位1状态)
{
SAA3010State=1;
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
}
else if(HighTick==TH_CYCLE_1_5) // S1->S2 ( 1,1,0 ) 转到位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(持续位0状态)
{
SAA3010State=2;
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
}
else if(HighTick==TH_CYCLE_1_5) // S2->S1(转到位1状态)
{
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 // 错误状态
{
SAA3010BitCount=0;
SAA3010State=0;
}
break;
default:break;
}
}
// 定时器T0的中断处理函数
void SAA3010Timer0(void) interrupt 1
{
ET0=0; // 关定时器0中断允许
TR0=0; // 关闭定时器0
// 出现了超时
if( SAA3010BitCount==13 )
{
if((SAA3010State==1)||(SAA3010State==2)) // 0,1
{
SAA3010BitCount ++;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
}
}
// 检查是否有合理数据
if( SAA3010BitCount==14 )
{
// 停止中断0
EX0=0;
// 处理遥控命令
SAA3010ProcessCommand((~SAA3010RecvCode)&0x0FFF);
// 重新初始化初始化
SAA3010BitCount=0;
SAA3010State= 0;
LCD1602_puts(9,0,dataElem); //键值显示程序
}
// 启用中断
EX0=1;
}
// 主函数
void main()
{
//1602初始化
LCD1602_init();
LCD1602_puts(0,0,"SAA-3010T Test!");
delay50ms(40);
LCD1602_setCmd("CLR_SCR");
LCD1602_puts(0,0,"KeyValue=");
// 初始化红外接收设备
SAA3010Init();
while(1);
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|