找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 15880|回复: 20
收起左侧

关于红外发射的问题

  [复制链接]
ID:20083 发表于 2010-9-4 16:39 | 显示全部楼层 |阅读模式

以下是51hei板子自带红外发射程序一部分

//发送9ms的起始码
  endcount=223;
  flag=1;
  count=0;
  do{}while(count<endcount);

 

这里写发送9ms起始码,设置endcountwei 223

 

想请教下,223是怎么算出来的,我自己老是算不出这个数,谢谢!

 

 

 

 

 

 

以下是完整程序


#include <AT89X51.h> 
static bit OP;        //红外发射管的亮灭
static unsigned int count;       //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag;      //红外发送标志
char iraddr1;  //十六位地址的第一个字节
char iraddr2;  //十六位地址的第二个字节
void SendIRdata(char p_irdata);
void delay();
void main(void) 
{
  count = 0;
  flag = 0;
  OP = 0;
  P3_4 = 0;
  EA = 1; //允许CPU中断 
  TMOD = 0x11; //设定时器0和1为16位模式1 
  ET0 = 1; //定时器0中断允许 

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

  do{
      delay();
      SendIRdata(0x55);// 在此填入发射数据
  }while(1);
} 
//定时器0中断处理 
void timeint(void) interrupt 1 
{ 
  TH0=0xFF; 
  TL0=0xE5; //设定时值为38K 也就是每隔26us中断一次
  count++;
  if (flag==1)
  {
    OP=~OP;
  }
  else
  {
    OP = 0;
  }
  P3_4 = OP;
} 

