OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5560|回复: 27

跪求红外接收模块,不占用整个定时器,不用外部中断下降沿触发~~~

[复制链接]

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
发表于 2017-7-20 15:58:24 | 显示全部楼层 |阅读模式
7金钱
不用外部中断下降沿触发方式和不占用整个定时器,就普通的IO实现红外接收;我自己写了个,但是到了最后,不行不知道为什么,求大神给个好的红外接收模块,在下谢谢了~~~

if(IRIN == 0)  //引导码低电平
        {

                r_LC_L++;                       
                if(r_LC_L >= 34&&r_LC_L <= 38)     
                {
                        b_IR_flag = 1;
                }
                else
                {
                        b_IR_flag = 0;
                }
        }
        if(b_IR_flag)
        {
                if(IRIN == 1)  //引导码高电平
                {
                        r_LC_H++;
                        if(r_LC_H >= 16&&r_LC_H <= 20)  
                        {
                                b_IR_flag1 = 1;
                        }
                        else
                        {
                                b_IR_flag1 = 0;
                        }
                }
        }
        if(b_IR_flag1)
        {
                for(i = 0;i < 4;i++)
                {
                        for(j = 0;j < 8;j++)
                        {
                                value = value >> 1;
                                while(!IRIN)   //数据码低电平,位0和位1相同的部分
                                {
                                        r_CD_L++;
                                }
                                if(r_CD_L >= 420&&r_CD_L <= 620)
                                {
                                        while(IRIN)      //数据码高电平,位0和位1区别的部分        
                                        {
                                                r_CD_H++;
                                        }
                                        if(r_CD_H >= 420&&r_CD_H <= 620)    //在这范围是位0
                                        {
                                                value &= 0x7f;
                                        }
                                        else if(r_CD_H >= 1600&&r_CD_H <= 1800)   //在这范围是位1
                                        {
                                                value |= 0x80;
                                        }
                                }
                        }
                        IR_Value[i] = value;       
                }
               
                if(IR_Value[2] = ~IR_Value[3])          //数据码的前面和后面相等时,表示解码完成                      
                {
                        b_IR_ok = 1;
                }
        }


最佳答案

