📄 ir_key.c
字号:
/*************************************************************************
** 红外遥控器解码程序(采用中断)----基于SM0038接收芯片
**说明:采用P2.0口中断,可通过修改IR_IN和P2来切换中断口的选择.
**使用方法: 当IR_FLAG==1时,表示有键按下,全局变量IR_KeyValue是键号.
** IR_KeyValueN--按键非码;IR_KeyValueSB--遥控器识别码
** IR_UK--用户自定义的键号
** 使用此模块时应先执行 IR_Init()
**使用示例: if(IR_FLAG==1)
** {
** IR_FLAG=0;//每次使用时须将标志位清零.
** Display_Int(IR_KeyValue,0x90);
** }
*************************************************************************/
#include "ir_key.h"
#include "delay.h"
/**********************以下是本程序中使用到的全局变量********************/
unsigned char IR_BitCnt=0;
unsigned char IR_KeyValue=10; //按键码(始值不能为按键号中包含的值)
unsigned char IR_UK=0; //用户定义的键号
unsigned char IR_KeyValueN=0; //按键非码;按键码+按键非码=0xff
long int IR_KeyValueSB=0; //遥控器识别码.
unsigned char IR_FLAG = 0; //有键按下时此标志为1
/*****************************************************************************
**此结构休是为键号转换用,IR_KV为遥控器本身的键号,IR_UK为用户自定义的按键号
*****************************************************************************/
struct IR_KEY
{
unsigned char IR_KV;//遥控器自身键码
unsigned char IR_UV;//user's value
};
/*****************************************************************************
**通过修改结构体数组中的值来设定遥控器的键号.
*******************************************************************************/
struct IR_KEY IR_UserKEY[IR_NUM]=
{
{68,1},{71,2},{14,3},{72,4},{73,5},{81,6},{10,7},{80,8},{74,9},{83,10},
{18,11},{84,12},{78,13},{75,14},{3,15},{21,16},{86,17},{67,18},{2,19},{76,20},
{82,21},{79,22},{70,23},{77,24},{69,25},{6,26},{66,27},{65,28},{64,29},{22,30},
{85,31},{23,32},{9,33},{13,34},{87,35},{15,36},{8,37},{25,38},{24,39},{11,40},
{0,41},{4,42},{16,43},{19,44},{5,45},{1,46},{17,47},{95,48},{94,49},{30,50},{26,51}
};
/*************************************************************************
**函数名称: IR_DELAY
**功能描述: 用于延时.
**调用模块: delay.h
**全局变量: 无
****************************************************************************/
void IR_DELAY(unsigned int delayTime)
{
DELAY(delayTime);//延时8MS
}
/*************************************************************************
**函数名称: IR_Init
**功能描述: 端口初始化设置,在main函数里面应先执行此函数
**输入变量:无
**返回值:无
**调用模块:无
**全局变量: IR_IN
****************************************************************************/
void IR_Init(void)
{
P2DIR &=~IR_IN; //端口设置为输入方向
P2IE |= IR_IN; //使能中断
P2IES |= IR_IN; //下降沿中断
P2IFG &=~IR_IN; //为避免程序运行后直接进中断,此处需先将中断标志位清零
_EINT();
}
/*************************************************************************
**函数名称: IR_getkey
**功能描述: 读取遥控器键值,包括识别码,非码
**输入变量: 无
**返回值: 无
**调用模块: IR_DELAY();
**全局变量: IR_Delay_8MS,IR_Delay8MS,IR_IN
****************************************************************************/
void IR_getkey(void)
{
P2IFG &=~IR_IN;
P2IE &=~IR_IN;
/**********以下是判断中断是由按键引起的***************/
IR_DELAY(IR_Delay_8MS); //延时0.8MS
if(P2IN & IR_IN) goto IR_NXT;
IR_DELAY(IR_Delay8MS); //延时8MS
if(!(P2IN & BIT0)) goto IR_NXT;
while(!(P2IN & IR_IN));//等待变高
IR_DELAY(8900); //延时5MS左右
if(P2IN & IR_IN) goto IR_NXT;
IR_FLAG = 0;
/********以下是读取16位识别码*******************/
IR_KeyValueSB=0;
for(IR_BitCnt=0;IR_BitCnt<16;IR_BitCnt++)
{
while(!(P2IN & IR_IN));//WAIT HIGH
IR_KeyValueSB >>=1;
IR_DELAY(IR_Delay_8MS);
if(P2IN & IR_IN)
IR_KeyValueSB |=0x80;
else
IR_KeyValueSB &=0x7f;
while(P2IN & IR_IN);//WAIT LOW
}
/***********以下是读取8位的键码*******************/
IR_KeyValue=0;
for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)
{
while(!(P2IN & IR_IN));//WAIT HIGH
IR_KeyValue >>=1;
IR_DELAY(IR_Delay_8MS);
if(P2IN & IR_IN)
IR_KeyValue |=0x80;
else
IR_KeyValue &=0x7f;
while(P2IN & IR_IN);//WAIT LOW
}
/************以下是读取8位的非码****************/
IR_KeyValueN=0;
for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)
{
while(!(P2IN & IR_IN));//WAIT HIGH
IR_KeyValueN >>=1;
IR_DELAY(IR_Delay_8MS);
if(P2IN & IR_IN)
IR_KeyValueN |=0x80;
else
IR_KeyValueN &=0x7f;
while(P2IN & IR_IN);//WAIT LOW
}
for(unsigned char i=0;i<20;i++)
IR_DELAY(IR_Delay8MS);
IR_NXT:P2IFG &=~IR_IN;
P2IE |=IR_IN;
IR_FLAG=1;
}
/*************************************************************************
**函数名称: IR_getUK
**功能描述: 根据得到的IR_KeyValue从IR_UserKEY表中查出对应的用户自定义的键值
**输入变量: 无
**返回值: 无
**调用模块: 无
**全局变量: IR_BitCnt,IR_NUM,IR_UserKEY,IR_KeyValue,IR_UK
****************************************************************************/
void IR_getUK(void)
{
for(IR_BitCnt=0;IR_BitCnt<IR_NUM;IR_BitCnt++)
{
if(IR_KeyValue==IR_UserKEY[IR_BitCnt].IR_KV)
{
IR_UK= IR_UserKEY[IR_BitCnt].IR_UV;
return;
}
}
if(IR_BitCnt==IR_NUM)
IR_UK=0;
}
/****************************************************************************
**以下是SM0038输入信号引脚的中断函数.
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -