打印

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

[复制链接]
楼主: 贺信
手机看帖
扫描二维码
随时随地手机跟帖
81
为什么呢???
ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
led=0;
return T0Count;    //匠人按:SendFlag 没有置位,光返回T0Count,没用吧?(除非你在主程序里没有判断SendFlag 就直接发送了。)
        if( T0Count > 30)        ...
贺信 发表于 2009-10-14 15:40


回 : 你有没有把标志置位?

使用特权

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

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

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

        }
}
是显示为0

使用特权

评论回复
83
程序匠人| | 2009-10-14 16:10 | 只看该作者
是显示为0?那就是说,T0Count没有计数。是这个意思吗?

使用特权

评论回复
84
贺信|  楼主 | 2009-10-14 16:16 | 只看该作者
我现在好好看过了以遍,可能刚才改动太多搞得有错了!
  现在我在
        ET1 = 1;                                //当有低电平到来打开定时器
        while(IR_RE == 0);                //低电平等待,T0计数
led=0;
return T0Count;
加了后按发射键
串口上显示E9 2B 28 1D A8 26 26 1B A9 26 2C 1D
每次下后按都会有不同的12个值!!
发射时我是连续发三bety

使用特权

评论回复
85
酱油店老板| | 2009-10-14 17:01 | 只看该作者
不知道谁是LZ的BOSS,,,如果是俺,直接找个砖头照自己头呼得了...

使用特权

评论回复
86
贺信|  楼主 | 2009-10-14 17:28 | 只看该作者
85# 酱油店老板

惭愧!!以前从没搞过单片机程序,现在开始学,见笑了!!

使用特权

评论回复
87
贺信|  楼主 | 2009-10-14 17:45 | 只看该作者
真的好难受!!!!
一个T0Count;怎么会错呢??!!!

使用特权

评论回复
88
zhiyonghe| | 2009-10-14 19:42 | 只看该作者
85# 酱油店老板

高手这样的态度真让人寒心!!果真很牛的话就帮忙分析为什么!!光说些没用的又打击新手的话真不是君子所为!!谁没有困惑过!!!!!
再此向匠人致敬!!!!

使用特权

评论回复
89
程序匠人| | 2009-10-14 20:44 | 只看该作者
唉,我也有点拿你没办法了,如果我是你老板,大概也要拿砖头来拍你了。呵呵。

把你当下的程序再完整发上来看看。



加了后按发射键
串口上显示E9 2B 28 1D A8 26 26 1B A9 26 2C 1D
每次下后按都会有不同的12个值!!
发射时我是连续发三bety

这里说发三bety是指红外?还是指串口?

使用特权

评论回复
90
贺信|  楼主 | 2009-10-14 21:25 | 只看该作者
本帖最后由 贺信 于 2009-10-14 21:35 编辑

我现在是真晕了!!
我刚做了些实验,又是一踏糊涂!!

3BETY是发射的红外数据

使用特权

评论回复
91
贺信|  楼主 | 2009-10-14 21:27 | 只看该作者
本帖最后由 贺信 于 2009-10-14 21:30 编辑

main,c 文件
#include <reg51.h>
#include"initial.h"
#include"IR Decode.h"
#include"UART.h"
#include"main.h"

#define uchar unsigned char
#define uint unsigned int

bit SendFlag = 0;


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

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;                                //清发送标志位
                }

        }
}


main.h的文件
//sbit IR_RE   = P3^2;        //红外接受中断口
sbit IR_RE   = P2^5;        //红外接受中断口
sbit led   = P2^1;        //红外接受中断口

使用特权

评论回复
92
踢球老越位| | 2009-10-14 21:28 | 只看该作者
建议楼主回家洗个澡,好好睡一觉,明天找本书看看,再理理思绪。。。

使用特权

评论回复
93
贺信|  楼主 | 2009-10-14 21:29 | 只看该作者
IR Decode.c文件
#include <reg51.h>
#include "main.h"


#define uchar unsigned char
#define uint unsigned int

uchar  T0Count;                         //定时器计数器
uchar k = 0;                                //中断后数据处理个数计数
extern bit SendFlag ;                //发送标志
       
//bit HeaderFlag  = 0;                /*数据头标志,数据头有效为1,无效为0
                                                          //用来判断下降沿来后是否要处理数据头*/



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

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计数
led=0;                                        //临时指示程序进度用
return T0Count;
/**
        if( T0Count > 30)                //电平为高,判断计数时间0.1* 60 = 6ms
        {


                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;
        }
***/
}
/**************************定时器0中断******************

定时100uS,用来解码高低电平

********************************************************/