查看完整内容[请看2#楼]

已经最近写出来了,谢谢大家
我是小白,很白很白的小白!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-20 15:58:25 | 显示全部楼层
已经最近写出来了,谢谢大家
我是小白,很白很白的小白!!!
回复

使用道具 举报

11

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2015-1-8
在线时间
46 小时
发表于 2017-7-20 18:03:33 | 显示全部楼层
       
        if(TIM_GetITStatus(TIM2, TIM_IT_Update))          // &#197;D&#182;&#207;·¢éúupdateê&#194;&#188;t&#214;D&#182;&#207;
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);     // &#199;&#229;3yupdateê&#194;&#188;t&#214;D&#182;&#207;±ê&#214;&#190;
                /******************************EVENT START*******************************/

                        /*--------------------------&#209;óê±&#191;&#216;&#214;&#198;---------------------------*/
               
                                       
                                        ant_r1 =GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_7);       
                                        if(ant_r1 ==0)                     //
                                {                  
                                        if(ant_start < 0xff)
                                          ant_start++;
                                        if(ant_start >83 && ant_start<100 )
                                  {                                  
                                        ant_l = 0;
                                        ant_h = 0;
                                        skip_nu= 0;
                                       
                                  }
                                       
                                }
                                        else
                                {
                                        ant_start =0;       
                                       
                                }
                                       
                                        switch(skip_nu)
                                {
                                case 0:
                                                if(ant_start > 83 && ant_start<100)     //9ms òyμ&#188;&#194;&#235;
                                        {
                                                ant_l = 0;
                                                ant_h = 0;
                                          skip_nu= 1;
            ant_start =0         ;                                       
                                               
                                                if(ant_r1 ==1)   
                                                {
                                                 ant_h=1;
                                                  skip_nu = 1;
                                                 ant_start = 0;         
                                                }                                               
                                        }
                                       
                                       
                                                break;
                         case 1:

                                                if(ant_r1 ==1)       // 4.5ms
                                                  ant_h ++;
         
                                        if( ant_h >36 && ant_h<53)      //4.5MS  &#184;&#223;μ&#231;&#198;&#189;μè′y1yè¥
                                         {
                                                 if (ant_r1 ==0)        //4.5ms&#184;&#223;μ&#231;&#198;&#189;1yè¥
                                                 {
                                                   skip_nu = 2;        //1y0.56MS   
                                                         ant_h=0 ;
                                                 }
                                       
                                         }

                                                break;
                                case 2:                                 

                                                if(ant_r1 ==0)   //  è&#231;1&#251;ê&#199;0.56Ms£&#172;±£3&#214;2&#187;±&#228;
                                         {
                                                ant_l = 1;
                                               
                                          }

                                                if(ant_r1 ==1)         //&#188;&#198;&#203;&#227;&#184;&#223;μ&#231;&#198;&#189;
                                         {
                                                  ant_h=1;
                                                skip_nu = 3;
                                               
                                         }
                                                break;
                                               
                                        case 3:
                                                           if(ant_r1 ==1)  
                                                                ant_h++ ;
                                       
                                             if(ant_r1 ==0)         //ò&#187;&#206;&#187;êy&#190;Y&#182;áíê
                                                         {                                                                 
                                              if( (ant_h >4 )&& (ant_h<8))     /*0.56ms, êy&#190;Y0 */
                                        {
       
                                                                        skip_nu =2  ;       
                                                                        frame_data=frame_data <<1 ;
                                                                }                                       
                                                         else if((ant_h>15)&&(ant_h<20))   /* 1.68ms£o1ms~2ms    êy&#190;Y 1*/
                                                          {
                                                                 
                                                                         skip_nu =2  ;
                                                          
                                                                        frame_data=frame_data <<1 ;
                                                                 frame_data ++ ;
                                                          }
                                                 }
             if((ant_h>21)&&(ant_h<25))    ///* 2.1ms£o2ms~4ms ò&#187;&#214;&#161;êy&#190;Y&#189;óê&#213;íê3é*/
                                                 {
                                                          frame_data=0 ;
                                                                skip_nu =0 ;
                                                 }
      
       
                                        break;
       
                                       
                                        default:
                                        ant_l = 0;
                                        ant_h = 0;
                                        skip_nu= 0;
                       
                                        break;
                                }

                       
                定时器采集,并且已经成功
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6661
金钱
6661
注册时间
2016-5-29
在线时间
909 小时
发表于 2017-7-20 18:08:27 | 显示全部楼层
楼主的红外解码方法方式不正确吧.
红外解码本身最好的方法就是外部中断+定时器.
您居然要放弃这个方法.
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-20 18:14:34 | 显示全部楼层
操作系统 发表于 2017-7-20 18:08
楼主的红外解码方法方式不正确吧.
红外解码本身最好的方法就是外部中断+定时器.
您居然要放弃这个方法.

你用外部中断,浪费CPU资源,在学校玩玩还可以,你在实际开发项目中,就好浪费
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-20 18:19:24 | 显示全部楼层
abcxuyangyang 发表于 2017-7-20 18:03
if(TIM_GetITStatus(TIM2, TIM_IT_Update))          // &#197;D&#182;&#207;·¢éúupdateê&#194;&# ...

先谢谢,你的是STM32的吧,原理都差不多,我先看看;你的定时器定时多少?怎么后面0.56ms的时候,寄存器的值还那么大?
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-20 18:25:04 | 显示全部楼层
操作系统 发表于 2017-7-20 18:08
楼主的红外解码方法方式不正确吧.
红外解码本身最好的方法就是外部中断+定时器.
您居然要放弃这个方法.

我的红外是用的普通IO口,不在外部中断那串口那,现在IC成本都低,IO口少,实现的功能多,所以能省的得省,这就是技术,我也是刚出来不就,所以欠缺~~~
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-20 18:35:03 | 显示全部楼层
abcxuyangyang 发表于 2017-7-20 18:03
if(TIM_GetITStatus(TIM2, TIM_IT_Update))          // &#197;D&#182;&#207;·¢éúupdateê&#194;&# ...

你是定时112us?
我是小白,很白很白的小白!!!
回复

使用道具 举报

