|
/********************************************************************
* *
* *
* CP-180单片机开发实验仪演示程序 - PS2 键值显示 * * *
* 红外遥控器键值显示 *
* 用短路帽将JP2短接,不用请拔掉,否则将会影响中断实验 *
* 2位数码管显示 *
* * * *
* DT9122D/6122 (遥控器) *
* *
* 版本: V1.0 *
* 作者: 未来 *
* 网站: www.sopc51.com(芯晶科技) *
* 邮箱: ece2008@126.com *
*******************************************************************/ *
/******** 红外遥控器键值表 ******
* 00 01 02
* 04 05 06
* 08 09 0A
* 0C 0D 0E
* 10 11 12
* 14 15 16
* 18 19 1A
*
*================================
IRCOM[0] --- 存放用户码 00H
IRCOM[1] --- 存放用户反码 BfH
IRCOM[2] --- 存放数据码
IRCOM[3] --- 存放数据反码
*******************************************************************/
#include <reg52.h>
#include <intrins.h>
sbit IRIN = P3 ^ 2; //红外接收器数据线
sbit BEEP = P2 ^ 3; //蜂鸣器驱动线
sbit RELAY = P3 ^ 6; //继电器驱动线
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char IRCOM[] =
{
0x00, 0x00, 0x00, 0x00, 0x10, 0x10
};
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节
/**********************************************************
ms延时子函数
**********************************************************/
void delayms(unsigned int ms)
{
unsigned char k;
while (ms--)
{
for (k = 0; k < 114; k++)
;
}
}
/**********************************************************
us延时子函数
**********************************************************/
void delay(unsigned char x) //x*0.14MS
{
unsigned char i;
while (x--)
{
for (i = 0; i < 14; i++)
;
}
}
/**********************************************************
蜂鸣器驱动子函数
**********************************************************/
void beep()
{
unsigned char i;
for (i = 0; i < 100; i++)
{
BEEP = !BEEP; //BEEP取反
delay(6);
}
BEEP = 1; //关闭蜂鸣器
}
/**********************************************************
显示函数
**********************************************************/
void display()
{
dula=0;
P0 = (table[IRCOM[4]]); //个位
dula=1;
dula=0;
wela=0;
P0=0xfd;
wela=1;
wela=0;
delayms(1);
dula=0;
P0 = (table[IRCOM[5]]); //十位
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delayms(1);
}
/**********************************************************
主函数
**********************************************************/
void main(void)
{
P0 = 0xff; //I/O口初始化
P2 = 0xff;
IRIN = 1;
BEEP = 1;
RELAY = 1;
IE = 0x81; //允许总中断中断,使能 INT0 外部中断
TCON = 0x01; //触发方式为脉冲负边沿触发
display();
while (1)
{
if (IRCOM[2] == 0x05)
//UP键
RELAY = 0;
//继电器吸合
if (IRCOM[2] == 0x06)
//DOWN键
RELAY = 1;
//继电器关闭
display(); //显示
}
}
/**********************************************************
INT0 中断服务子函数
**********************************************************/
void IR_IN()interrupt 0
{
unsigned char j, k, Num = 0;
EX0 = 0; //关闭INT0中断
delay(15); //延时
if (IRIN == 1)
//再确认IR信号是否出现
{
EX0 = 1; //开INT0中断
return ; //退出
}
while (!IRIN)
//等IR变为高电平,跳过9ms的前导低电平信号。
{
delay(1);
}
while (IRIN)
//等IR变为低电平,跳过4.5ms的前导高电平信号。
{
delay(1);
}
for (j = 0; j < 4; j++)
//收集四组数据
{
for (k = 0; k < 8; k++)
//每组数据有8位
{
while (IRIN)
//等 IR 变为低电平
{
delay(1);
}
while (!IRIN)
//等 IR 变为高电平
{
delay(1);
}
while (IRIN)
//计算IR高电平时长
{
delay(1);
Num++;
if (Num >= 15)
{
EX0 = 1; //0.14ms计数过长自动离开。
return ;
}
} //高电平计数完毕
IRCOM[j] = IRCOM[j] >> 1; //数据最高位补“0”
if (Num >= 8)
IRCOM[j] = IRCOM[j] | 0x80;
//数据最高位补“1”
Num = 0;
} //end for k
} //end for j
if (IRCOM[0] != 0x00)
//比较用户码
{
EX0 = 1; //开INT0中断
return ; //退出
}
if (IRCOM[2] != ~IRCOM[3])
//接收数据是否正确
{
EX0 = 1; //开INT0中断
return ; //退出
}
IRCOM[4] = IRCOM[2] &0x0F; //取键码的低四位
IRCOM[5] = IRCOM[2] >> 4; //右移4次,高四位变为低四位
display(); //显示键码
beep(); //蜂鸣器响一声
EX0 = 1; //重新开INT0中断
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|