×
单片机 > 单片机程序设计 > 详情

SAA3010红外解码(C51)

发布时间:2020-08-21 发布时间:
|
/********************************************************************************************
* 功    能:红外解码。 
* 硬件条件:1.CPU型号:AT89S52
*           2.晶振:12.000MHz
*           3.用跳线帽短接P2.3__SI2
*             用跳线帽短接P2.2__RCK2
*             用跳线帽短接P2.1__SCK2
*           4.用跳线帽短接HW-IRQ__P3.2 
*           5.欲完成本实验,还需另行准备一个遥控器,型号为SAA-3010T。                                                                                  
* 注    意:在SAA-3010T遥控器的身份码中,大多数是0x55,可是有一小部分的码是0x56,一定要注意区分。
*
*                   下面是一般的SAA-3010T电视遥控器的码值表         
*          **********************************************************
*          *[开关]55D2                                  [静音]55D3  *
*          *[1]55AB        [2]55AC        [3]55AD       [4]55B2     *
*          *[5]55B3        [6]55B4       [7]55B5       [8]55CA     *
*          *[9]55CB        [0]55AA        [单/双]55CC   [调谐]5554  *
*          *[节目+]56AA    [节目-]56AB    [微调+]56CD   [微调-]56D2 *
*          *[音量+]552A    [存储]56CB     [召回]55D5                *
*          *[音量-]552B    [爱好]55D4     [定时]56B4                *
*          *[对比+]5552    [色彩+]5532    [亮度+]5526   [录像]564A  *
*          *[对比-]5553    [色彩-]5533    [亮度-]55D2   [电视]5655  *  
*          *********************************************************
*
* 作    者:POWER
* 日    期:2006年12月12号
* 斯凯科技主页:www.armsky.net
* 斯凯科技论坛:www.armsky.net/bbs
*********************************************************************************************/
#include "reg52.h"                               // 包含头文件    

/* 与编译器无关的数据类型定义 */
/********************************************************************************************/
typedef unsigned char      uint8;                // 无符号8位整型变量
typedef signed   char      int8;                 // 有符号8位整型变量
typedef unsigned short     uint16;               // 无符号16位整型变量
typedef signed   short     int16;                // 有符号16位整型变量
typedef unsigned int       uint32;               // 无符号32位整型变量
typedef signed   int       int32;                // 有符号32位整型变量
typedef float              fp32;                 // 单精度浮点数(32位长度)
typedef double             fp64;                 // 双精度浮点数(64位长度)
/********************************************************************************************/

/* 定义位变量 */
sbit P2_3 = P2 ^ 3;                              
sbit P2_2 = P2 ^ 2;
sbit P2_1 = P2 ^ 1;
sbit HW_IRQ = P3 ^ 2;                            // 定义38KHz一体化红外接收头与CPU的连接                                              
sbit P1_7 = P1 ^ 7;                              

#define LED11_ON()   (P1_7=0)                    // 定义"LED11_ON()"为AT89S52的P1.7脚输出低电
                                                 // 平使LED11点亮
#define LED11_OFF()  (P1_7=1)                    // 定义"LED11_OFF()"为AT89S52的P1.7脚输出高电
                                                 // 平使LED11熄灭

#define SI2_H()       (P2_3=1)                   // 定义"SI2_H()"为P2.3输出高电平,作为74HC595_2的数据输入信号
#define SI2_L()       (P2_3=0)                   // 定义"SI2_L()"为P2.3输出低电平,作为74HC595_2的数据输入信号  
#define RCK2_H()      (P2_2=1)                   // 定义"RCK2_H()"为P2.2输出高电平,作为74HC595_2的片选输入信号
#define RCK2_L()      (P2_2=0)                   // 定义"RCK2_L()"为P2.2输出低电平,作为74HC595_2的片选输入信号
#define SCK2_H()      (P2_1=1)                   // 定义"SCK2_H()"为P2.1输出高电平,作为74HC595_2的时钟输入信号
#define SCK2_L()      (P2_1=0)                   // 定义"SCK2_L()"为P2.1输出低电平,作为74HC595_2的时钟输入信号

static uint8 data IRCode[3],IRCON,IRCON2;
static uint8 data DT;
static uint8 data LED_SHOW;
/********************************************************************************************
* 函数名称:SendDataTo74HC595_2()
* 功    能:向74HC595_2发送一字节数据
* 入口参数:data    要发送的数据
* 出口参数:无
* 注    意:发送数据时,高位先发送
*********************************************************************************************/
void SendDataTo74HC595_2(uint8 dat)
{
  uint8 i;
  
  RCK2_L();                                      // RCK2为低电平
  for(i=0;i<8;i++)                               // 发送8位数据(1个字节)
     {
       SCK2_L();                                 // SCK2为低电平
       
    /* 设置SI2的输出值 */
       if((dat & 0x80)!=0)
         {SI2_H();}                              // SI2输出高电平
       else
         {SI2_L();}                              // SI2输出低电平
       
    dat<<=1;                                  // 将要发送的1字节数据左移一位
       SCK2_H();                                 // SCK2为高电平
     }
  RCK2_H();                                      // RCK2为高电平     
}