2

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2013-6-5
在线时间
141 小时
发表于 2017-7-20 21:15:25 | 显示全部楼层
商业代码应该这样处理:
利用一个定时器,对每个信号的最小时间间隔,进行至少3次采样,然后取两次相同的做为信号电平,
收集完整的一帧信号,利用引导和数据之间的时间比例关系可以确认,利用引导和数据的比例关系确定高低电平脉冲的宽度,校验接收的每个脉冲宽度,正确后解码,.
同时,定时器还可以提供其他的定时信号或动态的数码刷新,输入可以是任意的I/O引脚.
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-21 08:59:22 | 显示全部楼层
zhxzhx 发表于 2017-7-20 21:15
商业代码应该这样处理:
利用一个定时器,对每个信号的最小时间间隔,进行至少3次采样,然后取两次相同的做为 ...

我是利用数据码的前4位和后四位取反值是否相等来判断解码完成
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-21 08:59:43 | 显示全部楼层
zhxzhx 发表于 2017-7-20 21:15
商业代码应该这样处理:
利用一个定时器,对每个信号的最小时间间隔,进行至少3次采样,然后取两次相同的做为 ...

我是利用数据码的前4位和后四位取反值是否相等来判断解码完成
我是小白,很白很白的小白!!!
回复

使用道具 举报

18

主题

155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3882
金钱
3882
注册时间
2016-7-8
在线时间
817 小时
发表于 2017-7-21 13:09:31 | 显示全部楼层
用普通IO口实时性不会太好吧?
回复

使用道具 举报

11

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2015-1-8
在线时间
46 小时
发表于 2017-7-21 14:11:38 | 显示全部楼层

定时中断 96us
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-21 16:11:12 | 显示全部楼层
yanzhuangsongqi 发表于 2017-7-21 13:09
用普通IO口实时性不会太好吧?

很好啊,我公司同事都是用这样普通的,不占用任何CPU资源
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-21 16:11:37 | 显示全部楼层

好的,谢谢
我是小白,很白很白的小白!!!
回复

使用道具 举报

0

主题

12

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-8-4
在线时间
6 小时
发表于 2017-7-21 21:56:29 来自手机 | 显示全部楼层
使用while等待,还好意思说不占CPU资源?
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-24 08:38:37 | 显示全部楼层
wacke 发表于 2017-7-21 21:56
使用while等待,还好意思说不占CPU资源?

while不是不一定不用,你先看清楚主题好吗?没看到我在求好的方法,不会就别瞎评论
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-24 08:39:00 | 显示全部楼层
wacke 发表于 2017-7-21 21:56
使用while等待,还好意思说不占CPU资源?

while不是不一定不用,你先看清楚主题好吗?没看到我在求好的方法,不会就别瞎评论
我是小白,很白很白的小白!!!
回复

使用道具 举报

0

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2015-4-16
在线时间
11 小时
发表于 2017-7-24 08:49:48 | 显示全部楼层
uint8_t time_l = 0;
uint8_t time_h = 0;
bool flag_io_state = 0;
bool flag_up_state = 0;
uint8_t bitcount = 0;
uint8_t bytecount = 0;
uint8_t task = 0;

__interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void) //50us
{
    flag_io_state = pRF_In_Status();
    if(flag_io_state)
    {
        if(time_h < 250) time_h++;
    }
    else
    {
        if(time_l < 250) time_l++;
    }

    if(!flag_read_ok)
    {
        if((!flag_io_state) && (flag_up_state))
        {
            if(0 == task)
            {
                if((time_l <= (180 + 36)) && (time_l >= (180 - 36))\
                && (time_h <= (90 + 18)) && (time_h >= (90 - 18)))//收同步头
                {
                    bitcount = 0;
                    bytecount = 0;
                    task++;
                }
            }
            else if(1 == task) //收数据
            {
                if((time_l <= (12 + 6)) && (time_l >= (12 - 6)))
                {
                    if((time_h <= (12 + 6)) && (time_h >= (12 - 6)))
                    {
                        rx_data[bytecount] &= ~(1 << bitcount);
                    }
                    else if((time_h <= (36 + 18)) && (time_h >= (36 - 14)))
                    {
                        rx_data[bytecount] |= (1 << bitcount);
                    }
                    else
                    {
                        task = 0;
                    }
                    bitcount++;
                    if(bitcount > 7)
                    {
                        bitcount = 0;
                        bytecount++;
                        if(bytecount >= 4)
                        {
                            bytecount = 0;
                            task = 0;
                            flag_read_ok = TRUE;
                        }
                    }
                }
                else
                {
                    task = 0;
                }
            }
            else
            {
                task = 0;
            }
            time_h = 0;
            time_l = 0;
        }
    }
    flag_up_state = flag_io_state;
}
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-24 09:23:17 | 显示全部楼层
salon_lee 发表于 2017-7-24 08:49
uint8_t time_l = 0;
uint8_t time_h = 0;
bool flag_io_state = 0;

