xujianglun1 发表于 2012-7-19 22:17:55

红外解码,51, 什么方法计算波形中低电平的时间

C8051
我用外部中断+定时器方法,

程序最开始打开外中断,(边沿触发,此处不确定是上升沿还是下降沿?,找资料没有发现如何设,网上别人有理解为下降沿,也只打开外中断,边沿触发)

每次进中断,读定时器的值(通过串口输出到电脑) ,后定时器0清零,

定时器初始值 为0
当第一次进入中断时,输出的定时器值应为0,但实际得到的不是0,不确认是什么引起?

不知道 我的思路是 不是有哪个地方不对,


BXAK 发表于 2012-7-19 23:09:36

外部中断方式:
1、上升沿触发
2、下降沿触发
3、边沿触发:上升沿触发 + 下降沿触发
4、低电平触发
……

如果编码是NEC的话,下降沿中断测脉冲周期解码最方便了

slzm40 发表于 2012-7-19 23:34:39

本帖最后由 slzm40 于 2012-7-19 23:35 编辑

如果中断程序开始就开了定时器一直未关的话,那么第一次进入中断得到的数值为前面一直计时的值,这个值没什么用,要跳过,(因为INTO P3.2空闲为一直高电平,定时器应该 是高电平计数。用了定时器的GATE了?)第一次进中断,到来的是前导码低电平,接着就来的应该 是前导码高电平。。

xujianglun1 发表于 2012-7-20 10:57:35

BXAK 发表于 2012-7-19 23:09 static/image/common/back.gif
外部中断方式:
1、上升沿触发
2、下降沿触发


边沿触发是每当上升沿或下降沿来时都触发,
那我以前理解有误,

我现用的不是NEC,
NEC能解,以前用过几种不同的,

现在用的功能多点,有地址,预置位设置,调用

谢谢,

xujianglun1 发表于 2012-7-20 11:03:49

slzm40 发表于 2012-7-19 23:34 static/image/common/back.gif
如果中断程序开始就开了定时器一直未关的话,那么第一次进入中断得到的数值为前面一直计时的值,这个值没什 ...

恩,谢谢提醒

BXAK 发表于 2012-7-20 11:07:12

xujianglun1 发表于 2012-7-20 10:57 static/image/common/back.gif
边沿触发是每当上升沿或下降沿来时都触发,
那我以前理解有误,



“引导码”波形:?
“1”波形:?
“0”波形:?

xujianglun1 发表于 2012-7-20 11:37:49

BXAK 发表于 2012-7-19 23:09 static/image/common/back.gif
外部中断方式:
1、上升沿触发
2、下降沿触发


C8051 边沿触发,
有什么寄存器设置为下降沿触发吗?

xujianglun1 发表于 2012-7-20 11:39:59

BXAK 发表于 2012-7-20 11:07 static/image/common/back.gif
“引导码”波形:?
“1”波形:?
“0”波形:?

波形:

xujianglun1 发表于 2012-7-20 11:45:31

我用在一楼说的方法,
在电脑串口调试助手上显示的
03 19 0E 0F 09 0E 0E 09 09 0E 04 09 0E 0E 09 0E
3E 19 0E 0E 09 04 0E 09 09 0E 09 02 0E 0F 09 0F
34 19 0E 0E 09 0E 0E 09 09 09 0E 09 0E 0E 09 0E
1,19为引导码的时间,
2,0E、09 为 1 或0
但为什么打印的数目与波形高电低数目不一致
打印16个数目,但监测的波形有21个周期?

BXAK 发表于 2012-7-20 12:02:13

xujianglun1 发表于 2012-7-20 11:39 static/image/common/back.gif
波形:

波形图是手工画的,还是工具测出后的截图?图中的各个高、低电平时间不标出,没法判断编码方式,也就无法选择好的解码方式了

slzm40 发表于 2012-7-20 12:09:15

不知道要解的什么码,NEC?还有这波形是中断口抓到的波形,还是遥控器发出的波形。

xiaoya1945 发表于 2012-7-20 12:14:28

做过红外解码,但没计算低电平的时间,“0”、“1”的区别只是高电平时间长短不同,应该不是很难吧,我用的是一体化接收头,发的码和接收到的码,电平是相反的… good luck…

xujianglun1 发表于 2012-7-20 12:41:18

BXAK 发表于 2012-7-20 12:02 static/image/common/back.gif
波形图是手工画的,还是工具测出后的截图?图中的各个高、低电平时间不标出,没法判断编码方式,也就无 ...

测出来的截图

时间也可以知道,我用截图没有标

xujianglun1 发表于 2012-7-20 12:43:23

时间:
引导码:2.46ms
1.27MS ---1
632us   ---0

BXAK 发表于 2012-7-20 13:33:25

按你的意思上面的 编码方式 是 脉宽调制,测脉冲周期解码最方便,

测脉冲周期时间方法:
1、外部下降沿中断 + 定时器计时;
2、PCA下降沿捕获(PCA下降沿捕获所得的计数值就是脉冲周期时间);



判断T值,
当T≈ (X+2.46)ms(即 高Xms + 低2.46ms),是引导码,接下来在进入中断时开始解码20位数据;
当T≈ 1.902ms(即 高0.632ms + 1.27ms),是数据“1”;
当T≈ 1.264ms(即 高0.632ms + 0.632ms),是数据“0”;

上面只是个大概,要加些防错措施,比如:解码20位数据区间如果T>2.3ms,则视为无效,清除当前解码进度后重新开始解码……

xujianglun1 发表于 2012-7-20 13:52:54

BXAK 发表于 2012-7-20 13:33 static/image/common/back.gif
按你的意思上面的 编码方式 是 脉宽调制,测脉冲周期解码最方便,

测脉冲周期时间方法:


1, 要加些防错措施,比如:解码20位数据区间如果T>2.3ms
    恩,
我用串口打印的数据没有20个,不确定什么引起的,是不是不能在串口中断中调用send_232_char(TH0);这个函数,?



xujianglun1 发表于 2012-7-20 14:03:01


void send_232_char(unsigned char wdata)
{
        bit b0,b1,b2,b3,b4,b5,b6,b7;

//EA      = 0x00;
       
        b0=wdata&0x01;
        b1=wdata&0x02;
        b2=wdata&0x04;
        b3=wdata&0x08;
        b4=wdata&0x10;
        b5=wdata&0x20;
        b6=wdata&0x40;
        b7=wdata&0x80;
       
        Send_PC=0;///start bit
        Delay_Send_PC_8us();
        Send_PC=b0;
        Delay_Send_PC_8us();
        Send_PC=b1;
        Delay_Send_PC_8us();
        Send_PC=b2;
        Delay_Send_PC_8us();
        Send_PC=b3;
        Delay_Send_PC_8us();
        Send_PC=b4;
        Delay_Send_PC_8us();
        Send_PC=b5;
        Delay_Send_PC_8us();
        Send_PC=b6;
        Delay_Send_PC_8us();
        Send_PC=b7;
        Delay_Send_PC_8us();
        Send_PC=1; //stop bit
        Delay_Send_PC_8us();
        Send_PC=1;
        Delay_Send_PC_8us();

//EA      = 1;
}

BXAK 发表于 2012-7-20 15:27:54

发一个红外线解码程序+仿真文件(可定义任意I/O作接收脚,支持长/短按,自适应主频6MHz~40
根据上面帖子改的,帖子中直接用定时器查询下降沿。
下面改成外部下降沿中断 + 定时器计时,用16位定时器计数,晶振12M,(随手改的没调试,还有你引导码周期自己加,因为你没给出引导码高电平时间……)


bit   IRsync;        //同步标志
bit   IR_N;      //解码完成标志
uint8BitN;       //位码装载数
uint8 NEC;   //用3字节装载20位数据:NEC8位、NEC8位、NEC高4位


#define    Boot_Limit          (( 引导码周期 + 900)/256)          //引导码周期上限   
#define    Boot_Lower          (( 引导码周期 - 900)/256)          //引导码周期下限   
#define    Bit1_Limit       ((1902 + 300)/256)                          //数据“1”周期上限
#define    Bit0_Limit       ((1264 + 300)/256)                          //数据“0”周期上限

//外部下降沿中断服务程序
void Int0_Routine(void) interrupt 0
{
            uint8   cntStep;        //步数计

            TL0 = 0;             //先清定时器低8位计数
            cntStep = TH0;   //保存高8位计数
            TH0 = 0;

               if( cntStep > Boot_Limit )//是否超过同步时间
                {      
                        IRsync = 0;                        //同步位清0
                }
                else if( cntStep > Boot_Lower ){ IRsync=1; BitN=20; } //同步位置1,装载位码数20                          
                else if( IRsync )                //如果已同步
                {                                               
                        if(cntStep > Bit1_Limit)IRsync=0;                    //装载20位数据区间,周期>Bit1_Limit则错误
                        else
                        {       
                                NEC >>= 1;                               
                                if(cntStep > Bit0_Limit)NEC |= 0x80;      //数据“0”与“1”
                              if(--BitN == 0)
                                {
                                        IRsync = 0;                                      //同步位清0
                                        IR_N = 1;                         //解码完成
                                }
                                else if((BitN & 0x07)== 0)      //NEC每装满8位,移动保存一次(即 BitN%8 == 0)
                                {      
                                        NEC=NEC;NEC=NEC;   
                                }
                        }
                }
}

xujianglun1 发表于 2012-7-24 14:23:18

谢谢,,
我用的方法和你说的差不多?
我现在的问题是:
用逻逻分析仪测得的波形有20个周期,
但程序中,只进入外部中断15次?
页: [1]
查看完整版本: 红外解码,51, 什么方法计算波形中低电平的时间