amigenius 发表于 2014-9-16 09:17:01

发个20多行代码的遥控解码程序,用定时器查询

放在定时器中断中调用,根据定时中断的时间间隔,调整一下#define 的参数就可以用了,够简单了吧


#define      LeadCodeMin                              70               
#define      LeadCodeMax                              130               
#define      OneCodeMin                              12               
#define      OneCodeMax                              25               
#define      ZeroCodeMin                              4               
#define      ZeroCodeMax                              12               

uint8 IR_RecvCt=0;                              // 捕捉数据暂存
uint8 IR_Recv_Step=0;                //接收状态
uint8 IR_Recv_int=0;                //接收到一次有效的遥控指令就置1
uint8 IR_RecvBuf;                //接收到的数据
uint8PulseWidth;                //捕捉到的脉冲宽度
#define IR_RecvCt_Srv(){IR_RecvCt++;if(IR_RecvCt>=250){IR_RecvCt=0;IR_Recv_Step=0;}}
void IR_Recv_Srv(void){                //遥控解码,定时中断
      uint8 i;                                       
      static uint8BitCt=0;      //                //接收位计数器
      static uint8tmpByte=0;                //正在接收的字节
      static uint8 preIRin=1;
      uint8 IRin;
      uint8 IRin_falling=0;
      IR_RecvCt_Srv();
      IRin=IR_INPUT();                //定义您的输入
      if(IRin==0 && preIRin) IRin_falling=1;
      preIRin=IRin;
      if(IRin_falling){
                PulseWidth=IR_RecvCt;IR_RecvCt=0;
                if (IR_Recv_Step==0){BitCt=0;IR_Recv_Step=1;return;}
                if(IR_Recv_Step==1){
                        BitCt=0;
                        if ((PulseWidth<=LeadCodeMax)&&(PulseWidth>=LeadCodeMin)){IR_Recv_Step=2;}
                        return;
                }
                if (IR_Recv_int!=0){IR_Recv_Step=0;return;} //如果主循环还未响应遥控信号,则不接收新的遥控信号
                if(IR_Recv_Step!=2){IR_Recv_Step=0;}
                if (PulseWidth<ZeroCodeMin){IR_Recv_Step=0;return;}      
                if (PulseWidth>=OneCodeMax){IR_Recv_Step=0;return;}
                tmpByte>>=1;
                if (PulseWidth>=OneCodeMin){tmpByte|=0x80;}
                BitCt++;i=BitCt>>3;
                if (((BitCt&0x07)==0)&&(i>0)){IR_RecvBuf=tmpByte;}
                if (BitCt>=(IR_BUF_LEN*8)){BitCt=0;IR_Recv_int=1;IR_Recv_Step=0;}
      }
}

rootxie 发表于 2014-9-16 09:45:55

不错,收下了,感谢分享!

blavy 发表于 2014-9-16 09:46:53

顶一下,上升沿的应该跟这个差不多吧。

zhangyihua 发表于 2014-9-16 09:54:52

把几行代码写成一行了

DiaoMao_Huang 发表于 2014-9-16 10:00:12

前段时间自己写过一个,IO中断+定时器,算出红外码,不过我用了两个资源

qq11qqviki 发表于 2014-9-16 17:20:16

mark{:smile:}

guyue180 发表于 2014-9-16 19:08:15

支持一下。

bysea 发表于 2014-9-17 11:56:49

头像牛逼+10086

minwang440 发表于 2014-9-17 12:06:08

遥控接收信号还没搞懂,学习了

heimareed 发表于 2016-2-14 18:54:46

学习了,谢谢分享!最近在DIY……

ly830102624 发表于 2016-2-15 09:04:33

最近刚好做了一个,学习一下

wofei3344 发表于 2016-2-17 12:26:11

bysea 发表于 2014-9-17 11:56
头像牛逼+10086

头像像是不能说的秘密里的....

风雨无阻88 发表于 2016-4-10 22:29:03

红外的   没有无线的吗

落叶随风 发表于 2016-4-11 08:56:45

我是用外部中断加上定时器的方式,计算脉宽得出红外码,支持重复码

zhanglongbao 发表于 2016-4-11 09:30:33

学习了,谢谢!

ayumi8 发表于 2017-11-19 19:28:14

IR_BUF_LEN是收到数据格式的长度?

IR_INPUT();   是读取IO的状态?

这个适应在多长的定时器中断?  我改过去没反应   

uint8 IR_Recv_int=0;                //接收到一次有效的遥控指令就置1
这个等于 1 的时候 就是收到遥控器按键了?  还是手动置1? 

kebaojun305 发表于 2017-11-21 17:22:06

本帖最后由 kebaojun305 于 2017-11-21 17:24 编辑

一直用定时器定时扫描来解码可以任意IO口解码。顺便定时器可以可以任意口驱动交流蜂鸣器2k4k 。

ayumi8 发表于 2017-11-23 07:41:48

可以用了 很好用不用开外部中断任意io就可以了就是我现在可以用但是我的中断是多久我也不知道   谢谢楼主66666