void SendIRdata(char p_irdata)
{
  int i;
  char irdata=p_irdata;
  //发送9ms的起始码
  endcount=223;
  flag=1;
  count=0;
  do{}while(count<endcount);
  //发送4.5ms的结果码
  endcount=117;
  flag=0;
  count=0;
  do{}while(count<endcount);
  //发送十六位地址的前八位
  irdata=iraddr1;
  for(i=0;i<8;i++)
  {
     //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
//停止发送红外信号(即编码中的高电平)
     if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
     {
       endcount=41;  //1为宽的高电平
     }
    else
     {
     endcount=15;   //0为窄的高电平
     }
    flag=0;
    count=0;
    do{}while(count<endcount);
    irdata=irdata>>1;
  }
  //发送十六位地址的后八位
  irdata=iraddr2;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
        endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据
  irdata=p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据的反码
  irdata=~p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  endcount=10;
  flag=1;
  count=0;
  do{}while(count<endcount);
  flag=0;
}
void delay()
{
  int i,j;
  for(i=0;i<400;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}

回复

使用道具 举报

ID:20083 发表于 2010-9-4 16:41 | 显示全部楼层
以上是51hei自带的一个完整程序 以下是程序一部分 //发送9ms的起始码 endcount="223; " flag="1; " count="0; " do{}while(count
回复

使用道具 举报

ID:1 发表于 2010-9-4 17:12 | 显示全部楼层

稍等 马上回复

回复

使用道具 举报

ID:20083 发表于 2010-9-4 17:15 | 显示全部楼层
真是太感谢了,呵呵
回复

使用道具 举报

ID:1 发表于 2010-9-4 21:21 | 显示全部楼层
  定时器0中断,每隔26us中断一次,  而这个223*26us 就是38k方波发射时间,
但是由于是c语言写的代码,效率有点低,我们没有办法直接计算出代码执行所需要的时间,所以还需要少算一点这时间值,因为其他的代码运行也需要时间。取223这样大约是发射9ms的的38k方波,这是个经验值,当然最好是要对着示波器验证一下,以保证刚好为9ms
回复

使用道具 举报

ID:20083 发表于 2010-9-4 21:32 | 显示全部楼层

原来是这样子啊。。我也是拿223X26,但觉得差好多,呵呵

 

 endcount=41;  //1为宽的高电平  代表1.685ms

 

endcount=10; 代表0.56ms

 

这些都是靠经验啊?有点郁闷,呵呵

回复

使用道具 举报

ID:1 发表于 2010-9-4 21:54 | 显示全部楼层

那我告诉你一招软件调试的方法吧,可把误差减到最小

 

首先在工程里把晶振设置为12.0M  debug框里选择 use simulator  并且要goto main打勾

 

在这2个个地方设置断点

其实这2个断点中间的代码就是在发射38k方波

001.jpg

记录程序运行到第一个断点的时间为1.49654400
002.jpg

程序运行到第二个断点的时间为1.50511800

 

所花的时间为1.50511800秒 -1.49654400秒=0.008574秒 ,和9ms已经差不远了 

 

然后你可以采用改变那个数字或者加入减少代码的方法把时间调试到1个微妙都不差,这也不是很难的事情

 

  我们用c语言编写这类的时候  要做到精确  也不是很难的  你需要首先计算出一个大概的时间 然后慢慢修改调试至最精确的值

[此贴子已经被作者于2010-9-5 0:51:01编辑过]
回复

使用道具 举报

ID:20083 发表于 2010-9-4 22:31 | 显示全部楼层
哈哈,实在感谢!
回复

使用道具 举报

ID:44179 发表于 2013-1-30 13:37 | 显示全部楼层

这个代码是NEC 发射的程式,各位大侠是否有RC5 发射的代码呢?

回复

使用道具 举报

ID:65464 发表于 2014-8-26 09:44 | 显示全部楼层
不错下来看看!!
回复

使用道具 举报

ID:66367 发表于 2014-9-18 22:33 | 显示全部楼层
为了 m比 回一个
回复

使用道具 举报

ID:67796 发表于 2014-11-29 13:23 | 显示全部楼层
admin 发表于 2010-9-4 21:54
那我告诉你一招软件调试的方法吧,可把误差减到最小
&nbsp;
首先在工程里把晶振设置为12.0M&nbsp; debug ...

这个方法确实是能解决一时问题。

代码的其中一个价值在于复用,如果写作函数调用,稍微改变下调用的结构,整个就得重算一遍。

看了您在 红外万能学习型遥控器_c  的代码,用了_nop_()在一定程度上回避了这一算法的缺陷,倒是更有借鉴之处。

也难怪,可能真没有比较完满的解决办法,不然宋老师的视频不至于跳过这个不讲。
回复

使用道具 举报

ID:58581 发表于 2014-12-18 09:27 | 显示全部楼层
学习了!!!
回复

使用道具 举报

ID:37147 发表于 2015-1-12 21:57 | 显示全部楼层
程序看起来好累 虽然看不懂  但坚持学习!!!!
回复

使用道具 举报

ID:92665 发表于 2015-11-1 15:04 | 显示全部楼层
现在还是菜鸟,红外的程序只能慢慢看了
回复

使用道具 举报

ID:68356 发表于 2017-1-26 17:07 | 显示全部楼层
好动西,收藏了
回复

使用道具 举报

ID:152917 发表于 2017-3-29 11:26 | 显示全部楼层
棒棒棒
回复

使用道具 举报

ID:185661 发表于 2017-5-15 19:22 | 显示全部楼层
好东西,
回复

使用道具 举报

ID:276399 发表于 2018-1-21 19:12 | 显示全部楼层
好资料,51黑有你更精彩
回复

使用道具 举报

ID:272080 发表于 2018-2-5 13:19 | 显示全部楼层
if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0   楼主可以解释一下这个代码吗  这里不是很看得懂了
回复

使用道具 举报

ID:282408 发表于 2018-2-5 17:17 | 显示全部楼层
0.5秒内检测到两个24v脉冲不动作,继续检测   当0.5秒只检测到一个为脉冲信号为异常  并报警,人工复位,有意向联系 微信tfktfk
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表