谢谢,程序没展示完全把
我是小白,很白很白的小白!!!
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2017-7-24 10:06:15 | 显示全部楼层
本帖最后由 yyx112358 于 2017-7-24 10:07 编辑

我发一下我写的STC15的NEC码解码(不是RC5等编码),用的是外部中断+定时器(定时器只是负责自加全局计时变量,所以可以加入其它代码),不同的是思路是使用状态机,所以实时性非常强,我觉得你可以借鉴一下这个思路。我状态机的转换关系如下:
1.        ERROR状态下,检测是否出现起始码,是则进入RCVDAT,否则留在ERROR
2.        RCVDAT状态下且接收到32位以下,连续接收,每次如果接收到0、1则储存入中间变量tmp,接收到的位数cnt++。否则回到ERROR。
3.        RCVDAT状态下且接收完32位后,进行校验(是否源码等于反码)。成功,则储存为结果addr、cmd,进入REPEAT状态,清零tmp,cnt,repeat。否则,回到ERROR
4.        REPEAT状态下,如果接收到重复码,则repeat++。否则回到ERROR。

不用外部中断和定时器就只能不停地while循环扫描,实时性很低堵塞程序还容易被打断,但是也可以实现。
[mw_shl_code=c,true]#ifndef            _INFRA_H_
#define        _INFRA_H_

#include        "main.h"
/*        红外遥控
        1.
                INFRA->INT0->P3.2
        2.使用定时器统计外部中断间隔来区分不同编码
                硬件上使用上拉电阻进行反相
                使用状态机实现非阻塞读取
*/
sbit        INFRA=P3^2;//INT0

typedef struct        s_DEV_INFRA
{
        u8        addr;//地址
        u8        cmd;//命令
        u8        repeat;//重复次数(最大255次即连按25s以上)
        void(*Init)(void);//初始化函数
}DEV_INFRA;//外部程序接口

typedef        enum
{
        INFRARED_ERROR                =0,
        INFRARED_11        =162,
        INFRARED_12        =98,
        INFRARED_13        =226,
        INFRARED_21        =34,
        INFRARED_22        =2,
        INFRARED_23        =194,
        INFRARED_31        =224,
        INFRARED_32        =168,
        INFRARED_33        =144,
        INFRARED_41        =104,
        INFRARED_42        =152,
        INFRARED_43        =176,
        INFRARED_51        =48,
        INFRARED_52        =24,
        INFRARED_53        =122,
        INFRARED_61        =16,
        INFRARED_62        =56,
        INFRARED_63        =90,
        INFRARED_71        =66,
        INFRARED_72        =74,
        INFRARED_73        =82 }INFRA_KEY;//遥控器编码

typedef        enum
{
        NEC_RCVDAT,//数据读取状态
        NEC_REPEAT,//重复码状态
        NEC_ERROR//空闲状态,未接收和接收错误状态
}NEC_STAT;//状态机状态

extern        DEV_INFRA        DEV_Infra0;

void        INFRA_Init(void);

#endif
[/mw_shl_code]
[mw_shl_code=c,true]#include        "Infra.h"
#include        "Uart.h"

#define        NEC_TIM_OVERFLOW_LENGTH_US        (200)//定时器计数周期,理论上越小越好

static void                NEC_Init(void);
static u32                NEC_GetDelay(void);

DEV_INFRA        DEV_Infra0={0,0,0,NEC_Init};



