找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3830|回复: 0
打印 上一主题 下一主题
收起左侧

【原创】部分开源NEC红外遥控解码程序(适合多款单片机)

[复制链接]
跳转到指定楼层
楼主
ID:405708 发表于 2018-10-5 23:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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



评分

参与人数 2黑币 +60 收起 理由
lzh1762 + 10
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表