/********************************************************************************************
* 函数名称:Timer0_Server()
* 功    能:定时器0中断服务程序
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void Timer0_Server(void) interrupt 1 using 2
{
  TH0=0xFC;                                      // 12M: TH0=0XFC;TL0=0XE0;11.0592:TH0=0XFD;TL0=0X1E;
  TL0=0xE0;                                      // 设定时值为800us  500:FE0C
  
  if(IRCON<3)
   {
     if(IRCON2<8)                                // 每中断一次读一次遥控接收头的状态,每二次为遥控编码中的一个位
   {
     IRCON2++;
  IRCode[IRCON]=IRCode[IRCON]<<1;          // 每读一次放入变量中的二进制的一个位,每次左移一位
  IRCode[IRCON]=IRCode[IRCON] | HW_IRQ;    // 每八次填满一个字节,一个字节存放遥控编码4个位
   }
  else
   {
     IRCON++;                                 // 填满一个字节,指向下一个变量
  IRCON2=0;                                // 计数清零
   }
   }
  else
   {
     TR0 = 0;                                    // 关闭定时器
  ET0 = 0;                                    // 定时器0中断关闭
  if((IRCode[1] != 0xFF) && (IRCode[2] != 0xFF))
   {
     if(IRCode[1] == 0x55)
   {
     switch(IRCode[2]) 
    {
      case 0xD2:                     // 按下[开关]键
                
                DT = 1;
                break;
      case 0xD3:                     // 按下[静音]键
                
                DT = 1;
                break;
      case 0xAB:                     // 按下[1]键
                
                DT = 1;
                break;
      case 0xAC:                     // 按下[2]键
                
                DT = 1;
                break;
      case 0xAD:                     // 按下[3]键
               
                DT = 1;
                break;
      case 0xB2:                     // 按下[4]键
               
                DT = 1;
                break;
      case 0xB3:                     // 按下[5]键
               
                DT = 1;
                break;
      case 0xB4:                     // 按下[6]键
                
                DT = 1;
                break;
      case 0xB5:                     // 按下[7]键
               
                DT = 1;
                break;
      case 0xCA:                     // 按下[8]键
               
                DT = 1;
                break;
      case 0xCB:                     // 按下[9]键
                
                DT = 1;
                break;
      case 0xAA:                     // 按下[0]键
                
                DT = 1;
                break;
      case 0xCC:                     // 按下[单/双]键
                
                DT = 1;
                break;
      case 0x54:                     // 按下[调谐]键
                
                DT = 1;
                break;
      case 0x2A:                     // 按下[音量+]键
                
                DT = 1;
                break;
      case 0x2B:                     // 按下[音量-]键
                
                DT = 1;
                break;
      case 0xD5:                     // 按下[召回]键
               
                DT = 1;
                break;
      case 0xD4:                     // 按下[爱好]键
                
                DT = 1;
                break;
      case 0x52:                     // 按下[对比+]键
                
                DT = 1;
                break;
      case 0x53:                     // 按下[对比-]键
                
                DT = 1;
                break;
      case 0x32:                     // 按下[色彩+]键
                
                DT = 1;
                break;
      case 0x33:                     // 按下[色彩-]键
                
                DT = 1;
                break;
   //   case 0x26:                     // 按下[亮度+]键
                
   //             DT = 1;
   //             break;
   //   case 0xD2:                     // 按下[亮度-]键
                
   //             DT = 1;
   //             break;
      
      default :
                break;
    }
   }
  if(IRCode[1] == 0x56)
   { 
     switch(IRCode[2]) 
    {
      case 0xAA:                     // 按下[节目+]键
                
                DT = 1;
                break;
      case 0xAB:                     // 按下[节目-]键
                
                DT = 1;
                break;
                  case 0xCD:                     // 按下[微调+]键
                
                DT = 1;
                break;
      case 0xD2:                     // 按下[微调-]键
                
                DT = 1;
                break;
      case 0xCB:                     // 按下[存储]键
                
                DT = 1;
                break;
      case 0xB4:                     // 按下[定时]键
                
                DT = 1;
                break;
      case 0x4A:                     // 按下[录象]键
                
                DT = 1;
                break;
      case 0x55:                     // 按下[电视]键
                
                DT = 1;
                break;
                  
      default :
                break;
    }
   }
   }
   }
}

/********************************************************************************************
* 函数名称:INT0_Server()
* 功    能:外部中断0中断服务程序
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void INT0_Server(void) interrupt 0 using 2
{
  EX0 = 0;                                       // 外部中断0关闭
  ET0 = 1;                                       // 定时器0中断打开
  TH0=0xFc;
  TL0=0xe0;                                      // 设定时值为800us

  for(IRCON=0;IRCON<3;IRCON++) IRCode[IRCON] = 0;
  IRCON = 0;
  IRCON2 = 0;                                    // 计数清零

  TR0 = 1;                                       // 开始计数
}

/********************************************************************************************
* 函数名称:main()
* 功    能:红外解码。将38KHz一体化红外接收头接收到的来自SAA-3010T遥控器的遥控编码在LED1~LED8
*           上显示(LED8为高位,LED1为低位,亮表示1,灭表示0)。
*********************************************************************************************/    
void main (void)                
{
  uint16 de;

  TMOD = 0x01;                                   // 定时器0方式1
  EA = 1;                                        // 允许CPU中断
  IT0 = 1;                                       // INT0下降沿有效
  EX0 = 1;                                       // 开INT0中断

  SendDataTo74HC595_2(0xFF);                     // LED1~LED8熄灭

  do

  
   for(de=0;de<8000;de++) LED11_ON();         // LED11点亮
   for(de=0;de<8000;de++) LED11_OFF();        // LED11熄灭 
   if(DT)
    {
      EX0=0;                                  // 关闭外中断0
   for(de=0;de<30000;de++) LED11_ON();     // 这里起到按键值正确后会有一个延时,防止重复按键
   for(de=0;de<30000;de++) LED11_OFF();    
   DT = 0;
   SendDataTo74HC595_2(~IRCode[2]);        // LED1~LED8显示当前接收到的遥控编码值
    }
   EX0 = 1;                                   // 打开外部中断0
}while(1);
}


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会