打印

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

[复制链接]
楼主: 贺信
手机看帖
扫描二维码
随时随地手机跟帖
61
有风Y真够热心...
酱油店老板 发表于 2009-10-14 12:26


哎...

使用特权

评论回复
62
贺信|  楼主 | 2009-10-14 12:50 | 只看该作者
本帖最后由 贺信 于 2009-10-14 13:33 编辑

谢谢大家的指导,下面是定时器的产生的波形

F0000TEK.JPG (83.66 KB )

F0000TEK.JPG

使用特权

评论回复
63
ZigBee笔记| | 2009-10-14 13:11 | 只看该作者
定时器0你设1干嘛
wangyy608 发表于 2009-10-14 12:24


对啊,先搞清这个先

使用特权

评论回复
64
贺信|  楼主 | 2009-10-14 13:13 | 只看该作者
ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数

        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
        {
led=0;    //节点4

                ET1 = 0;
                T0Count = 0;
                ET1 = 1;
                while(IR_RE == 1);  //等待4.5ms的头高电平过去

                if(T0Count > 5)                //超过0.1*30 = 3ms,即视为数据头判断

程序还是没能进节点4!!灯没亮!!!
难道这种解码思想真不行???

使用特权

评论回复
65
程序匠人| | 2009-10-14 13:29 | 只看该作者
if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms

去掉看看。
或者想办法把这个计数器(T0Count )的值通过串口发发给电脑显示出来看看到底是多少?

使用特权

评论回复
66
贺信|  楼主 | 2009-10-14 13:38 | 只看该作者
while(IR_RE == 1);  //等待4.5ms的头高电平过去

                if(T0Count > 5)                //超过0.1*30 = 3ms,即视为数据头判断完
                {
led=0;

去掉就能跑到节点5,同样会停在节点6判断处!!

使用特权

评论回复
67
程序匠人| | 2009-10-14 13:41 | 只看该作者
还是计时器有问题。

想办法把这个计数器(T0Count )的值通过串口发发给电脑显示出来看看到底是多少?

使用特权

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

void uDelay(uchar n) //延时子程序,入口参数每加1约加10us
{
        for(;n>0;n--)
                {uchar m=20;while(--m);}        
}

***/

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

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

        ET1 = 0;                                //关定时器1
        T0Count = 0;                        //定时器计数值清零
        while(IR_RE == 1);      //初始状态下,红外输出脚一直是高电平,等待

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

//        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
//        {
//led=0;

                ET1 = 0;
                T0Count = 0;
                ET1 = 1;
                while(IR_RE == 1);  //等待4.5ms的头高电平过去

        //        if(T0Count > 5)                //超过0.1*30 = 3ms,即视为数据头判断完
        //        {
//led=0;
                        ET1 = 0;
                        T0Count = 0;
                        uData = 0;
                        for(k=0;k<4;k++)
                        {
                                while(IR_RE == 0);        //等待560ms低电平过去,因为只判断数据高电平
//led=0;
                                ET1 = 0;                        
                                T0Count = 0;                //高电平时清计数值开定时器
                                ET1 = 1;
                                while(IR_RE == 1);        //高电平等待计时
                                if(T0Count > 2)                //根据波形长度判定码值为0或1
                                uTemp = 1;
                                else
                                uTemp = 0;
                                uData |= (uTemp<<k);         //保存键值
                        }
                        SendFlag = 1;                        //置位发送标志
led=0;
                        return uData;                        //判断四位后返回得到的值
        //        }
/**
        }
        else
        {
                T0Count = 0;
                return uData = 0;
        }
**/        
}


这样的话,灯到节点11都亮!!难到这种判断行不通!!!

使用特权

评论回复
69
程序匠人| | 2009-10-14 13:45 | 只看该作者
这个流程应该是可以走通的,问题是你的计时器到底有没有正确计数?

再重复一遍 :想办法把这个计数器(T0Count )的值通过串口发发给电脑显示出来看看到底是多少?

使用特权

评论回复
70
贺信|  楼主 | 2009-10-14 13:48 | 只看该作者
现场采集的波形!
看这波形也没问题!!是定时判断上的问题???

F0001TEK.JPG (84.77 KB )

F0001TEK.JPG

使用特权

评论回复
71
贺信|  楼主 | 2009-10-14 14:04 | 只看该作者
*/

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

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

        ET1 = 0;                                //关定时器1
        T0Count = 0;                        //定时器计数值清零
        while(IR_RE == 1);      //初始状态下,红外输出脚一直是高电平,等待

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

        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
        {


                ET1 = 0;
                T0Count = 0;
                ET1 = 1;
                while(IR_RE == 1);  //等待4.5ms的头高电平过去
led=0;
return uData;       
                if(T0Count > 5)                //超过0.1*30 = 3ms,即视为数据头判断完
                {


/*****************************主函数*************************/

unsigned char uSendData;

void main(void)
{
        InitialTimer0();        //定时器0初始化
        Uart_initial();                //串口初始化
        while(1)
        {       
                uSendData = IR_Decode();        //取解码函数返回值

        //        if(SendFlag ==1)                        //判断发送标志位
        //        {
//        uSendData = 0x27;
                        Uart_send (uSendData);        //串口发送函数
                        SendFlag=0;                                //清发送标志位
//                }

        }
}


结果等亮了,串口显示是0!!!
我在这之前试了串口是能正常发送!!
//        uSendData = 0x27;这句能实现串口显示27

所以为什么会显示0呢??怎么就不计数??

使用特权

评论回复
72
程序匠人| | 2009-10-14 14:12 | 只看该作者
楼主你到底有没有看到我前面的回复?我要你把计数器(T0Count )的值通过串口发给电脑显示出来看看到底是多少?

目的就是看看有没有正常计数。

感觉就差一步了。。。。。

使用特权

评论回复
73
贺信|  楼主 | 2009-10-14 14:20 | 只看该作者
本帖最后由 贺信 于 2009-10-14 15:59 编辑

led=0;
return uData;   
不好意思我忘改了!!
我的本意是:

                ET1 = 1;
                while(IR_RE == 1);  //等待4.5ms的头高电平过去
led=0;
return T0Count;        

结果:灯亮了却没有得到发送的值!!!

使用特权

评论回复
74
sz_kd| | 2009-10-14 14:24 | 只看该作者
LZ应该找找别人写好的程序,自己对比下,看问题出现在那里,这样很容易搞定~~~~~~~~~~

使用特权

评论回复
75
程序匠人| | 2009-10-14 14:49 | 只看该作者
却没有发送任何值?

哎……调试的原则,后续的每一步都是建立在前一步准确无误的基础上的。

你前面说串口是好的,现在却说没有发送任何值?也就是连0也没有发送?真是让人抓狂了。

使用特权

评论回复
76
贺信|  楼主 | 2009-10-14 14:56 | 只看该作者
本帖最后由 贺信 于 2009-10-14 15:58 编辑

ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
led=0;
return T0Count;
        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
        {

这样改后结果是灯亮 串口上没有想要的值!!
之后我在改
unsigned char uSendData;

void main(void)
{
        InitialTimer0();        //定时器0初始化
        Uart_initial();                //串口初始化
        while(1)
        {        
        //        uSendData = IR_Decode();        //取解码函数返回值

        //        if(SendFlag ==1)                        //判断发送标志位
        //        {
        uSendData = 0x27;
                        Uart_send (uSendData);        //串口发送函数
        //                SendFlag=0;                                //清发送标志位
        //        }

        }
}
结果串口上显示27
刚我又做了一遍!也是这样!!

使用特权

评论回复
77
贺信|  楼主 | 2009-10-14 15:00 | 只看该作者
tu

串口接受.jpg (199.41 KB )

串口接受.jpg

使用特权

评论回复
78
kingTek| | 2009-10-14 15:05 | 只看该作者
本帖最后由 kingTek 于 2009-10-14 19:19 编辑

俺博客里的:“高效率的大功率LED闪灯”
http://blog.21ic.com/user1/5849/archives/2009/62988.html
这个系统里面就包含了一个红外解码程序,可以收发双工方式工作,经过验证是非常可靠,程序代码量却很小。
计时用绝对中断,解码还是用主流程。
中断里干的事不要太复杂。
得考虑到相互中断的计时误差,设置容限。
再一个,编写一点测试程序,我们当时就是用测试程序,测定了关键的数据,
还可以很清楚地看到程序在什么地方出了问题,
其中的技术细节可能三言两语一下子说不完,在这里我就只能给你提醒这么多,
如果你是这块料的话很快就会得到启发的。

使用特权

评论回复
79
贺信|  楼主 | 2009-10-14 15:22 | 只看该作者
78# kingTek

看了,可没见任何实际能帮到我的

使用特权

评论回复
80
贺信|  楼主 | 2009-10-14 15:40 | 只看该作者
为什么呢???
ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
led=0;
return T0Count;
        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
        {
应该怎么也要返回个值呀!!!!

使用特权

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

本版积分规则