开发板上焊接有红外接收模块VS1838B,可以接收红外遥控器发来的红外数据,并通过程序的解码最终得到按下的哪个按键,使用如下程序可以将按下的按键值显示到LCD1602上:
infrared.h:
#ifndef _INFRARED_H
#define _INFRARED_H
#include "reg52.h"
#define Time_16ms 16000 //16ms
extern bit Flag; //定义一个接收标志,正确接收后标志置1
extern unsigned long infvalue; //接收数据存放变量,32位
extern unsigned char *keys;
unsigned int Time(bit Flag);
void Int1_Init(void);
void KeyTrans(unsigned int keyvalue);
void KeyValue_Transform(unsigned char k);
#endif
infrared.c:
#include "infrared.h"
sbit inf = P3^3; //位定义红外接收引脚
bit Flag; //定义一个接收标志,正确接收后标志置1
unsigned char *keys;
void Int1_Init(void)
{
TMOD &= 0xF0; //清空定时器0的控制位
TMOD = 0x01; //定时器0工作在方式1,16位定时器
TR0 = 0; //关闭定时器
ET0 = 0; //关闭定时器0中断,采用查询模式
IT1 = 1; //设置外部中断1下降沿触发
EX1 = 1;
EA = 1;
inf = 1; //初始化红外接收引脚为高电平
}
unsigned int Time(bit Flag) //输出低电平直接输出时间,高电平需要判断是否超过16ms
{
TH0 = 0;
TL0 = 0; //定时器初始值清零
TR0 = 1; //开启定时器
while( (inf == Flag) ) //P3.3引脚的高电平时间超过16ms时为超时
{
if( TH0 >= (Time_16ms >> 8) ) break;
}
TR0 = 0;
return (TH0*256 + TL0); //返回定时时间,单位为us
}
//键值转换函数,将键值转换成按键字符
void KeyValue_Transform(unsigned char k)
{
switch( k )
{
case 69:keys = "CH-";break;
case 70:keys = "CH";break;
case 71:keys = "CH+";break;
case 68:keys = "PREV";break;
case 64:keys = "NEXT";break;
case 67:keys = "PLAY/PAUSE";break;
case 7:keys = "-";break;
case 21 :keys = "+";break;
case 9:keys = "EQ";break;
case 22:keys = "0";break;
case 25:keys = "100+";break;
case 13:keys = "200+";break;
case 12:keys = "1";break;
case 24:keys = "2";break;
case 94:keys = "3";break;
case 8:keys = "4";break;
case 28:keys = "5";break;
case 90:keys = "6";break;
case 66:keys = "7";break;
case 82:keys = "8";break;
case 74:keys = "9";break;
default: keys = "error"; break;
}
}
main.c:
#include "reg52.h"
#include "LCD1602.h"
#include "infrared.h"
unsigned char key;
unsigned long infvalue; //接收数据存放变量,32位
void main(void)
{
LCD_Init(); //LCD初始化
Int1_Init(); //红外初始化
LCD_WriteString(1,1,"Infrared Key:");
while(1)
{
if( Flag )
{
Flag = 0; //接受标志清零
key = ( unsigned char ) ( infvalue >>16 ); //取出数据码
KeyValue_Transform(key); //键值转换
LCD_WriteString(2,1," ");
LCD_WriteString(2,1,keys); //在第二行第一个位置开始显示
}
}
}
void Int1() interrupt 2
{
unsigned int i;
unsigned int TL,TH;
TL = Time(0);
TH = Time(1);
/****下面语句判断引导码的正确与否****/
if( TL < 8000 || TL > 10000 || TH < 3500 || TH > 5000 ) //高、低电平的时间超过范围的话直接退出
{
IE1 = 0;
return;
}
/****引导码正确后进入数据的接收****/
for(i=0;i<32;i++)
{
TL = Time(0);
TH = Time(1); //接收0或者1的数据,然后进行时间的判断
if( TL < 300 || TL > 700 || TH < 300 || TH > 1800 ) //高、低电平的时间超过范围的话直接退出
{
IE1 = 0;
return;
}
infvalue >>= 1; //先接收最低位,因此先右移一位再接收
if( TH > 1300 ) //高电平时间大于1300us认为接收的为逻辑1
{
infvalue |= 0x80000000; //接收为1时高位置1,否则仍然为0
}
Flag = 1;
IE1 = 0;
}
}