[原创] 51单片机 stm8 stm32 红外发码,红外发码距离短 过短 太近解决方法

仙景   2017-5-8 12:03 楼主
此内容由EEWORLD论坛网友仙景原创,如需转载或用于商业用途需征得作者同意并注明出处 之前做项目,要用到红外,看了网上很多例子,都不是很理想,就自己搞了一个,我们都知道红外可以传输数据,要生活中很多地方用到,红外遥控,语言数据传输,红外检测,都需要红外,那就需要产生红外的仪器,有纯硬件的,网上都有,也有软件的。 红外的特点:就是简单,价格也低,缺点就是距离近,方向性特强。 红外载波:38K比较常用,1/3占空比就可以实现,至于为什么用38K不用其他的,其实用哪个频率都可以,只要你能产生都可以,但这也要考虑到红外接收头,很多都是在一定的频率,太低,太高都接收不了。所以,38K载波频率肯定有它存在的道理。红外协议:NEC协议是众多红外遥控协议的其中一种,除NEC外,还有RC5、RC6等其它的。市面上买到的非学习型万能电视遥控器大多集成一种或多种编码是NEC型的的,这里也主要说说NEC协议。NEC 码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。 红外码.png 当然,对于这种协议,自己也可以完全定义自己专用的,这样的话,别人就解调不了,现在市场空调,每家有每家的一套做法。 红外硬件电路:电路一: 红外一.png 通过电源接个电阻再接红外灯直接接入单片机的IO口; 电路二: 红外二.png 通过电源接个电阻再接红外灯通过一个三极管接地。 我们发现两种电路都可以,如果对距离没要求,建议选第一种,可以省成本;如果对距离有要求,建议选第二种,第二种,电流大,距离远,毕竟红外发射距离跟功率有很大的关系。 软件:要产生38K的频率,那就只需要26us周期就可以了,现在的单片机都可以产生,软件模拟也很贱多,但是选择1/2,1/3……哪种的占空比,经过我测试后,发现占空比是对红外距离影响最小的。随意选择就有,我是利用定时器中断来做的,代码如下:
  1. TIM2_DeInit();[/size]
  2. TIM2_TimeBaseInit(TIM2_PRESCALER_1, 211);
  3. TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
  4. ITC_SetSoftwarePriority(ITC_IRQ_TIM2_OVF,ITC_PRIORITYLEVEL_1);
  1. void IR_Process(void)
  2. {
  3. switch(State)
  4. {
  5. case 0: // 状态初始化
  6. SendCnt = 0;
  7. Bit = 1;
  8. Pos = 1;
  9. IR_OFF;
  10. State++;
  11. break;
  12. case 1: // 发送4.5ms调制引导码
  13. if(++SendCnt < 342)
  14. {
  15. IR_TOGGLE;
  16. }
  17. else
  18. {
  19. //IR_TOGGLE;
  20. SendCnt = 0;
  21. State++;
  22. }
  23. break;
  24. case 2: // 发送4.5ms引导码
  25. if(++SendCnt < 342)
  26. {
  27. IR_OFF;
  28. }
  29. else
  30. {
  31. IR_TOGGLE;
  32. SendCnt = 0;
  33. State++;
  34. }
  35. break;
  36. case 3: // 发送一位数据
  37. ++SendCnt;
  38. if(SendCnt < 40)
  39. {
  40. IR_TOGGLE;
  41. }
  42. else if(SendCnt < 84)
  43. {
  44. IR_OFF;
  45. }
  46. else
  47. {
  48. if((IR_Data[Pos] & Bit) && (SendCnt < 168))
  49. {
  50. IR_OFF;
  51. }
  52. else
  53. {
  54. SendCnt = 0;
  55. State++;
  56. }
  57. }
  58. break;
  59. case 4: // 下一位
  60. Bit <<= 1;
  61. if(Bit >= 0x100)
  62. {
  63. ++Pos;
  64. if(Pos > IR_Data[0]) // 发送完成
  65. {
  66. State++;
  67. }
  68. else
  69. {
  70. Bit = 1;
  71. State--;
  72. }
  73. }
  74. else
  75. {
  76. State--;
  77. }
  78. break;
  79. case 5: // 发送最后一位
  80. ++SendCnt;
  81. if(SendCnt <= 40)
  82. {
  83. IR_TOGGLE;
  84. }
  85. else if(SendCnt < 84)
  86. {
  87. IR_OFF;
  88. }
  89. else
  90. {
  91. if((IR_Data[Pos] & Bit) && (SendCnt < 168))
  92. {
  93. IR_OFF;
  94. }
  95. else
  96. {
  97. SendCnt = 0;
  98. State++;
  99. }
  100. }
  101. break;
  102. default:
  103. State = 0;
  104. IR_Sended = 2;
  105. IR_ON;
  106. TIM2_Cmd(DISABLE);
  107. TimeOut(&TimeIRDelay, 0);
  108. break;
  109. }
  110. }
经过上面就可以利用stm8惊醒红外发码了,如果再发现距离不够,好像又发现不了什么问题,那我们就从最初的开始寻找,距离跟红外的功率有关,那我们可以调试电阻看看是否能改善,其次就是看看电源是否波动,我就是由于电源波动,导致距离非常近,经过寻找发现后,电源加了个滤波,红外发射距离可以更远,至少8米之外。这就是我要说的。如果有什么不对,也可以交流交流。 本帖最后由 仙景 于 2017-5-8 13:54 编辑

回复评论 (3)

除非你电源带不起啊,不然要什么滤波啊。
点赞  2017-5-8 23:09
引用: weizhongc 发表于 2017-5-8 23:09
除非你电源带不起啊,不然要什么滤波啊。

肯定带得起,如果你不是稳压电源的话,肯定有波动啊
点赞  2017-5-9 10:07
以前也弄过,距离是不远,具体原因也没搞清楚,因为接收端就是个黑盒子
点赞  2017-5-9 12:53
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复