查看: 1367|回复: 0
打印 上一主题 下一主题

STM8 红外解码程序--使用外部中断和定时器

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-13 20:07:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
*********************************************************************************************************
*
*        模块名称 : 红外遥控解码
*
   引导码   地址码   地址反码   数据码  数据反码
\ 9+4.5ms \ c0-c07 \ c0-c07 \ c0-c07 \ c0-c07 \
*********************************************************************************************************
*/
#include "Ir_decode.h"


u8 Ir_Status=0;                 //红外接收处理状态
u8  Ir_Receive_Count=0;         //红外接收数据位计数
u32 Ir_Receive_Data=0;          //32位的红外接收数据
u8 Ir_receive_ok=0;             //红外接收完成标志


void TIM2_Config(void)
{
  TIM2_DeInit();

  TIM2_TimeBaseInit(TIM2_PRESCALER_16, 60000);//定时器设置1M的计数频率,1US的分辨率
  
  TIM2_ClearFlag(TIM2_FLAG_UPDATE);

  /* Enable update interrupt (使能更新中断)*/
  TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);

  /* Disable TIM2 */
  TIM2_Cmd(DISABLE);
}
/*
********************************************************************************
            定时器溢出中断内处理
********************************************************************************
*/
void TIM_IT_Updata_Handdle(void)
{
   Ir_Status=0;
    TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
    TIM2_SetCounter(0);
    TIM2_Cmd(DISABLE);
}
/*
********************************************************************************
                          红外解码初始化函数
********************************************************************************
*/
void Ir_Init(void)
{
  GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_IT);                      //配置引脚上拉中断输入
  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);//下降沿中断

  TIM2_Config();
}


/*
********************************************************************************
                          红外接收数据处理函数
********************************************************************************
*/
u8 Ir_Process(void)
{
  u8 Ir_num=0;                  //最终处理后的键值返回值
  u8 Address_H,Address_L;       //地址码,地址反码
  u8 Data_H,Data_L;             //数据码,数据反码
  
  if(Ir_receive_ok==1)          //接收完成
    {
          Address_H=Ir_Receive_Data>>24;                //得到地址码
          Address_L=(Ir_Receive_Data>>16)&0xff;                //得到地址反码
          //if((Address_H==(u8)~Address_L)&&(Address_H==REMOTE_ID))//检验遥控识别码(ID)及地址
          if((Address_H==(u8)~Address_L))//检验遥控识别码(ID)及地址
            {
                printf("\r\n %d",Address_H);
                Data_H=Ir_Receive_Data>>8;              //得到数据码
                Data_L=Ir_Receive_Data;                 //得到数据反码
                if(Data_H==(u8)~Data_L)                 //接收数据码正确
                  {
                    Ir_num=Data_H;                      //正确键值
                    Ir_receive_ok=0;
                    printf("\r\n %d",Ir_num);
                  }
            }
     
    }
   return  Ir_num;      //返回键值
}

/*
********************************************************************************
                          红外接收中断处理函数
********************************************************************************
*/
void Ir_Receive_Handle(void)
{
  u16 Interval_tim=0;//两个下降沿间隔时间
  
  switch(Ir_Status)
    {
    case 0://第一个下降沿,定时器开始计数
            Ir_Status=1;
            TIM2_Cmd(ENABLE);                   //Enable TIM2
            TIM2_SetCounter(0);                 //定时器计数值清零
            break;
    case 1://第二个下降沿,定时器关闭,读取定时器计数值
            TIM2_Cmd(DISABLE);
            Interval_tim=0;
            Interval_tim=TIM2_GetCounter();     //读取定时器计数值
            TIM2_SetCounter(0);                 //定时器计数值清零
            TIM2_Cmd(ENABLE);                   //Enable TIM2
            if( (Interval_tim>=12500)&&(Interval_tim<=14500) )//判断引导码是否正确9+4.5ms
              {
                Ir_Status=2;                    //进入下一状态
               
              }
            else                                //引导码错误,从新接收
              {
                Ir_Status=0;
                Ir_Receive_Count=0;
              }
            break;
    case 2://进入32位数据接收
            TIM2_Cmd(DISABLE);
            Interval_tim=0;
            Interval_tim=TIM2_GetCounter();
            TIM2_SetCounter(0);
            TIM2_Cmd(ENABLE); //Enable TIM2
            if(Ir_Receive_Count<32)
              {
                if( (Interval_tim>=1000)&&(Interval_tim<=1300) )        //间隔1.12ms ->0
                  {
                    Ir_Receive_Data=Ir_Receive_Data<<1;
                    Ir_Receive_Count++;
                  }
                else if( (Interval_tim>=2000)&&(Interval_tim<=2600) )   //间隔2.25ms ->1
                        {
                          Ir_Receive_Data=Ir_Receive_Data<<1;
                          Ir_Receive_Data=Ir_Receive_Data|0x0001;
                          Ir_Receive_Count++;
                        }
                      else//不是0,1 接收错误,从新接收
                        {
                          Ir_Status=0;
                          Ir_Receive_Data=0;
                          Ir_Receive_Count=0;
                        }
                      break;  
              }
            else//超出接收数据位数,接收下一个
              {
                Ir_receive_ok=1;//红外接收完成
                Ir_Status=0;
                Ir_Receive_Count=0;
                break;
              }
            
            
            break;
    default :
            break;
    }
}




/*
*********************************************************************************************************
*
*        模块名称 : 红外遥控解码
*
*********************************************************************************************************
*/

#ifndef __Ir_decode_H
#define __Ir_decode_H

#include "stm8s.h"
#include "uart.h"


//红外遥控识别码(ID)

#define REMOTE_ID 0                     
        

extern u8 Ir_Status;
extern u8  Ir_Receive_Count;
extern u8 Ir_receive_ok;
extern u32 Ir_Receive_Data;


u8 Remote_Scan(void);
void Ir_Init(void);
u8 Ir_Process(void);
void Ir_Receive_Handle(void);
void TIM_IT_Updata_Handdle(void);

#endif



******************************************************************************
stm8s_it.c
******************************************************************************
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
  Ir_Receive_Handle();
  
}

INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{        
   TIM_IT_Updata_Handdle();
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

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