51单片机+红外发射模块(38k+NEC),这代码对不对?有详细...

2020-01-27 11:34发布

哪位大神帮小弟看一下这段代码,是网上载的,我大概修改了一下几个数值,因为我觉得原来的错的,结果红外发射模块发射不了,用原来载下来的数值执行起来也是不行,小弟这里没示波器,这份代码小弟很详细的给它添加了很多注释,只求有心的前辈帮一下小弟,帮忙看一下哪里不对。。。。 38k + NEC协议。。。。作者没有使用循环去发送 用户码 用户反码 键码 键反码,所以代码看起来比较多,其实是很少的。。。
捣鼓了我好几天了一直不知道为什么不行,啊啊啊啊啊啊 拜托前辈了!帮了小弟这个忙,什么都好说
  1. //#include <AT89X51.h>
  2. #include <reg51.h>

  3. static bit OP;                                   //红外发射管的亮灭控制位
  4. static unsigned int count;                //延时计数器
  5. static unsigned int endcount;         //终止延时计数
  6. static unsigned char flag;                //红外发送标志
  7. sbit  P3_4=P3^4;
  8. char iraddr1; //十六位地址的第一个字节
  9. char iraddr2; //十六位地址的第二个字节
  10. void SendIRdata(char p_irdata);//发送子函数
  11. void delay();


  12. void main(void)                                 
  13. {
  14.         count = 0;
  15.         flag = 0;                //无载波
  16.         OP = 0;                        //不亮
  17.         P3_4 = 0;                //在后面会发现用OP赋值的
  18.         EA = 1;                 //允许CPU中断
  19.         TMOD = 0x11;         //设定时器0和1为16位模式1  
  20.         ET0 = 1;                 //定时器0中断允许
  21.         TH0 = 0xFF;  
  22.         TL0 = 0xE6;         //设定时值0为38K 也就是每隔26us中断一次
  23.         TR0 = 1;                //开始计数
  24.         iraddr1=3;                //自定义的一个地址
  25.         iraddr2=252;        //地址反码

  26.         do
  27.         {
  28.                 delay();                 //延时
  29.                 SendIRdata(221); //发送数据

  30.         }while(1);
  31. }

  32. //定时器0中断处理
  33. void timeint(void) interrupt 1
  34. {
  35.         TH0=0xFF;
  36.         TL0=0xE6;                 //设定时值为38K 也就是每隔26us中断一次
  37.         count++;
  38.        
  39.         if (flag==1)         //如果是待发送的有效数据flag=1,就在此产生载波(亮灭交变)
  40.         {
  41.                 OP=~OP;                //产生方波其实就是调制后的高电平哈
  42.         }
  43.         else
  44.         {
  45.                 OP = 0;                 //发送低电平
  46.         }
  47.        
  48.          P3_4 = OP;           //往发射模块的 IO口发送出去哈
  49. }

  50. void SendIRdata(char p_irdata)                //发送数据子函数
  51. {
  52.         int i;
  53.         char irdata=p_irdata;
  54.        
  55.         /***************************************************************/
  56.        
  57.         //发送9ms的起始码       
  58.         //引导码是9ms的高电平,9000us/26us = 346
  59.         endcount = 346;
  60.         flag=1;                                          //载波模式有效
  61.         count=0;
  62.         while(count<endcount);        //等待中断,在中断中发送载波,总时间为9ms


  63.         //发送4.5ms的结果码,并是载波模式无效,也就是发送4.5ms的低电平
  64.         //结果码是 4500us/26us = 173
  65.         endcount = 173;
  66.         flag=0;
  67.         count=0;
  68.         while(count<endcount);

  69.         /***************************************************************/
  70.         //发送十六位地址的前八位,iraddr存的是地址码
  71.         irdata=iraddr1;
  72.         for(i=0;i<8;i++)
  73.         {
  74.                 //一个周期里规定先以高电平开始,在以低电平结束。先发送0.56ms的38KHZ“1”的红外波(即编码中0.56ms的高电平)
  75.                 endcount = 21;                        //560us/26us = 21
  76.                  flag=1;
  77.                 count=0;
  78.                 while(count<endcount); //等待中断


  79.                   if(irdata-(irdata/2)*2)        //判断二进制数个位为1还是0
  80.                   {
  81.                         endcount=64; //如果是 1,修改 endcount = 64, 64*26us = 1680us
  82.                 }
  83.                   else                 
  84.                   {
  85.                         endcount=21;//如果是0,则低电平 21*26us = 560us;
  86.                 }
  87.                 flag=0; //因为发送的 0,所以调制后就是一连串连续的低电平,所以 flag=0,载波模式无效
  88.                 count=0;
  89.                
  90.                 while(count<endcount); //等待中断发送
  91.                
  92.                 irdata=irdata>>1;//依次取位
  93.                        
  94.         }

  95.         //发送十六位地址的后八位

  96.        
  97.         irdata=iraddr2;        //此处已经是地址的反码       
  98.         for(i=0;i<8;i++)
  99.         {
  100.                 endcount = 21;
  101.                 flag=1;
  102.                 count=0;
  103.                
  104.                 while(count<endcount);
  105.                
  106.                 if(irdata-(irdata/2)*2)
  107.                 {
  108.                         endcount = 64;

  109.                 }
  110.                 else
  111.                 {
  112.                         endcount = 21;
  113.                 }

  114.                 flag=0;
  115.                 count=0;
  116.                
  117.                 while(count<endcount);
  118.                
  119.                 irdata=irdata>>1;
  120.         }/***************************************************************/
  121.         //发送八位数据
  122.        
  123.         irdata=p_irdata;
  124.        
  125.         for(i=0;i<8;i++)
  126.         {
  127.                 endcount = 21;
  128.                 flag=1;
  129.                 count=0;
  130.                
  131.                 while(count<endcount);
  132.                
  133.                 if(irdata-(irdata/2)*2)
  134.                 {
  135.                         endcount=64;;
  136.                        
  137.                 }
  138.                 else
  139.                 {
  140.                         endcount = 21;
  141.                 }
  142.                
  143.                 flag=0;
  144.                 count=0;
  145.                
  146.                 while(count<endcount);
  147.                
  148.                 irdata=irdata>>1;               
  149.         }

  150.         //发送八位数据的反码
  151.         irdata=~p_irdata;                //要将数据位取反
  152.        
  153.         for(i=0;i<8;i++)
  154.         {
  155.                 endcount = 21;
  156.                 flag=1;
  157.                 count=0;
  158.                
  159.                 while(count<endcount);
  160.                
  161.                 if(irdata-(irdata/2)*2)
  162.                 {
  163.                         endcount = 64;
  164.                 }
  165.                 else
  166.                 {
  167.                         endcount = 21;
  168.                 }
  169.                
  170.                 flag=0;
  171.                 count=0;
  172.                
  173.                 while(count<endcount);
  174.                
  175.                 irdata=irdata>>1;
  176.         }
  177.        
  178.   //到这边一帧的数据已经按照 38K + NEC发送出去了
  179. }


  180. void delay()
  181. {
  182.         int i,j;
  183.        
  184.         for(i=0;i<400;i++)
  185.         {
  186.                 for(j=0;j<100;j++)
  187.                 {
  188.                 }
  189.         }
  190. }

复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
29条回答
zjx_arm
2020-01-28 16:21
zjykwym 发表于 2013-4-9 14:05
中断要13us一次,不是26us

我把定时器的TH跟TL改了。。。改成TH1 = 0XFF; TL1 = 0XF3,我算了一下应该是13us了。。。前辈帮忙也算一下。。。我把定时器改成13us之后我就把程序中的全部 encount全部乘以2翻倍,达到 NEC协议的要求。。。结果还是没反应啊。。。唉,前辈留个QQ号,帮小弟一把,小弟感激不尽啊!

一周热门 更多>