标题: 单片机模拟红外发射源程序IR-send [打印本页]

作者: uid0416    时间: 2018-1-10 12:35
标题: 单片机模拟红外发射源程序IR-send
单片机源程序如下:
  1. 单片机模拟红外遥控器发射的C语言程序
  2. //********************************************单片机红外发射*******************************************
  3. #include "reg52.h"
  4. sbit ir=P1^0;//红外发射管控制脚,使用24M晶振
  5. sbit ka=P2^0;
  6. sbit kb=P2^1;
  7. unsigned int count, set_count; //中断计数,设定中断次数
  8. bit irflag,keyflag;   //红外发送标志位,按键标志位
  9. unsigned char irsys[]={0x00,0xff};//16位用户码
  10. unsigned char irdata,ircode; //发送的红外数据
  11. //---------------------------------------------------------------------------
  12. void delay(unsigned int a)//延时约1ms,晶振24M ,此处延时不需很精确
  13. {
  14. unsigned char i;
  15. while(--a!=0)
  16. for(i=300;i>0;i--); //若是12M晶振i=125
  17. }
  18. //---------------------------------------------------------------------------
  19. void keyscan() // 按键扫描
  20. {
  21.    if(ka==0){keyflag=1;irdata=0x0a;} //a键按下,则发射数据0x0a
  22.        if(kb==0){keyflag=1;irdata=0x0b;} //b键按下,则发射数据0x0b
  23. }
  24. //---------------------------------------------------------------------------
  25. void ir_sendbyte()    //红外发送一个字节数据
  26. {
  27. unsigned char i;
  28. for(i=0;i<8;i++)    //发送8位数据
  29. {
  30.    set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
  31.    irflag=1;      //启动红外发射二极管发射
  32.    count=0;     //中断计数先清0
  33.    TR0=1;      //开启定时器0
  34.    while(count<set_count); //等待发送完
  35.    TR0=0; //关闭定时器0
  36.     if(ircode&0x01) set_count=130;//130; //判断红外编码最低位,若为1则1.69ms的低电平 (//后为12M晶振下的数值)
  37.      else set_count=43;//35;    //为0则0.565ms的低电平 (//后为12M晶振下的数值)
  38.    irflag=0; //低电平则不发射
  39.    count=0; //中断计数清0
  40.    TR0=1; //开启定时器0
  41.    while(count<set_count); //等待发送完
  42.    TR0=0; //关闭定时器0
  43.    ircode=ircode>>1; //将数据右移,即从低位到高位发送
  44. }
  45. }
  46. //---------------------------------------------------------------------------
  47. void ir_send() //发送红外数据
  48. {
  49. set_count=692;//672; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)
  50. irflag=1;    //启动红外发射二极管发射
  51. count=0;    //中断计数清0
  52. TR0=1;
  53. while(count<set_count);
  54. TR0=0;
  55. set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
  56. irflag=0; //低电平则不发射
  57. count=0;
  58. TR0=1;
  59. while(count<set_count); //等待发送完
  60. TR0=0;
  61. ircode=irsys[0]; //发送16位用户码的前1-8位
  62. ir_sendbyte();
  63. ircode=irsys[1]; //发送16位用户码的前9-16位
  64. ir_sendbyte();
  65. ircode=irdata;   //发送8位数据码
  66. ir_sendbyte();
  67. ircode=~irdata; //发送8位数据反码
  68. ir_sendbyte();
  69. set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
  70. irflag=1;
  71. count=0;
  72. TR0=1;
  73. while(count<set_count);
  74. TR0=0;
  75. ir=1;
  76. delay(23);    //延时23ms(编码中的23ms低电平)
  77. set_count=692;//670; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)
  78. irflag=1;
  79. count=0;
  80. TR0=1;
  81. while(count<set_count);
  82. TR0=0;
  83. set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
  84. irflag=0;
  85. count=0;
  86. TR0=1;
  87. while(count<set_count);
  88. TR0=0;
  89. set_count=43;//35;   //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
  90. irflag=1;
  91. count=0;
  92. TR0=1;
  93. while(count<set_count);
  94. TR0=0;
  95. ir=1;    //发射完了关闭红外发射二极管
  96. }
  97. //---------------------------------------------------------------------------
  98. void timer0_init()    //定时器初始化
  99. {
  100. EA=1;
  101. TMOD=0x02;     //定时0 8位自动重装模式
  102. ET0=1;
  103. TH0=0xe6;//0xf3;   //定时13us,38K红外矩形波,晶振24M (//后为12M晶振下的数值)
  104. TL0=0xe6;   
  105. }
  106. //---------------------------------------------------------------------------
  107. void main()
  108. {
  109. timer0_init(); //定时0初始化
  110. count=0;     //中断计数先清0
  111. irflag=0;     //红外发射标志先置0
  112. while(1)
  113. {
  114. keyscan();   //键值扫描
  115.    if(keyflag)   //若有按键按下
  116.    {
  117.     delay(10);
  118.     ir_send();   //发送红外编码
  119.     delay(500);
  120.     keyflag=0;   //按键标志清零
  121. delay(100);
  122.    }
  123. }
  124. }
  125. //---------------------------------------------------------------------------
  126. void timer0() interrupt 1 //定时器0中断
  127. {
  128. count++;
  129. if(irflag==1) ir=~ir; //有发射标志,则发射38khz的矩形波
  130.    else ir=1;     //否则不发射,即相当于发射编码中的低电平
  131. }
  132. /*说明:本人经多次调试发现若在24M晶振下使用,发射很正常,而在12M晶振下发射的数据则稳定性要差很多,正在完善中*/
  133. /*程序编写:落叶*/
