当前位置:首页 > 单片机 > 单片机
[导读]/******************************************************************************************** * 功能:红外解码。 * 硬件条件:1.CPU型号:AT89S52 * 2.晶振:12.000MHz * 3.用跳线帽短接P2.3__SI2 * 用跳

/********************************************************************************************
* 功能:红外解码。
* 硬件条件: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 charuint8;// 无符号8位整型变量
typedef signed charint8; // 有符号8位整型变量
typedef unsigned short uint16; // 无符号16位整型变量
typedef signed short int16;// 有符号16位整型变量
typedef unsigned int uint32; // 无符号32位整型变量
typedef signed int int32;// 有符号32位整型变量
typedef floatfp32; // 单精度浮点数(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;// 设定时值为800us500: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);
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机内部有很多的特殊功能寄存器,每个寄存器在单片机内部都分配有唯一的地址,一般我们会根据寄存器功能的不同给寄存器赋予各自的名称,当我们需要在程序中操作这些特殊功能寄存器时,必须要在程序的最前面将这些名称加以声明,声明的...

关键字: C51 数据类型 扩充定义

数据元(Data Element),也称为数据元素,是用一组属性描述其定义、标识、表示和允许值的数据单元,在一定语境下,通常用于构建一个语义正确、独立且无歧义的特定概念语义的信息单元。数据元可以理解为数据的基本单元,将若...

关键字: C51 数据类型

▼点击下方名片,关注公众号▼欢迎关注【玩转单片机与嵌入式】公众号,回复关键字获取更多免费资料。回复【加群】,限时免费进入知识共享群;回复【3D封装库】,常用元器件的3D封装库;回复【电容】,获取电容、元器件选型相关的内容...

关键字: C51 MDK RealView

在Keil C51软件中51单片机的中断服务和外设驱动程序的开发

关键字: keil5 编译 C51

Intel公司1980年推出了MCS-51系列单片机:集成 8位CPU、4K字节ROM、128字节RAM、4个8位并口、1个全双工串行口、2个16位定时/计数器。寻址范围64K,并有控制功能较强的布尔处理器。 80C5...

关键字: C51 KEIL 编程

c上标3下标5怎么算用计算机,c上标3下标5怎么算

关键字: C51 KEIL

▼点击下方名片,关注公众号▼大家好,很高兴和各位一起分享我的第16篇原创文章,喜欢和支持我的工程师,一定记得给我点赞、收藏、分享。加微信[xyzn3333]与作者沟通交流,免费获取更多单片机与嵌入式的海量电子资料。很多初...

关键字: 51单片机 C51

常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。

关键字: C51 单片机 误区 注意事项

简介:编程首要是要考虑程序的可行性,然后是可读性、可移植性、健壮性以及可测试性。这是总则。但是很多人忽略了可读性、可移植性和健壮性(可调试的方法可能歌不相同),这是不对的。

关键字: C51 编程规范 文件配置

如果你用 Keil C51 进行编译,记住一点:它不区分大小写!!!卧槽,今天编程序那个调错啊,就因为一个数组名和一个变量名完全一样,只是大小写不一样罢了,标准 C 我怎么记得这样可以啊……上网一查,卧槽,Keil C5...

关键字: C51 单片机 编程要点
关闭
关闭