//INFRA->INT0->P3.2
//TIM3,200us@30MHz
//使用TIM3测量INFRA引脚上低电平之间的周期
static void        NEC_Init(void)
{
        CLRBIT(P3M0,2);
        CLRBIT(P3M1,2);

        INFRA=1;
        IT0=1;//上升、下降沿
        EX0=1;

        T4T3M |= 0x02;                //定时器时钟1T模式
        T3L = 0x100-(SYSCLK/1000000*NEC_TIM_OVERFLOW_LENGTH_US)%0x100;//0x90;                //设置定时初值
        T3H = 0x100-(SYSCLK/1000000*NEC_TIM_OVERFLOW_LENGTH_US)/0x100;//0xE8;                //设置定时初值
        SETBIT(IE2,5);                //开中断
        T4T3M |= 0x08;                //定时器3开始计时
}
static        u16        NEC_TimCnt=0;//定时器溢出计数(周期NEC_TIM_OVERFLOW_LENGTH_US微秒)
void        TIM3_ISR(void)        interrupt        19
{
        NEC_TimCnt++;
}
//获取与上一次调用NEC_GetDelay()后的间隔
static u32                NEC_GetDelay(void)
{
        static        u16 lastcnt=0;
        u16        delay=NEC_TimCnt-lastcnt;
        lastcnt=NEC_TimCnt;
        return delay*NEC_TIM_OVERFLOW_LENGTH_US;
}
//硬件电路上对信号做了反相,故可用下降沿计数
//起始码->8位地址码->8位地址反码->8位命令码->8位命令反码->重复码->重复码->...
void        INT0_ISR(void)        interrupt        0
{
        u32        t=0;
        static NEC_STAT flag=NEC_ERROR;//状态机标志
//统计高低电平
        t=NEC_GetDelay();
        #ifdef        _DEBUG_
//        sprintf("%ld\t",t);
//        UART_SendString(str);
        #endif
        switch(flag)
        {
                case        NEC_ERROR://扫描是否出现起始码
                {
                        if( t>=12000 && t<=15000 )//起始码
                        {
                                flag=NEC_RCVDAT;//进入数据接收状态
                        }
                        break;
                }
                case        NEC_RCVDAT://数据接收状态
                {
                        static        u8        cnt=0;//接收位数计数
                        static        u32        tmp=0;//接收
                        if(cnt<32)
                        {
                                tmp<<=1;
                                cnt++;
                                if( t>=1600 && t<= 2600)//编码1
                                {
                                        tmp++;
                                }
                                else if( t>=600 &&t<=1400)//编码0
                                {
//                                        tmp&=~(0x01);
                                }
                                else//都不是,发送错误
                                {
                                        flag=NEC_ERROR;
                                        cnt=0;
                                        tmp=0;
                                        break;                               
                                }
                        }
                        if(cnt==32)//接收完32bit
                        {
                                if(        ((u8)(tmp>>24)==(u8)(~(tmp>>16)))        &&       
                                        ((u8)((tmp>>8))==(u8)~tmp)        )//地址、命令校验
                                {
                                        DEV_Infra0.addr=tmp>>24;
                                        DEV_Infra0.cmd=~tmp&0xFF;
                                        DEV_Infra0.repeat=0;
                                        flag=NEC_REPEAT;
                                }
                                else//校验失败
                                {
                                        flag=NEC_ERROR;
                                }
                                cnt=0;
                                tmp=0;
                        }
                        break;
                }
                case        NEC_REPEAT://重复码
                {
                        if( t>=30000 && t<=42000)//【这个地方与其它资料不同,并非长98ms】
                        {
                                flag=NEC_REPEAT;
                        }
                        else        if((t>=10000)&&(t<=12000))
                        {
                                if(DEV_Infra0.repeat<0xFF)
                                {
                                        DEV_Infra0.repeat++;
                                }
                                flag=NEC_REPEAT;
                        }
                        else        if( t>12000 && t<=15000 )//起始码
                        {
                                flag=NEC_RCVDAT;//进入数据接收状态
                        }
                        else
                        {
                                flag=NEC_ERROR;
                        }
                        break;
                }
                default:
                        flag=NEC_ERROR;
                        break;
        }
}
[/mw_shl_code]


