找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1833|回复: 6
打印 上一主题 下一主题
收起左侧

单片机红外遥控的功能如何设置?程序有问题

[复制链接]
跳转到指定楼层
楼主
ID:473410 发表于 2019-2-18 17:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
板子上有一个红外线接受设备,以及一个遥控,就想用遥控上的各个按键实现不同的功能,设计了一个通过遥控上电源按键的开关来控制LED灯亮灭的小程序,但是烧上程序之后,只能实现一次LED灯的亮灭。就是一开始灯是灭的,按一下就亮了,然后无论怎么按都不灭,不明白是怎么回事,希望大家解答一下,或者能帮忙修改一下。初学51单片机,请多指教!

单片机源程序如下:
  1. /**************************************************************************************
  2. *                              红外通信实验                                                                                                  *
  3. 实现现象:下载程序后,数码管显示红外遥控键值数据
  4. 注意事项:        红外遥控器内的电池绝缘片一定要抽掉                                                                                                                                                         
  5. ***************************************************************************************/

  6. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  7.       

  8. typedef unsigned int u16;          //对数据类型进行声明定义
  9. typedef unsigned char u8;

  10. sbit IRIN=P3^2;
  11. sbit led=P2^0;

  12. u8 IrValue[6];
  13. u8 Time;

  14. /*******************************************************************************
  15. * 函 数 名         : delay
  16. * 函数功能                   : 延时函数,i=1时,大约延时10us
  17. *******************************************************************************/
  18. void delay(u16 i)
  19. {
  20.         while(i--);      
  21. }


  22. /*******************************************************************************
  23. * 函数名         : IrInit()
  24. * 函数功能                   : 初始化红外线接收
  25. * 输入           : 无
  26. * 输出                  : 无
  27. *******************************************************************************/

  28. void IrInit()
  29. {
  30.         IT0=1;//下降沿触发
  31.         EX0=1;//打开中断0允许
  32.         EA=1;        //打开总中断
  33.         IRIN=1;//初始化端口
  34. }


  35. /*******************************************************************************
  36. * 函 数 名       : main
  37. * 函数功能                 : 主函数
  38. * 输    入       : 无
  39. * 输    出             : 无
  40. *******************************************************************************/
  41. void main()
  42. {      
  43.         IrInit();
  44.         while(1);
  45. }

  46. /*******************************************************************************
  47. * 函数名         : ReadIr()
  48. * 函数功能                   : 读取红外数值的中断函数
  49. * 输入           : 无
  50. * 输出                  : 无
  51. *******************************************************************************/

  52. void ReadIr() interrupt 0
  53. {
  54.         u8 j,k;
  55.         u16 err;
  56.         Time=0;                                         
  57.         delay(700);        //7ms
  58.         if(IRIN==0)                //确认是否真的接收到正确的信号
  59.         {         
  60.                
  61.                 err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
  62.                 /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
  63.                 侯,程序死在这里*/      
  64.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                 
  65.                 {                       
  66.                         delay(1);
  67.                         err--;
  68.                 }
  69.                 if(IRIN==1)                        //如果正确等到9ms低电平
  70.                 {
  71.                         err=500;
  72.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
  73.                         {
  74.                                 delay(1);
  75.                                 err--;
  76.                         }
  77.                         for(k=0;k<4;k++)                //共有4组数据
  78.                         {                              
  79.                                 for(j=0;j<8;j++)        //接收一组数据
  80.                                 {

  81.                                         err=60;               
  82.                                         while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
  83.                                         {
  84.                                                 delay(1);
  85.                                                 err--;
  86.                                         }
  87.                                         err=500;
  88.                                         while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
  89.                                         {
  90.                                                 delay(10);         //0.1ms
  91.                                                 Time++;
  92.                                                 err--;
  93.                                                 if(Time>30)
  94.                                                 {
  95.                                                         return;
  96.                                                 }
  97.                                         }
  98.                                         IrValue[k]>>=1;         //k表示第几组数据
  99.                                         if(Time>=8)                        //如果高电平出现大于565us,那么是1
  100.                                         {
  101.                                                 IrValue[k]|=0x80;
  102.                                         }
  103.                                         Time=0;                //用完时间要重新赋值                                                      
  104.                                 }
  105.                         }
  106.                 }
  107.                 if(IrValue[2]!=~IrValue[3])
  108.                 {
  109.                         return;
  110.                 }
  111.         }
  112.         led=0;
  113.         if(IrValue[2]==45)                                //45为红外遥控电源键的数值
  114.         {
  115.                 delay(100);
  116.                 if(IrValue[2]==45)                        //45为红外遥控电源键的数值
  117.                         led=~led;
  118.         }                       
  119. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:164602 发表于 2019-2-19 09:41 | 只看该作者
红外通讯中,很重要的是时间的判断。
看了你的程序,与板子所给的例程没什么变化,但你把延时程序改了,这就有很大的问题了。
原来的延时函数为:
void DelayMs(unsigned int x)   //0.14ms误差 0us
{
unsigned char i;
  while(x--)
{
  for (i = 0; i<13; i++)
{}
}
}
你改成了:
void delay(u16 i)
{
        while(i--);      
}
但你的输入只大了10倍,如原程序是70,你的新程序给了700,不够啊
另外,延时函数时间的多少,与晶振有关哦

只有把这些时间段搞清楚,再改写,怎么都有理的。
回复

使用道具 举报

板凳
ID:96072 发表于 2019-2-19 10:02 | 只看该作者
if(IrValue[2]==45)                        //45为红外遥控电源键的数值                         led=~led;   这样就可以
回复

使用道具 举报

地板
ID:473410 发表于 2019-2-19 15:12 | 只看该作者
HC6800-ES-V2.0 发表于 2019-2-19 09:41
红外通讯中,很重要的是时间的判断。
看了你的程序,与板子所给的例程没什么变化,但你把延时程序改了,这 ...

我没有改这个延时函数啊,原本的里程貌似就是这样。你说的那个延时应该怎么改,我没明白
回复

使用道具 举报

5#
ID:473410 发表于 2019-2-19 15:14 | 只看该作者
HEIZI555 发表于 2019-2-19 10:02
if(IrValue[2]==45)                        //45为红外遥控电源键的数值                         led=~le ...

不行啊,我试了,还是只能亮灭一次,之后一直亮
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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