打印

STM8红外遥控解码,有做过的吗

[复制链接]
8238|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
//#################################################################################################
//?
//PC=8LED
//PD4=JR_IN
//NEC协议、PC838红外接收头
//#################################################################################################
#include"STM8S103F.h"
#define uchar unsigned char
#define uint  unsigned int
#define PD5  PD_ODR

#define Sys_Time 13 //14*4us = 56us
#define Sys_Prescaler 1   //2^1 = 2
#define IrIn_PIN() (PD_IDR=0x10)   //红外输入端口
uchar IrRecStep = 0;                  //接收步骤
uchar IrRecCnt = 0;                   //接收时间计数
uchar IrIndex = 0;                    //接收位数
uchar IrRecFlag = 0;                  //接收完标志
uchar IrRecBuff[4];                   //接收缓冲区
uchar IrRecAddr1;                     //红外地址码
uchar IrRecAddr2;
uchar IrRecData1;                     //红外数据码
uchar IrRecData2;
const uchar IrCode[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};


//延时程序
void Delay_ms( uint ms )
{
  uint i,j;
  for( j=0; j < ms; j++ )
  {
    for( i=0; i > 1000; i++ )
    {;}
  }
}

//红外接收端口初始化
void Ir_Init(void)
{
  PD_DDR = 0x20;       //PD2为中断悬浮输入
  PD_CR1 = 0x21;       //PD5为LED 输出指示
  PD_CR2 = 0x00;
}

//红外接收程序
void Ir_Receive(void)
{
  switch(IrRecStep)
  {
  case 0:
          IrIndex = 0;                   //接收位数
          if(!IrIn_PIN())                //检测低电平
          {
            IrRecCnt ++;                 //接收时间计数
          }
          else
          {
            if((IrRecCnt>=155)&&(IrRecCnt<=165)) // 码头低电平时间9ms
            {
              IrRecCnt = 1;
              IrRecStep ++;
              IrRecBuff[0] = 0;
              IrRecBuff[1] = 0;
              IrRecBuff[2] = 0;
              IrRecBuff[3] = 0;
            }
            else
            {
              IrRecCnt = 0;
              IrRecStep = 0;
            }
          }
          break;
  case 1:
          if(IrIn_PIN())
          {
            IrRecCnt ++;
            if(IrRecCnt >= 100)   //高电平时间过长,退出
            {
              IrRecCnt = 0;
              IrRecStep = 0;
            }
          }
          else
          {
            if((IrRecCnt>=75)&&(IrRecCnt<=85))   // 码头高电平时间4.5ms
            {
              IrRecCnt = 1;
              IrRecStep = 2;
            }
            else
            {
              IrRecCnt =0;
              IrRecStep = 0;
            }
          }
          break;
  case 2:
          if(!IrIn_PIN())
          {
            IrRecCnt ++;
            if(IrRecCnt > 30)            //低电平时间过长,退出
            {
              IrRecCnt = 0;
              IrRecStep = 0;
            }
          }
          else
          {
            if((IrRecCnt >= 8)&&(IrRecCnt <= 12)) //每位开头0.56ms低电平
            {
              IrRecCnt = 1;
              IrRecStep = 3;
            }
            else
            {
              IrRecCnt = 0;
              IrRecStep = 0;
            }
          }
          break;
  case 3:      
          if(IrIn_PIN())
          {
            IrRecCnt ++;
          }
          else
          {
            if((IrRecCnt >= 25)&&(IrRecCnt <= 35))  //高电平时间约为1.68ms,则为数据1
            {
              IrRecBuff[IrIndex >> 3] |= IrCode[IrIndex & 0x07]; //相应位置1
              IrRecCnt = 1;
              IrIndex ++;
              IrRecStep = 2;
            }
            else if((IrRecCnt >= 8)&&(IrRecCnt <= 12))//高电平时间约为0.56ms,则为数据0
            {
              IrRecCnt = 1;
              IrIndex ++;
              IrRecStep = 2;
            }
            else
            {
              IrRecStep = 0;     //退出
              IrRecCnt = 0;
            }
            if(IrIndex >= 32)    //是否接收完32位
            {
              IrRecStep = 0;
              IrRecFlag = 1;
            }
          }
          break;
  }
}
      

/*
;================================
;******  红外遥控器键值表  ******

  遥控按键:CH-   CH   CH+  |<<   >>|   >|    -    +    EQ    0   100+   200+
         键值    :45H  46H   47H  44H   40H  43H   07H  15H   09H  16H  19H    0DH  
        遥控按键:1    2    3    4    5    6    7    8    9
            键值:0CH  18H  5EH  08H  1CH  5AH  42H  52H  4AH
         
;================================  */


