本帖最后由 psuxaog 于 2018-10-5 23:47 编辑
本次开源代码为大批量量产项目中的代码(标准模块),已经在多款国内外产品中使用。移植方便,仅需要处理IO口和提供100微秒中断,10毫秒节拍主循环即可,按键读取等操作直接对接结构体即可,具体请分析源程序。大家可以参考编程思想和代码风格,欢迎批评指正
//remote.c
#include "remote.h"
#define ID_IR_USER 0x06F9
#define REMOTE_KEY_SPEED 0xF0
#define REMOTE_KEY_SETINC 0xF1
#define REMOTE_KEY_MODE 0xF2
#define REMOTE_KEY_SETDEC 0xF3
#define REMOTE_KEY_SET 0xF4
#define REMOTE_KEY_POWER 0xF5
#define REMOTE_KEY_LIGHT 0xF6
#define REMOTE_KEY_WIFI 0xF7
#define REMOTE_KEY_NOPRESS 0
static u8 gCntIrBit = 0;
static bit gFlagIrNow = 0;
static bit gFlagIrPrev = 0;
static u8 gCntFilter = 0;
static u8 gCntIrTime = 0;
static u8 idata gBufIrCode[4] = { 0, 0, 0, 0 };
static u8 idata gBufIrCodeOut[4] = { 0, 0, 0, 0 };
static bit gFlagStart = 0;
static bit gFlagIrHold = 0;
static bit gFlagRecvOk = 0;
REMOTE_StructDef xdata REMOTE_Struct;
bit REMOTE_Action = 0;
void REMOTE_Init(void)
{
u8 *p, i;
p = (u8 *) &REMOTE_Struct;
for (i = 0; i < sizeof(REMOTE_Struct); i++)
{
p = 0;
}
}
void REMOTE_IsrServer(void)
{
u8 tmp = 0;
if (PIN_IR_REC) //检测IO口电平变化
{
if (gCntFilter < 2) //滤波
{
gCntFilter++;
}
else
{
gFlagIrNow = 1; //高电平
}
}
else
{
if (gCntFilter) //滤波
{
gCntFilter--;
}
else
{
gFlagIrNow = 0; //低电平
}
}
if (gFlagIrPrev && (!gFlagIrNow))
{
if ((gCntIrTime > 125) && gCntIrTime < (145))
{
gCntIrBit = 0;
gFlagStart = 1;
}
else if (!gFlagStart)
{
if ((gCntIrTime > 105) && (gCntIrTime < 125))
{
gFlagIrHold = 1;
}
}
else
{
if ((gCntIrTime < 5) || (gCntIrTime > 30))
{
gFlagStart = 0;
}
else
{
tmp = gCntIrBit >> 3;
gBufIrCode[tmp] >>= 1;
if (gCntIrTime > (1680 / 100))
{
gBufIrCode[tmp] |= 0x80;
}
else
{
gBufIrCode[tmp] &= ~0x80;
}
gCntIrBit++;
if (gCntIrBit >= 32)
{
if (!gFlagRecvOk)
{
gFlagRecvOk = 1;
gBufIrCodeOut[0] = gBufIrCode[0];
gBufIrCodeOut[1] = gBufIrCode[1];
gBufIrCodeOut[2] = gBufIrCode[2];
gBufIrCodeOut[3] = gBufIrCode[3];
}
gFlagStart = 0;
}
}
}
gCntIrTime = 0;
}
else
{
if (gCntIrTime < 255)
{
gCntIrTime++;
}
}
gFlagIrPrev = gFlagIrNow;
}
void REMOTE_Server(void)
{
static u16 idata dlyLong = 0;
static u16 idata dlyLongLim = 0;
static u16 idata dlyReleased = 0;
static u8 keyReleased = 0;
static u8 keyOut = 0;
static u8 keyLong = 0;
bit flagLong3s = 0;
bit flagLong5s = 0;
bit flagReleased = 0;
bit flagAction = 0;
if (gFlagRecvOk)
{
if ((gBufIrCodeOut[2] == ~gBufIrCodeOut[3])
&& (gBufIrCodeOut[0] == (ID_IR_USER / 256))
&& (gBufIrCodeOut[1] == (ID_IR_USER % 256)))
{
keyOut = gBufIrCodeOut[2];
keyLong = keyOut;
keyReleased = keyOut;
dlyLong = 0;
dlyLongLim = 0;
dlyReleased = 0;
flagAction = 1;
}
gFlagRecvOk = 0;
}
if (dlyLongLim < 65530)
{
dlyLongLim++;
}
if (dlyLongLim == 300)
{
if (dlyLong > 20)
{
flagLong3s = 1;
dlyLong = 0;
keyOut = keyLong;
// keyLong = REMOTE_KEY_NOPRESS;
keyReleased = 0;
}
}
if (dlyLongLim == 500)
{
dlyLongLim = 0;
if (dlyLong > 10)
{
flagLong5s = 1;
dlyLong = 0;
keyOut = keyLong;
keyLong = REMOTE_KEY_NOPRESS;
keyReleased = 0;
}
}
if (keyReleased)
{
dlyReleased++;
if (dlyReleased > 15)
{
dlyReleased = 0;
keyOut = keyReleased;
flagReleased = 1;
keyReleased = 0;
}
}
if (gFlagIrHold)
{
gFlagIrHold = 0;
if (dlyLong < 65530)
{
dlyLong++;
}
dlyReleased = 0;
}
if (REMOTE_Struct.HasAction)
{
if (flagAction)
{
flagAction = 0;
REMOTE_Struct.Activated = 1;
}
if (flagLong3s || flagReleased)
{
REMOTE_Struct.HasAction = 0;
}
keyOut = REMOTE_KEY_NOPRESS;
return;
}
flagAction = 0;
if (keyOut != REMOTE_KEY_NOPRESS)
{
switch (keyOut)
{
case REMOTE_KEY_MODE:
if (flagLong3s)
{
REMOTE_Struct.Value = REMOTE_KeyDispTemp;
}
else if (flagReleased)
{
REMOTE_Struct.Value = REMOTE_KeyMode;
}
break;
case REMOTE_KEY_SPEED:
if ((!flagReleased) && (!flagLong3s) && (!flagLong5s))
{
REMOTE_Struct.Value = REMOTE_KeySpeed;
}
break;
case REMOTE_KEY_LIGHT:
if (flagLong5s)
{
REMOTE_Struct.Value = REMOTE_KeyLock;
}
else if (flagReleased)
{
REMOTE_Struct.Value = REMOTE_KeyLight;
}
break;
case REMOTE_KEY_POWER:
if ((!flagReleased) && (!flagLong3s) && (!flagLong5s))
{
REMOTE_Struct.Value = REMOTE_KeyPower;
}
if (flagLong3s)
{
REMOTE_Struct.Value = REMOTE_KeyPowerLong;
}
break;
case REMOTE_KEY_SETINC:
if ((!flagReleased) && (!flagLong3s) && (!flagLong5s))
{
REMOTE_Struct.Value = REMOTE_KeySetInc;
}
break;
case REMOTE_KEY_SETDEC:
if ((!flagReleased) && (!flagLong3s) && (!flagLong5s))
{
REMOTE_Struct.Value = REMOTE_KeySetDec;
}
break;
case REMOTE_KEY_WIFI:
if (flagLong5s)
{
REMOTE_Struct.Value = REMOTE_KeyWifi;
}
break;
case REMOTE_KEY_SET:
if (flagLong5s)
{
REMOTE_Struct.Value = REMOTE_KeySet;
}
else if (flagReleased)
{
REMOTE_Struct.Value = REMOTE_KeySetOK;
}
break;
}
}
keyOut = REMOTE_KEY_NOPRESS;
flagLong3s = 0;
flagLong5s = 0;
flagReleased = 0;
}
//remote.h
#ifndef __REMOTE_H__
#define __REMOTE_H__
#include "global.h"
typedef enum
{
REMOTE_KeyNoPress = 0,
REMOTE_KeyPower = 1,
REMOTE_KeySetInc = 2,
REMOTE_KeySetDec = 3,
REMOTE_KeyLight = 4,
REMOTE_KeyMode = 5,
REMOTE_KeySpeed = 6,
REMOTE_KeyWifi = 7,
REMOTE_KeyLock = 8,
REMOTE_KeyDispTemp = 9,
REMOTE_KeySet = 10,
REMOTE_KeySetOK = 11,
REMOTE_KeyPowerLong = 12,
} REMOTE_KeyEnumDef;
typedef struct
{
REMOTE_KeyEnumDef Value; //按键键值
u8 HasAction :1;
u8 Activated :1;
} REMOTE_StructDef;
extern REMOTE_StructDef xdata REMOTE_Struct; //程序接口
extern void REMOTE_Init(void); //初始化
extern void REMOTE_IsrServer(void); //定时器中断中调用的程序100微秒调用一次
extern void REMOTE_Server(void); //主循环,10毫秒调用一次
#endif
|