STM8 捕获模式HS0038 红外遥控解码

123

 

天热了坐着就不站着、躺着就不坐着,风扇手动换挡简直很要命,某宝买了一个遥控改装后按键失去作用了很不爽,于是自己换芯片改装呗,第一次做红外遥控不知所措,百度一堆解码过程最多的就是使用定时器判断解码 ,后来找到一种简单的解码就是通过PWM输入捕获,判断两个下降沿的宽度完成解码,标准NEC协议则是 同步(9+4.5ms) 、数据1 (2.25ms),数据 0(1.12ms),具体可参考协议。

于是开搞了 第一次用了PIC16F616 做完发现芯片内存不够,于是转STM8S003 ,记录一下调试代码:

方法则是采用TIM1 捕获信号的下降沿 ,TIM2 则记录输入空闲时间 ,当超过设定空闲时间后认为当前帧已经结束了(有的遥控发出的信息会多2bit ,至今不明原因所以采用此方法)

#include "time.h"
#include "iostm8s003f3.h"
#include "sys.h"

#define      CAPSIZEMAX         100
uint16_t captureint[CAPSIZEMAX]={0}; 
uint8_t  capcount =0;
uint8_t  lastcapcount =0;
uint16_t caplasttiak =0;

void time_s_init(void)//tim2
{
  TIM2_IER = 0x00;
 //分频值(1024分频)16MHZ / 1024 = 15,625HZ,fCK_CNT =fCK_PSC / 2 ^(PSCR[3:0])
  TIM2_PSCR =0xf;//15 ,16Mhz /32768 =?488.28125? hz = 2.048ms
  // 最大计数时间 :2.048ms *65536 =134.217秒
  TIM2_CNTRH =0;
  TIM2_CNTRL=0;
  TIM2_CR1 |= 0x01;//enable timer2
  TIM2_SR1 = 0; // 清除更新中断   
}
void Timer1CaptureInit(void)
{
  TIM1_CNTRH = 0x00;//清零计数器高8位
  TIM1_CNTRL = 0x00;//清零计数器低8位
  //计数器的时钟频率(fCK_CNT)等于fCK_PSC/( PSCR[15:0]+1)
  //16Mhz / =16 =1Mhz =1us
  TIM1_PSCRH = 0x00;//计数器时钟分频高8位
  TIM1_PSCRL = 0x0F;//计数器时钟分频低8位15+1分频
  TIM1_CCER2 &= (unsigned char)~0x01;//清零TIM1_CCER3中的CC3E位,之后才可配置TIM1_CCMR3
  TIM1_CCMR3 = 0x01;//配置TIM1_CCMR3中的CC1S位为1,CC3通道配置为输入,IC3映射到TI3FP1上
  //无滤波器、无预分频器(捕获输入口上检测到的每一个边沿都触发一次捕获)
  TIM1_CCER2 |= 0x02;//下降沿触发
  TIM1_IER |= 0x08;//CC3IE=1,使能捕获/比较3中断
  TIM1_CCER2 |= 0x01;//捕获使能
  TIM1_CR1 |= 0x01;//使能定时/计数器
}
//软件解码
#define		SYNC_L		(13558-200)//13558
#define		SYNC_H		(13558+200)
#define		LOW_L		(1135-200)
#define		LOW_H		(1135+200)//1135
#define		HIGH_L		(2243-200)
#define		HIGH_H		(2243+200)//2243
uint8_t IRDACMD(uint8_t *ret)
{
	uint8_t tempbuf[4]={0};
	uint8_t i,j,retv=0;
	uint16_t det,CUR;
        uint16_t *src=captureint;
        if(lastcapcount!=capcount)//收到数据。。
        {
          CUR =TIM2_CNTRH;
          CUR<<=8;
          CUR|=TIM2_CNTRL;//得到现在时间 
          det = (CUR>caplasttiak)?(CUR-caplasttiak):\
            (0xffff-caplasttiak+CUR+1);
          if(det>=50)//50*2.048ms = 102.4ms超时时间,认定当前帧接收完毕
          {
            if(capcount<34)//数据帧失效
            {
              goto errto;
            }
          }
          else
          {
            return 0;//继续接收
          }
        }
        else //未接收到数据
        {
          return 1;
        }
        det =(src[1]>=src[0])?(src[1]-src[0]):(0xffff-src[0]+src[1]+1);//计算控制周期
        if((det>SYNC_L)&&(det<SYNC_H)){;}// 同步头 (13.655667ms) /0.001ms = 13,655.667  
        else{ goto errto;}
        src++;
        for(i=0;i<4;i++)//包含4个数据
        {
          tempbuf[i]=0;//clear
          for(j=0;j<8;j++)// 8bit
          {
              det =(src[1]>=src[0])?(src[1]-src[0]):(0xffff-src[0]+src[1]+1);//计算控制周期
              src++;
              if((det>LOW_L)&&(det<LOW_H)){;} //0 逻辑:1.143917ms /0.001ms =1,143.917
              else if((det>HIGH_L)&&(det<HIGH_H))//1逻辑:2.259583ms/0.001ms =2,259.583
              {
                    tempbuf[i]|=(1<<j); //低位在前,
              }
              else {retv =1;goto errto;}
          }
        }
        ret[0] =tempbuf[0]; ret[1] =tempbuf[2];
        retv= 0x80;  
errto:
      capcount =0;
      lastcapcount=capcount;//失效
      return retv;
}
#pragma vector=TIM1_CAPCOM_CC3IF_vector//TIM1CA3
__interrupt void TIM1_CAPCOM_CC3IF(void)//  捕获
{
  captureint[capcount] =TIM1_CCR3H;
  captureint[capcount]<<=8;
  captureint[capcount]|=TIM1_CCR3L;
  caplasttiak = TIM2_CNTRH;//当前计数器tim2
  caplasttiak<<=8;
  caplasttiak|=TIM2_CNTRL;
  if(++capcount>=CAPSIZEMAX){capcount=0;}
  TIM1_SR1 &= (unsigned char)~0x08;//清除CC3IF标志
return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值