复制代码

所有资料51hei提供下载:
IR--send(单片机模拟红外发射) c.rar (1.53 KB, 下载次数: 205)



作者: chanofeng    时间: 2018-7-19 22:15
好帖子,感谢楼主
作者: vnbo    时间: 2018-9-26 09:21
赶上写论文,继续啊,找了好多资料,都看的云里雾里的
作者: wade_tan    时间: 2018-9-26 10:16
好资料,谢谢。
作者: littlejia    时间: 2018-10-31 21:30
下载下来,试一试
作者: 铃恋仙    时间: 2018-11-13 16:28
感谢楼主的分享
作者: 橘子先生    时间: 2018-11-18 21:28
最近在看有关红外发射,试了一下楼主12M晶振下的程序,抓到的一个波形,不知道是不是正确的,楼主大神能不能提供发送的波形,和接受到的波形呢,根据程序没能推出抓到的波形对不对
作者: jemery1030    时间: 2019-7-27 17:40
感謝無私分享
作者: 1530974286    时间: 2019-9-28 22:52
请问一下这个接线是怎么接的呀,我在做一个把ad转换获得的数字信号通过红外发射,只用一个红外发射管的话可以发送吗,怎么接线呀
作者: 职教电子    时间: 2020-3-14 09:15
这个程序我用STC试了一下,24M只是比12M好些。关键是9+4.5的引导有时竟成6.6+3.3,难道是按键产生的干扰影响了中断?
作者: 职教电子    时间: 2020-3-19 15:05
发现这个周期26us很准,但占空比不确定,不知道是怎么回事?
作者: 职教电子    时间: 2020-3-21 11:20
职教电子 发表于 2020-3-19 15:05
发现这个周期26us很准,但占空比不确定,不知道是怎么回事?

终于解决了,准确率100%.
作者: a461624201    时间: 2020-4-5 14:47
本帖最后由 a461624201 于 2020-4-5 17:13 编辑

发个我对这个程序理解,stc15f104e,未测试,逻辑分析仪查看没错。

红外发射.zip

43.42 KB, 下载次数: 34, 下载积分: 黑币 -5


作者: 行者无边    时间: 2020-6-5 10:05
谢谢楼主分享,好评
作者: 行者无边    时间: 2020-7-1 10:47
职教电子 发表于 2020-3-14 09:15
这个程序我用STC试了一下,24M只是比12M好些。关键是9+4.5的引导有时竟成6.6+3.3,难道是按键产生的干扰影 ...

您好问下,这个问题怎么解决的,测试中也是遇到引导码变成6.6+3.3,非常感谢
作者: kavin21513    时间: 2021-8-2 16:10

在12M晶振下发射的数据则稳定性要差很多的原因:
实验发现, 采用12M的晶振,中断最少要20us,也就是周期最少要40us了
如果采用24M晶振,就可以13us中断,产生周期为26us的38K载波.
所以要采用24M晶振.不然速度不够.




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1