开始 发表于 2018-6-17 20:59:34

留个脚印

EddieZhu 发表于 2018-7-6 14:17:07

请问一下定时器的中断间隔是多少呢?

zhongsandaoren 发表于 2018-7-6 14:38:46

我去,这都追问了4年了,楼主还是没有回答定时器中断到底是多少?该不会成为永久的迷了吧?{:lol:}{:lol:}

相由心生 发表于 2018-7-7 10:06:33

zhongsandaoren 发表于 2018-7-6 14:38
我去,这都追问了4年了,楼主还是没有回答定时器中断到底是多少?该不会成为永久的迷了吧? ...

何必呢,告诉你吧,一般是100us

3DA502 发表于 2018-7-7 11:08:34

本帖最后由 3DA502 于 2018-7-7 11:19 编辑

我写比lz的更简单{:lol:}
货真价实不到20行



void tm0() interrupt 1 using 1
{
    static WORDhwWaiteCnt;
    static WORDhwTicCnt;
    static WORDhwTicStampPosedge ;
    WORDhwTicStampNegedge;
    WORDhwTicInc;
   
    static BYTE streamBuf;
   
   
    if (--TCNT == 0)
    {
      TCNT = 3;                     //reset send baudrate counter
      if (TING)                     //judge whether sending
      {
            if (TBIT == 0) {
                PinTXB = 0;                //send start bit
                TDAT = TBUF;            //load data from TBUF to TDAT
                TBIT = 9;               //initial send bit number (8 data bits + 1 stop bit)
            } else {
                TDAT >>= 1;             //shift data to CY
                if (--TBIT == 0) {
                  PinTXB = 1;
                  TING = 0;         //stop send
                  TEND = 1;         //set send completed flag
                } else {
                  PinTXB = CY;         //write CY to TX port
                }
            }
      }
    }
   
      
    if(STATE_BLAND == state.stateNum){ /* stop test and waite a time*/
      if(hwWaiteCnt > 0){
            hwWaiteCnt -= 1;
            return;
      }else{
            hwWaiteCnt = BLAND_TICK;
            state.stateNum = STATE_WAITE4_SYNC ;
      }
        }
   
    streamBuf <<= 1;
    streamBuf |= PinRF;         /* bit stream buff*/
   
    hwTicCnt += 1;            /* tick increase */
   
    if(STATE_WAITE4_SYNC == state.stateNum){
                if(streamBuf == 0){
                        state.syncLowCnt += 1;   /* if low , keepcount*/
                        if(state.syncLowCnt > SYNC_LENGTH){ /* if get sync signal*/
                               
                                state.rcvBufIdex = 0; /* reset the buffer index*/
                               
                                state.stateNum = STATE_SAMPLE_START;
                               rcvID.rcvIDlong =0;
                        }
                }else{
                        state.syncLowCnt = 0;      /* reset , if any pulse */
                }
        }
   

    if(STATE_SAMPLE_START == state.stateNum){
          if( streamBuf == 0x01 ){ /* rising edge*/
            hwTicStampPosedge = hwTicCnt;/* sample ticks1*/
                }
                if( streamBuf == 0xfe ){ /* rising edge*/
                        hwTicStampNegedge = hwTicCnt;/* sample ticks2*/
                //        if(hwTicStampNegedge > hwTicStampPosedge){
                       hwTicInc = hwTicStampNegedge - hwTicStampPosedge; /* ignoi a little bug*/
                        //}
                        if(hwTicInc > 0xb0){
                state.rcvBuf = '1';
            }else{
                state.rcvBuf = '0';
            }   
            
                        if(hwTicInc > 0xb0){
                rcvID.rcvIDlong += 1;
            }            
            rcvID.rcvIDlong <<= 1;
                          
                        state.rcvBufIdex += 1;       /* index ++*/
                        if(state.rcvBufIdex >= 23){
                                state.rcvBufIdex = 0;
                state.stateNum = STATE_SEND;
                        }
                }
    }
}
   
   
   

磊磊映画 发表于 2023-11-3 08:56:05

zhongsandaoren 发表于 2018-7-6 14:38
我去,这都追问了4年了,楼主还是没有回答定时器中断到底是多少?该不会成为永久的迷了吧? ...
(引用自21楼)

/*
遥控码由三部分组成
1、leader code 9ms的高电平 + 4.5ms 的低电平
2、系统识别码 区别不同的红外遥控设备
3、操作码 8bit操作码和8bit的操作反码组成

0和1均以0.56ms的低电平开始(实际测量是500us的样子),不同的是后面出现的高电平,
如果高电平是0.56ms(实际测量是500us的样子),则表示0,如果高电平是1.68ms(0.56*3=1.68)则表示1

结束码
高电平超过40ms,然后出现9ms的低电平
连发码 2.1ms的高电平
*/


1码判断范围是4~12 个时间单位   协议要求高电平持续时间是0.56ms实测500us   所以程序中定时器的中断时间应该是100us


页: [1]
查看完整版本: 发个20多行代码的遥控解码程序,用定时器查询