打印

关于红外解码的程序

[复制链接]
6286|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Jutinlee|  楼主 | 2013-4-15 20:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
此程序hex文件在AT89s52芯片上可以运行,验证无误。但是加载到STC15L204系列上运行时无反应,可能是解码不成功!!!,两者用的是同样的程序。求高手指导!!!

#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define uint unsigned int
#define uchar unsigned char
sbit ir=P3^3 ;//定义红外接收端口
sbit P1_6=P1^6 ; //定义电机控制端口1
sbit P3_7=P3^7 ; //定义电机控制端口2
uchar key_code=0 ;//遥控键值
uchar new_code=0 ;//有无新按键
uint buf_key_code=0 ;//键值暂存
uchar key_bit_count=0 ;//键编码脉冲计数
uint count=0 ;//定时中断次数计数
uint buf_count=0 ;//定时中断计数暂存
uchar common_code_count=0 ;//前导码脉冲计数
uchar ir_status=0 ;//脉冲接收器所处的状态,0:无信号,1:系统码接收区,2:数据编码接收区
unsigned char n,n1,n2,n3,n4;

///延时子程序1 10us
void delay_10us(unsigned char y)
{
    unsigned char x ;
    for(x=y;x>0;x--);
}
/////初始化
void init(void)
{
     ir=1 ;
    //红外端口写 1
EA=1 ;
    //开总中断
TMOD=0x22 ;
    //定时器0跟定时器1,模式2,8 位自动装载模式
    TH0=0Xd1 ;
    //定时50us
   TL0=0Xd1 ;
    IT0=1 ;
    //INT1 下降沿触发
    ET0=1 ;
    //允许定时器中断
    EX0=1 ;
//允许外部中断
}
/***********************************************
定时器中断
***********************************************/
///定时器中断
void time0()interrupt 1
{
count++;
//定时器中断次数累加
}
/**********************************************
   外部中断,红外解码程序
**********************************************/
///外部中断
void int1()interrupt 0
{
   
    TR0=1 ;
    //开定时器中断
    //如果信号合法,则放入buf_count,count 清 0,对下一个脉冲信号计时
    if(count>12&&count<270)
    {
        buf_count=count ;
        count=0 ;
    }
    delay_10us(10);
    //延时 100us 以消除下降沿跳变抖动
    //INT1 引脚稳定为低电平,则表法确实是信号,count 重新计时,因上面延时了50us,故要 补偿 1 次T0中断
    if(ir==0)
    {
        count=2 ;
    }
    //若收到的信号合法,则再进行信号分析
    if(buf_count>12&&buf_count<270)
    {
        //如果之前未收到引导码
        if(ir_status==0)
        {
            //判断是否引导码 13.5ms
            if(buf_count>210&&buf_count<270)
            {
                ir_status=1 ;
                //系统标记
                buf_count=0 ;
                //
            }
        }
        ///收到引导码
        else if(ir_status==1)
        {
            
            //若收完26 个脉冲
            if(common_code_count>=25)
            {
               
                ir_status=2 ;
                //数据解码标记
                common_code_count=0 ;
                //系统码计算清零
                buf_count=0 ;
                // 中断计数暂存清0
            }
            else if((buf_count>40&&buf_count<70)||(buf_count>12&&buf_count<32))
            {
                buf_count=0 ;
                common_code_count++;
                //每收到一个信号自加 1
            }
            
        }
        
        //进入数据编码接收
        else if(ir_status==2)
        {
            //收到数据少于8 位,则将收到的数据写入buf_key_code
            if(key_bit_count<8)
            {
               
                if(buf_count>40&&buf_count<70)
                {
                    buf_count=0 ;
                    buf_key_code>>=1 ;
                    buf_key_code|=0x80 ;
                    //收到 1
                    key_bit_count++;
                    //数据脉冲累加
                }
                //收到0
                else if(buf_count>12&&buf_count<32)
                {
                    buf_count=0 ;
                    buf_key_code>>=1 ;
                    //收到0
                    key_bit_count++;
                }
            }
            //若收完 8 位数据则做以下处理
            else
            {
                ir_status=0 ;
                //接收状态返回到空闲
                key_code=buf_key_code ;
                key_bit_count=0 ;
                buf_key_code=0 ;
                buf_count=0 ;
                TR0=0 ;
                new_code=1 ;
               
            }
        }
    }
}
/*************************************
   主程序
*************************************/
void main()
{
init();_//中断初始化。
    while(1)
    { _
        while(!new_code);
        //判断是否有新按键,如果有则执行下面程序,没有则一直循环
        switch(key_code%16) //判断哪个按键。   
       {
case 1:{ P1_6=1; P3_7=0; };break;
case 2:{P1_6=0;P3_7=1; };break;
    case 3:{P1_6=1; P3_7=1; };break;
   }
   new_code=0; //按键标志位清"0",进入下一次循环判断。
    }
   }