void timer0() interrupt 1
{

        SendFlag = 1;
        T0Count++;
//        TH0         = 0x9C;                //定时100uS
//        TL0         = 0x00;

}

IR Decode.h文件
extern void mDelay(unsigned int i);
extern unsigned char IR_Decode();
extern unsigned char ReceiveData;

使用特权

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

UART.C文件
#include <reg51.h>
//#include "main.h"

#define uchar unsigned char
#define uint unsigned int



/***********************串口初始化***********************************/

#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;             //开总中断

}



/****************************串口发送**********************************/


void Uart_send (unsigned char uData)
{
        ES   = 0;             //关串口中断
        TI   = 0;             //清零串口发送完成中断请求标志
        SBUF = uData;                  //发送值
        while(TI==0)                  //等待发送
        {
                ;
        }

        TI   = 0;             //清零串口发送完成中断请求标志               
        ES   = 1;                       //允许串口中断
        //EA   = 1;
}

/**************************************************************/


UART.h文件
#include <reg51.h>

extern void Uart_initial();
extern void Uart_send (unsigned char uData);

使用特权

评论回复
95
贺信|  楼主 | 2009-10-14 21:34 | 只看该作者
initial.c


#include <reg51.h>



/*************************初始化函数****************************/
/**
void InitialINT0()                //中断0初始化
{
        IT0 = 1;                        //设置外部下降沿触发中断
        EX0 = 1;                        //开放外部中断1       
        EA  = 1;                        //开总中断
}

**/

/***************************定时器0初始化*********************************/

void InitialTimer0()
{
        TMOD = 0x02;                // 定时器0, 1工作模式2, 8位自动从装定时方式
       
        TH0         = 0x9C;                //定时100uS
        TL0         = 0x00;
        //TCON = 0x01;
       
        ET0=1;       
        EA          = 1;                          
        TR0         = 1;                        //开定时器0中断
}
/*********************


initial.h

//extern void InitialINT0();
extern void InitialTimer0();

使用特权

评论回复
96
程序匠人| | 2009-10-14 21:38 | 只看该作者
IR Decode.c文件
#include <reg51.h>
#include "main.h"


#define uchar unsigned char
#define uint unsigned int

uchar  T0Count;                         //定时器计数器
uchar k = 0;                                //中断后数据处理个数计数
extern bit SendFlag ;                //发送标志
        
//bit HeaderFlag  = 0;                /*数据头标志,数据头有效为1,无效为0
                                                          //用来判断下降沿来后是否要处理数据头*/



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

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计数
led=0;                                        //临时指示程序进度用


   SendFlag = 1;                        //置位发送标志        //增加这句

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


                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;
        }
***/
}
/**************************定时器0中断******************

定时100uS,用来解码高低电平

********************************************************/

void timer0() interrupt 1
{

   //    SendFlag = 1;                   //屏蔽这句
        T0Count++;
//        TH0         = 0x9C;                //定时100uS
//        TL0         = 0x00;

}

IR Decode.h文件
extern void mDelay(unsigned int i);
extern unsigned char IR_Decode();
extern unsigned char ReceiveData;


//另外请注意:每次上电复位后,只能发一次红外。如果要再次发红外,请先复位。(因为你的程序没有退出接收机制)

使用特权

评论回复
97
贺信|  楼主 | 2009-10-14 21:40 | 只看该作者
程序压缩打包

IR RE.rar

25.04 KB

使用特权

评论回复
98
贺信|  楼主 | 2009-10-14 21:44 | 只看该作者
本帖最后由 贺信 于 2009-10-14 21:46 编辑

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

unsigned char uSendData;

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

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

        }
***/
}

我这样时,串口上一直在发55!!!
真的是奇怪

使用特权

评论回复
99
程序匠人| | 2009-10-14 21:48 | 只看该作者
先搞定你的计数器吧。红外解码先放在一边,先确保定时中断能顺利执行。

使用特权

评论回复
100
wangyy608| | 2009-10-14 22:14 | 只看该作者
ET1 = 0;
    T0Count = 0;
    ET1 = 1;

你没开定时器0计时 ET1应该改为ET0

使用特权

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

本版积分规则