6809|17

78

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

51自制遥控器出现问题(有代码) [复制链接]

利用AT89C51定时中断产生的载波频率达不到38K,只有12K左右,这是什么原因?

还有计数部分 endcount=223,产生9MS起始码,这是怎么计算的啊?按26us中断一次9MS应该是346啊?

例码如下:


#include
static bit OP;        //红外发射管的亮灭
static unsigned int count;       //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag;      //红外发送标志
char iraddr1;  //十六位地址的第一个字节
char iraddr2;  //十六位地址的第二个字节

sbit IR=P1^0;

void SendIRdata(char p_irdata);
void delay();

void main(void)
{
  count = 0;
  flag = 0;
  OP = 0;
  IR = 0;

  EA = 1; //允许CPU中断
  TMOD = 0x11; //设定时器0和1为16位模式1
  ET0 = 1; //定时器0中断允许


  TH0 = 0xFF;
  TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次  
  TR0 = 1;//开始计数

iraddr1=3;
iraddr2=252;


  do{
      delay();
    SendIRdata(12);
  }while(1);
}

//定时器0中断处理
void timeint(void) interrupt 1
{
  TH0=0xFF;
  TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  count++;

  if (flag==1)
  {
    OP=~OP;
  }
  else
  {
    OP = 0;
  }
  IR = OP;
}


void SendIRdata(char p_irdata)
{
  int i;
  char irdata=p_irdata;

  //发送9ms的起始码
  endcount=223;
  flag=1;
  count=0;
  do{}while(count
  //发送4.5ms的结果码
  endcount=117;
  flag=0;
  count=0;
  do{}while(count
  //发送十六位地址的前八位
  irdata=iraddr1;
  for(i=0;i<8;i++)
  {

     //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count
    //停止发送红外信号(即编码中的高电平)
     if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
     {
       endcount=41;  //1为宽的高电平
     }
    else
     {
     endcount=15;   //0为窄的高电平
     }
    flag=0;
    count=0;
    do{}while(count
    irdata=irdata>>1;
  }

  //发送十六位地址的后八位
  irdata=iraddr2;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count
     if(irdata-(irdata/2)*2)
     {
        endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count
     irdata=irdata>>1;
  }

  //发送八位数据
  irdata=p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count
     irdata=irdata>>1;
  }

  //发送八位数据的反码
  irdata=~p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count
     irdata=irdata>>1;
  }

  endcount=10;
  flag=1;
  count=0;
  do{}while(count   flag=0;
}

void delay()
{
  int i,j;
  for(i=0;i<400;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}

最新回复

楼主,我教你怎么解决这个办法! 给我邮箱发邮件:xqlftg@163.com  详情 回复 发表于 2009-3-6 14:32
点赞 关注

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
先来说说那38K的问题,f=1/T,周期T为26us,但是中断应该是T/2=13us.因为38K是在26us完成一个周期(即一个高一个低电平).

然后再说第二个计算的问题.
按26us中断一次9ms应该是346次.但如果你将endcount=346这样赋值,那么程序总执行时间约为369*26us+346(T0中断服务程序中消耗的时长).
所以说所要求的endcount应该是9ms/(26us+T0中断服务程序中消耗的时长).

看你的程序是成C写的,C程序的可读性是高,但是程序执行的时间很难把握(这与编译器有关).
而且中断时间要改为13us的话,就要保证T0中断服务程序要在13us内完成,否则就会影响下次中断时间.

调整一下试试吧.
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
谢谢楼上的,解释的很到位,特别是中断服务程序要在13us内完成,否则会影响下次中断时间,的确很到位,是高手!

但有很好的解决办法吗?能否提供参考实例?
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

4
 
没有什么太好的解决办法,只能是严格控制代码.
因为我只用汇编,所以对代码的控制比较方便.
不过用C的话,只能尽可能的让代码行少点,判断少点.可是你的中断程序已经够简练的了.
实际生成波形,用显波器看看效果吧.
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

5
 
可以计算代码所需要的周期,比如代码需要3us,那你只需要定时10us就可以了
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

6
 
用示波器看过,定时13US,大约有19KHZ(12M晶振),以后怎么减少定时时间,频率就没有变化。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

7
 
定时再怎么减少,频率都不再变了。那肯定是由于中断程序中的时间消耗太大。
可以试试在中断中用汇编程序。

你可以这样先试一下,在中断中就执行一条对一个引脚的反转的指令。当改变定时时,频率一定会变。
这就可能证明出,是由于中断程序消耗时间过长,引起你遇到的问题。
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

8
 
void timeint(void) interrupt 1
{
  TH0=0xFF;
  TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  count++;

  if (flag==1)
  {
    OP=~OP;
  }
  else
  {
    OP = 0;
  }
  IR = OP;
}
用自动装载模式,这两句可去掉
  TH0=0xFF;
  TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次


 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

9
 
if (flag==1)
  {
    IR=~IR;
  }
  else
  {
    IR = 0;
  }
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

10
 
cyymycc :你好!
去掉定时初值的话,将不产生波形。怎么办啊?
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

11
 
LZ 用的是不适6212的编码方式?
do{}while(count 否则就死循环了
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

12
 
还得请教一下楼主,数据是从哪个端口发出的,以前都是用遥控器,现在也想做个独立发射的
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

13
 
bu会吧
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

14
 
定时器时间= 周期/2
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

15
 
一定要先搞清是什么编码的,然后按编码来解,才能可能正确
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

16
 
发射的端口为P3^3
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

17
 

我的
红外线串口通信(波特率为2400b/s,可靠发送距离能达到8米以上)很好用、配套的红外线接收板(不使用单片机,价格便宜,使用方便,可以和计算机进行串口通信)。

西安杨工单片机博客

http://c8051fmcu.blog.sohu.com
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

18
 
楼主,我教你怎么解决这个办法!
给我邮箱发邮件:xqlftg@163.com
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表