相关帖子

沙发
rgh111| | 2013-4-15 21:09 | 只看该作者
虽然都叫51单片机, 而且貌似相同的程序也能"run"起来. 但是它的时钟系统和一些功能寄存器的设置还是有些许区别的.

楼主可以查两方面的原因:
1. 检查时钟是不是调在同一个频率上, 因为红外接掐时间的关键.
2. 看看IO的配置是否满足接收收响应条件.

搞定这两个问题, 有99%的机会程序"欧啦".:lol

使用特权

评论回复
板凳
dirtwillfly| | 2013-4-15 21:57 | 只看该作者
估计问题出在时钟频率的设置上。STC15L204是1T的单片机,时钟频率比较快

使用特权

评论回复
地板
airwill| | 2013-4-15 22:49 | 只看该作者
在AT89s52芯片上可以运行,验证无误。但是加载到STC15L204系列上运行时无反应,
估计最大可能是 处理器的频率不同导致的。STC15L204的单周期快了很多

使用特权

评论回复
5
coody| | 2013-4-15 23:11 | 只看该作者
由于STC15L204EA的速度比89S52快得多,和资源的问题,所以注意:
1、凡是软件延时的程序,都要改慢。
2、TC15L204EA目前STC只出了A版本,而A版本的外中断不能使用,否则会死机。

很多例子证明,红外接收使用外部中断没有用查询的可靠,因为外部中断对干扰比较敏感,即使是几个us的干扰都能进中断,这个在LED PWM驱动的灯带红外遥控的比较容易碰到,跟使用什么MCU没关系,当然用外部中断一样可以做得可靠,程序要做些滤波处理。我 从来都用查询,简单可靠。

STC的官网有用于STC15系列的查询方式红外接收完成的 工程程序。

使用特权

评论回复
6
天命风流| | 2013-4-16 11:03 | 只看该作者
好东西!!!

使用特权

评论回复
7
Jutinlee|  楼主 | 2013-4-16 14:46 | 只看该作者
rgh111 发表于 2013-4-15 21:09
虽然都叫51单片机, 而且貌似相同的程序也能"run"起来. 但是它的时钟系统和一些功能寄存器的设置还是有些许 ...

昨晚发帖的时候忘记加上去了,两个单片机的时钟频率是一样的,而且IO口也做了相应的改动。应该不是这两个问题!!

使用特权

评论回复
8
Jutinlee|  楼主 | 2013-4-16 14:49 | 只看该作者
airwill 发表于 2013-4-15 22:49
在AT89s52芯片上可以运行,验证无误。但是加载到STC15L204系列上运行时无反应,
估计最大可能是 处理器的频 ...

我也觉得这个可能性比较大,还在调。。。:'(烦死了

使用特权

评论回复
9
Jutinlee|  楼主 | 2013-4-16 14:50 | 只看该作者
coody 发表于 2013-4-15 23:11
由于STC15L204EA的速度比89S52快得多,和资源的问题,所以注意:
1、凡是软件延时的程序,都要改慢。
2、TC ...

有没有那个“用于STC15系列的查询方式红外接收完成的 工程程序”的网址,我在官网上没找到。

使用特权

评论回复
10
SunFans| | 2013-4-16 18:48 | 只看该作者

使用特权

评论回复
11
Jutinlee|  楼主 | 2013-4-17 13:28 | 只看该作者
谢谢各位大神,问题已经解决。小弟不胜感激!!!

使用特权

评论回复
12
clarkewayne| | 2013-4-17 16:59 | 只看该作者
由于STC15L204EA的速度比89S52快得多,和资源的问题,所以注意:
1、凡是软件延时的程序,都要改慢。
2、TC15L204EA目前STC只出了A版本,而A版本的外中断不能使用,否则会死机。

很多例子证明,红外接收使用外部中断没有用查询的可靠,因为外部中断对干扰比较敏感,即使是几个us的干扰都能进中断,这个在LED PWM驱动的灯带红外遥控的比较容易碰到,跟使用什么MCU没关系,当然用外部中断一样可以做得可靠,程序要做些滤波处理。我 从来都用查询,简单可靠。

STC的官网有用于STC15系列的查询方式红外接收完成的 工程程序。


同意

使用特权

评论回复
13
china0043| | 2013-11-11 11:32 | 只看该作者
单片机如何对多个红外接收管同时解码

使用特权

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

本版积分规则

1

主题

7

帖子

0

粉丝