⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 saa3010解码测试.txt

📁 SAA3010红外解码测试
💻 TXT
字号:
引用请保留版权信息,转载请注明出处~谢谢!

********************************************************************************************
* 功    能:红外解码。 
* 硬件条件:1.CPU型号:AT89C2051
*                2.晶振:12.0000MHz
*                3.MC14889 驱动4位4寸大LED
*                4.一体化红外接收头接P3.2 
*                5.遥控器,型号为SAA-3010T。                                                                                  
*
*                   下面是通过本程序解码SAA-3010T电视遥控器的键值表         
*          **********************************************************
*          *[开关PWOER]0C                                  [静音MUTE]0D
*          *[1]01        [2]02        [3]03      [4]04
*          *[5]05        [6]06        [7]07      [8]08
*          *[9]09        [0]00        [单/双 _/__]0A           [调谐SEARCH]1E
*          *[节目PROG+]20    [节目PROG-]21    [微调+]2B   [微调-]2C
*          *[音量VOL+]10    [存储STORE]29     [返回RECALL]0F               
*          *[音量VOL- ]11    [爱好P.P]OE     [定时SLEEP]26             
*          *[对比+]14   [色彩+]1C    [亮度+]12   [录像AV]38
*          *[对比-] 15   [色彩- ]1D    [亮度- ]13   [电视TV]3F
*          *********************************************************
*
* 作    者:JACK
* 日    期:2007年06月23号
* 博客:http://yeyudo.cn/

SAA3010.h

//==============================================================================
#ifndef __SAA3010__H__INCLUDED__
#define __SAA3010__H__INCLUDED__
//==============================================================================
#include <AT89X52.h> // MCS-51单片机
//==============================================================================


//==============================================================================
// 定义红外接收的接口(根据实际的硬件接线进行修改)
//==============================================================================
sbit SAA3010_RECV    = P3^2;    // INT0


// 由外部模块实现的处理函数
extern void SAA3010ProcessCommand( int remotecode );


// 初始化函数(注意:使用中断INT0及定时器T0)
void SAA3010Init();


//==============================================================================
#endif
//==============================================================================

SAA3010.c



#include "SAA3010.h"

//==============================================================================
//
// 状态机的含义:
//
//    状态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 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 )

// 用于解码的变量
unsigned int  SAA3010RecvCode = 0;        // 保存解码数值(1个控制位 5个地址位 6个命令位)
unsigned char SAA3010BitCount = 0;        // 记录已经解码的位数
unsigned char SAA3010State       = 0;        // 初始状态

// 初始化中断及定时器
void SAA3010Init()
{
    // 允许中断
    EA    =    1;
    
    // 定时器0
    TMOD = 0x01;    // T0工作于方式1,即16位定时器
    ET0     = 1;        // 关定时器0中断允许
    TR0     = 1;        // 关闭定时器0
    TH0  = 0;
    TL0  = 0;
    
    // 外部中断源INT0
    EX0  = 1;        // 允许外部中断源INT0
    PX0  = 1;        // 外部中断源为高优先级
    IT0  = 1;        // 边缘触发
    
    // 初始化变量
    SAA3010BitCount    =    0;
    SAA3010RecvCode    =    0;
    SAA3010State   =     0;
    
}

// 定时器T0的中断处理函数
void SAA3010Timer0(void) interrupt 1
{
    // 出现了超时
    if( SAA3010BitCount == 13 )
    {
        if( SAA3010State == 1 ||  // 1,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;
            
    // 启用中断
    EX0 = 1;
}

// 外部中断0的处理函数
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
        {
            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 // 错误状态
        {
            SAA3010BitCount = 0;
            SAA3010State     = 0;
        }
        break;
    }
}



Main.c




#include <DS1302.h>
#include <MC14489.h>

void Timer0_Init();
void ShowTime();
void DelayMs(unsigned int a);
unsigned char SwitchFlag = 0;


// 延时1ms
void DelayMs(unsigned int a)
{    
    unsigned char i = 0;
    while( --a != 0)
    {        
        for(i = 0; i < 125; i++);  //一个 ; 表示空语句,CPU空转。
    }                              //i 从0加到125,CPU大概就耗时1毫秒
}

// 显示时间
void ShowTime()
{
    // 从DS1302读取时间信息
    unsigned char hour         = CLOCK_READ_TIME_PART( TIME_PART_HOUR ); // 小时
    unsigned char minute    = CLOCK_READ_TIME_PART( TIME_PART_MINUTE);// 分钟
    unsigned char second     = CLOCK_READ_TIME_PART( TIME_PART_SECOND);// 秒
    unsigned char buffer[3];
    buffer[1] = minute;
    buffer[2] = second;

    // 显示到MC14489
    // 显示分钟和秒钟
    if( SwitchFlag == 0 )
    {
        SwitchFlag     = 1;
        buffer[0]    = 0x80;
    }
    else
    {
        SwitchFlag     = 0; 
        buffer[0]    = 0xB0;
    }

    MC14489Write( buffer,3 );
}


// 处理红外命令
void SAA3010ProcessCommand(int remotecode)
{
    unsigned char buffer[3];
    buffer[0] = 0x80;
    buffer[1] = (unsigned char)((remotecode >> 8)& 0xFF);
    buffer[2] = (unsigned char)(remotecode & 0xFF);
    MC14489WriteCmd( 0x01 ); 
    MC14489Write( buffer,3 );
}


// 主函数
void main()
{
    // 初始化红外接收设备
    SAA3010Init();

    // 初始化MC14489
    MC14489WriteCmd( 0x01 ); // 显示器处于正常工作状态
//    CLOCK_INIT();
    while( 1 )
    {
//        MC14489WriteCmd( 0x01 );
//        ShowTime();
        DelayMs(495);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -