打印

红外解码程序!!请高手帮忙看看

[复制链接]
楼主: 贺信
手机看帖
扫描二维码
随时随地手机跟帖
21
程序匠人| | 2009-10-13 17:28 | 只看该作者 回帖奖励 |倒序浏览
16# 程序匠人

要是有仿真就好了!!我是直接在单片机上实验的!!!困惑中!!!!
贺信 发表于 2009-10-13 17:21


没有仿真并不意味着束手无策。可以用多余的IO口来指示程序走过哪里。
不知到你看过这篇  匠人手记:程序调试(除错)过程中的一些雕虫小技(连载进行中……)  没有?

使用特权

评论回复
22
贺信|  楼主 | 2009-10-13 17:29 | 只看该作者
13# 有风

延时的话有个问题!!我的程序打算用下降沿中断来实现,当你延时时下降沿来了又中断了,比如是0来了它在还没到1120us就中断了根本就没来的及判断是0是1!!!

使用特权

评论回复
23
贺信|  楼主 | 2009-10-13 17:31 | 只看该作者
17# 程序匠人

就是KEIL里编程后直接下载到STC单片机看效果

使用特权

评论回复
24
savagezp| | 2009-10-13 17:32 | 只看该作者
先看硬件对不对。。

使用特权

评论回复
25
程序匠人| | 2009-10-13 17:33 | 只看该作者
你先按照我的方法,找出程序走过哪些地方,没走过哪些地方吧。(在程序节点处,用多余IO口去点LED即可)

晚上等你的消息。

使用特权

评论回复
26
程序匠人| | 2009-10-13 17:47 | 只看该作者
如何设置节点?
1、找一个不用的IO口外接一个LED
2、请分别在下列标注“节点”的地方,插入一条指令去点亮LED。注意每次只能插入一个节点,并单独编译烧录测试,运行后按下遥控器后,观察LED是否会被点亮。
3、被点亮的代表该程序节点被执行到了。否则代表未被执行到。
4、反复修改节点位置并编译执行,最后汇总所有节点的执行情况。
等你回音。


//**********************红外解码******************************//

uchar IR_Decode()
{
       unsigned char uData = 0;        //处理数据后返回值
        unsigned char uTemp = 0;        //数据为1或0暂存值

//节点1
        ET1 = 0;                                //关定时器1
        T0Count = 0;                        //定时器计数值清零
        while(IR_RE == 1);      //初始状态下,红外输出脚一直是高电平,等待
//节点2
        ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
//节点3
        if( T0Count > 17)                //电平为高,判断计数时间0.5* 17 = 8.5ms约为9.0ms
        {
//节点4
                ET1 = 0;
                T0Count = 0;
                ET1 = 1;
                while(IR_RE == 1);  //等待4.5ms的头高电平过去
//节点5
                if(T0Count > 5)                //超过0.5*5 = 2.5ms,即视为数据头判断完                  {
//节点6
                        ET1 = 0;
                        T0Count = 0;
                        for(k=0;k<4;k++)
                        {
                                while(IR_RE == 0);        //等待560ms低电平过去,因为只判断数据高电平
//节点7
                                ET1 = 0;                        
                                T0Count = 0;                //高电平时清计数值开定时器
                                ET1 = 1;
                                while(IR_RE == 1);        //高电平等待计时
//节点8
                                if(T0Count > 2)                //根据波形长度判定码值为0或1
//节点9
                                uTemp = 1;
                                else
//节点10
                                uTemp = 0;
                                uData |= (uTemp<<k);         //保存键值
                        }
                        return uData;                        //判断四位后返回得到的值
//节点11
                        SendFlag = 1;                        //置位发送标志
                }
        }
        else
        {
                T0Count = 0;
                return uData = 0;
        }
        
}

使用特权

评论回复
27
程序匠人| | 2009-10-13 17:51 | 只看该作者
哦,不用了,问题已经找到了
这两条指令:
               return uData;                        //判断四位后返回得到的值
               SendFlag = 1;                        //置位发送标志
请把执行次序修改为:
                SendFlag = 1;                        //置位发送标志
                return uData;                        //判断四位后返回得到的值

否则,SendFlag 不会被置位

使用特权

评论回复
28
贺信|  楼主 | 2009-10-13 18:02 | 只看该作者
哦,不用了,问题已经找到了
这两条指令:
               return uData;                        //判断四位后返回得到的值
               SendFlag = 1;                        //置位发送标志
请把执行次序修改 ...
程序发表于 2009-10-13 17:51


首先真的很谢谢匠人 前辈!!!!

程序改完后下载还是没有发送!!

使用特权

评论回复
29
贺信|  楼主 | 2009-10-13 19:08 | 只看该作者
本帖最后由 贺信 于 2009-10-13 20:41 编辑

按匠人的测试话 到节点3就不亮了,前面的灯都亮
这样岂不是来数据低电平后就没往下走了??
我测试时示波器探头一直放在单片机IR_RE脚上呀,也能看到示波器上有波形变化!!

使用特权

评论回复
30
贺信|  楼主 | 2009-10-13 19:10 | 只看该作者
这下我就纳闷了!!看样子还有大问题
在此谢谢匠人前辈
吃饭去了:dizzy:
希望高手们指教

使用特权

评论回复
31
程序匠人| | 2009-10-13 21:17 | 只看该作者
"到节点3就不亮了,前面的灯都亮"
回复:
问题出在这里:

//节点2
        ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
//节点3

这两条指令本身似乎没有问题。按道理来说,只要IO口电平条件满足,并且程序没有因为复位或中断的原因跳出,就应该执行下去。
请按以下思路查找故障:
1、IR_RE 是否正常? 可以换一个IO口看看。确保输入0或者1时都能正常读取到。
2、有没有用到WDT? 是否因为WDT溢出导致程序意外复位了?
3、是否有其它中断开启着?如有,请全部关闭。再测试。

使用特权

评论回复
32
贺信|  楼主 | 2009-10-13 22:10 | 只看该作者
本帖最后由 贺信 于 2009-10-13 22:13 编辑

回复:
问题出在这里:

//节点2
        ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数 ...
程序匠人 发表于 2009-10-13 21:17 [/quote]

思路2和3的故障可以排除,我这程序只是为实现这一解码方法而独立写的,里面还有个串口发射函数就没有其他的东西!!


/***********************串口初始化***********************************/
#define RELOAD_COUNT  0xF3   //12MHz,12T,SMOD=0,2400bps
sfr  AUXR = 0x8e;
void Uart_initial()
{
SCON    =   0x50;           //0101,0000  方式1:8位可变波特率
PCON    =   0X00;   //设置SMOD=0 波特率不加倍
TMOD    =   0x21;           //0011,0001 设置定时器1为8位自动重装计数器
TH1     =   RELOAD_COUNT;   //设置定时器1自动重装数
TL1     =   RELOAD_COUNT;
TR1     =   1;              //开定时器1
AUXR = 0X00;  //不允许独立波特率发生器运行,用定时器1做波特率发生器
ES = 1;             //允许串口中断
EA = 1;             //开总中断
}


/***************************定时器0初始化*********************************/
void InitialTimer0()
{
TMOD = 0x11;  // 定时器0, 1工作模式1, 16位定时方式

TH1  = 0xfe;  //定时500uS
TL1  = 0x0c;
//TCON = 0x01;
EA   = 1;   
TR0  = 1;      
}

方法1暂时没试

使用特权

评论回复
33
程序匠人| | 2009-10-14 08:26 | 只看该作者
继续穷追猛打:

//节点2
        ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
//节点3

改为:

//节点2
        ET1 = 1;                                //当有低电平到来打开定时器
     while(IR_RE == 0)                //低电平等待,T0计数
     {
        //在这个地方加一段指令,让LED测试口不断翻转,然后用示波器观察测试口的电平。在按下遥控器之前,测试口为低电平,按下之后,是否为方波?如是,则说明程序被卡在这里了;否则说明程序飞出去了(或者顺序执行下去了)。
        }

//节点3

使用特权

评论回复
34
程序匠人| | 2009-10-14 08:27 | 只看该作者
建议把所有中断(包括串口中断)先临时关闭。免得意外发生。

使用特权

评论回复
35
贺信|  楼主 | 2009-10-14 08:57 | 只看该作者
34# 程序匠人

我现在把串口也关了,红外接受口也换了sbit IR_RE   = P2^5;        //红外接受中断口
现在的情况是到节点3能亮灯,但到接点4就不亮了
继续努力去了……

使用特权

评论回复
36
程序匠人| | 2009-10-14 09:09 | 只看该作者
"我现在把串口也关了,红外接受口也换了sbit IR_RE   = P2^5;        //红外接受中断口
现在的情况是到节点3能亮灯,但到接点4就不亮了"

? 为什么现在节点3可以过了?原因呢?

使用特权

评论回复
37
贺信|  楼主 | 2009-10-14 09:21 | 只看该作者
"我现在把串口也关了,红外接受口也换了sbit IR_RE   = P2^5;        //红外接受中断口
现在的情况是到节点3能亮灯,但到接点4就不亮了"

? 为什么现在节点3可以过了?原因呢? ...
程序匠人 发表于 2009-10-14 09:09


我刚刚做了几次实验,也把sbit IR_RE   = P3^2; //红外接受中断口  改回来了!!
串口也没关,节点3都能亮!!!真是奇怪!!昨晚我也反复做了这实验,节点3是不能亮的!!
我现在往下走时就是到节点4就不能亮了!!!
关串口,改红外接受口都是!!在节点4就不亮

使用特权

评论回复
38
程序匠人| | 2009-10-14 09:41 | 只看该作者
分析:节点4不过,是因为T0Count不满足条件。建议:
1、把这个条件临时去掉或放宽。
2、检测一下你的定时是否准确。要用实验证明。
3、红外接受波形上有没有干扰或毛刺?影响了正常的电平识别




//节点3
        if( T0Count > 17)                //电平为高,判断计数时间0.5* 17 = 8.5ms约为9.0ms
        {
//节点4

使用特权

评论回复
39
lhj200304| | 2009-10-14 10:00 | 只看该作者
用中断来测量高低电平长度会好点

使用特权

评论回复
40
贺信|  楼主 | 2009-10-14 10:03 | 只看该作者
***************************定时器0初始化*********************************/
void InitialTimer0()
{
TMOD = 0x11;  // 定时器0, 1工作模式1, 16位定时方式

TH1  = 0xfe;  //定时500uS
TL1  = 0x0c;
//TCON = 0x01;
EA   = 1;  
//ET0=1;   这个不开有问题吗??
TR0  = 1;      
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则