//改变PWM占空比
/*
;================================
;******  红外遥控器键******

  遥控按键:   -    +    //两个按键改变PWM占空比  
         键值    :  07H  15H  
        遥控按键:1    2    3    4    5    6    7    8    9//九个鞍醇谢欢嘀只ㄑ?
            键值:0CH  18H  5EH  08H  1CH  5AH  42H  52H  4AH
         
;================================  */

void Ir_PWM_change(void)
        {
                uchar PWM_value=0;
                //PWM_value=IrRecData1 & 0x0F;     //取键码的低四位
                if(IrRecData1==0x07)
                   PWM_value++;
                else if (IrRecData1==0x15)
                         PWM_value--;
                PD5=0x20;
        }

//切换显示模式
void Ir_mode_change(void)
        {
                uchar mode_value=0;
        if(IrRecData1==0x0C) mode_value=1;
        else if (IrRecData1==0x18) mode_value=2;        
        else if (IrRecData1==0x5E) mode_value=3;
  else if (IrRecData1==0x08) mode_value=4;
  else if (IrRecData1==0x1C) mode_value=5;
        else if (IrRecData1==0x5A) mode_value=6;
  else if (IrRecData1==0x42) mode_value=7;
        else if (IrRecData1==0x52) mode_value=8;
        else if (IrRecData1==0x4A) mode_value=9;
        }



//时钟初始化
void CLK_Init(void)
{
  CLK_ICKR=0x03;//内部时钟寄存器 内部时钟准备就绪,外部时钟开
  CLK_SWCR=0x02;//切换控制寄存器 使能切换机制
  CLK_SWR=0xE1;//主时钟切换寄存器 选择HSI为主时钟源*/

  while (!(CLK_SWCR & 0x08));  
  CLK_CSSR=0x01;//时钟安全系统寄存器   
}
//定时器4初始化,56us中断一次
void SysClk_Init(void)
{
  _asm("sim");
  TIM4_IER = 0x00; //禁止中断
  TIM4_EGR = 0x01; //允许产生更新事件
  TIM4_PSCR = Sys_Prescaler;
  TIM4_ARR = Sys_Time;
  //TIM4_CNTR = Sys_Time;
  TIM4_CR1 = 0x01;
  TIM4_IER = 0x01;
  _asm("rim");
}
//TIM4中断入口
@far @interrupt void TIM4_UPD_OVF_IRQHandler (void)
{
  TIM4_SR = 0x00;
  Ir_Receive();
}

//初始化
void Devices_Init(void)
{
  Delay_ms(200);
  CLK_Init();
  Ir_Init();
  SysClk_Init();
}

//主程序
void main( void )
{
  Devices_Init();
  while(1)
  {
    if(IrRecFlag == 1)
    {
      IrRecAddr1 = IrRecBuff[0];
      IrRecAddr2 = IrRecBuff[1];
      IrRecData1 = IrRecBuff[2];
      IrRecData2 = IrRecBuff[3];
      IrRecFlag = 0;
    }
  
            Ir_PWM_change();
                        Ir_mode_change();
        }
}



有问题,求高手帮忙指正问题
沙发
bpshui| | 2013-5-2 17:07 | 只看该作者
有什么问题说清楚,贴这么代码没鸟用的。

使用特权

评论回复
板凳
cjhk| | 2013-5-2 18:46 | 只看该作者
把问题讲清楚   感觉没人会看你的代码   直接说问题

使用特权

评论回复
地板
20091613310050|  楼主 | 2013-5-2 21:49 | 只看该作者
我想把红外遥控器按键对应的键值存到一个数组中,然后通过数码管显示出来,能给些指导吗

使用特权

评论回复
5
20091613310050|  楼主 | 2013-5-2 21:51 | 只看该作者
Ir_PWM_change(void)
Ir_mode_change(void)
这两个函数是没用的。

使用特权

评论回复
6
oldzhang| | 2013-7-6 16:49 | 只看该作者
用这个工具试试,我编写了,很简单,没这么发杂,从前面的9ms低电平,4.5ms高电平的波头后面,识别32位高电平长度就行,短的为0,长的位1
前面16位是用户码正码反码,后面16位为你需要的8正码和8位反码。附件为软件测量长度的工具。

IF_Read.rar

746 Bytes

使用特权

评论回复
7
oldzhang| | 2013-7-6 16:55 | 只看该作者
这类都是NEC编码,PWM码,靠接收头输出的高电平长度区分0,1,短的0,长的1,短的0.56ms,长的1.68ms,很好区分的,
自己好好琢磨一下,程序很好编的,可以用我上传的工具的思想编写的。

使用特权

评论回复
8
oldzhang| | 2013-7-6 17:02 | 只看该作者
上传的是NEC红外遥控编码的图

nec_IFR.jpg (74.09 KB )

nec_IFR.jpg

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

27

帖子

0

粉丝