回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-7-24 10:50:18 | 显示全部楼层
yyx112358 发表于 2017-7-24 10:06
我发一下我写的STC15的NEC码解码(不是RC5等编码),用的是外部中断+定时器(定时器只是负责自加全局计时变 ...

谢谢~~~
我是小白,很白很白的小白!!!
回复

使用道具 举报

2

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2013-6-5
在线时间
141 小时
发表于 2017-7-25 15:08:06 | 显示全部楼层
wacke 发表于 2017-7-21 21:56
使用while等待,还好意思说不占CPU资源?

我的第一任务就是解码,不解码我没事干,不等待干吗?
回复

使用道具 举报

2

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2013-6-5
在线时间
141 小时
发表于 2017-7-25 15:11:34 | 显示全部楼层
程功之道 发表于 2017-7-21 08:59
我是利用数据码的前4位和后四位取反值是否相等来判断解码完成

不是所有的遥控器编码都具有这个特点,特别是无线的,干扰很严重,利用比例关系,还可以还原一部分被干扰的脉冲
回复

使用道具 举报

2

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2013-6-5
在线时间
141 小时
发表于 2017-7-25 15:12:24 | 显示全部楼层
yanzhuangsongqi 发表于 2017-7-21 13:09
用普通IO口实时性不会太好吧?

比用中断要好,为什么自己理解去
回复

使用道具 举报

3

主题

15

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2017-7-26
在线时间
8 小时
发表于 2017-8-3 10:34:11 | 显示全部楼层
很好,学习到了很多
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-8-8 11:03:06 | 显示全部楼层
Vigor6 发表于 2017-8-3 10:34
很好,学习到了很多

我最近写了个很好的红外,普通IO口就可以实现
我是小白,很白很白的小白!!!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
 楼主| 发表于 2017-8-8 18:00:28 | 显示全部楼层
#include <define.h>

#define IR_time         100
#define IR_Sync_Max     (15000/IR_time)
#define IR_Sync_Min     (9700/IR_time)
#define IR_Sync_Divide  (12375/IR_time)
#define IR_Data_Max     (3000/IR_time)
#define IR_Data_Min     (600/IR_time)
#define IR_Data_Divide  (1685/IR_time)
#define IR_Bit_Num      32

uchar r_IR_SyCnt;
uchar r_bitcnt;
uchar IR_datashif;
uchar IR_data;
uchar IR_code;
uchar IR_UserH;
uchar IR_UserL;
bit b_IR_temp;
bit b_IR_State;
bit b_Sync;
bit b_IR_ok;

/*********êéé&#207;346P*******/
void IR_on(void)
{
        uchar Sync_time;
        r_IR_SyCnt++;
        b_IR_temp = b_IR_State;
        b_IR_State = IRIN;
        if(b_key_IR)
        {
                if(b_IR_temp&&!b_IR_State)
                {
                        Sync_time = r_IR_SyCnt;
                        r_IR_SyCnt = 0;
                        if(Sync_time > IR_Sync_Max)
                        {b_Sync = 0;}
                        else if(Sync_time >= IR_Sync_Min)
                        {
                                if(Sync_time >= IR_Sync_Divide)
                                {
                                        b_Sync = 1;
                                        r_bitcnt = IR_Bit_Num;
                                }
                        }
                        else if(b_Sync)
                        {
                                if((Sync_time < IR_Data_Min)|(Sync_time > IR_Data_Max))
                                {b_Sync = 0;}
                                else
                                {
                                        IR_datashif >>= 1;
                                        if(Sync_time >= IR_Data_Divide)
                                        {IR_datashif |= 0x80;}
                                        if(--r_bitcnt == 0)
                                        {
                                                b_Sync = 0;
                                                if(~IR_datashif == IR_data)
                                                {
                                                        IR_code = IR_data;
                                                        b_IR_ok = 1;
                                                }
                                        }
                                }
                                if((r_bitcnt&7) == 0)
                                {
                                        IR_UserH = IR_UserL;
                                        IR_UserL = IR_data;
                                        IR_data = IR_datashif;
                                }
                        }
                }
        }
}
这是我写的红外,普通IO口就可以实现,不占用CPU资源,不影响其他任务的工作,现在分享出来,谢谢~~~
我是小白,很白很白的小白!!!
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-27 13:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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