[51单片机] 独立按键控制继电器

[复制链接]
1268|7
 楼主| 小分子 发表于 2016-7-31 21:11 | 显示全部楼层 |阅读模式
  1. /***************************
  2.         独立按键控制继电器
  3. ***************************/
  4. #include <reg52.h>

  5. #define uchar unsigned char

  6. sbit KEY = P1 ^ 0;
  7. sbit RelayEN = P0 ^ 0;                                   //定义继电器开启信号

  8. void Timer0Init();                                           //声明定时器0初始化函数
  9. void RelayProcess();                                   //声明断电器处理函数

  10. uchar count = 0;                                           //计秒数

  11. void main()                                                           //主函数
  12. {
  13.         RelayEN = 1;                                           //开机时关闭继电器,否则一上电继电器有动作;

  14.         Timer0Init();
  15.         RelayProcess();
  16.        
  17. }

  18. void Timer0Init()                                           //定时器初始化函数
  19. {
  20.         TMOD |= 0x01;                                           //“|”使用多个定时器时不受影响
  21.         TH0 = 0xFC;                                                   //定时1MS
  22.         TL0 = 0x67;
  23.         TR0 = 1;                                                   //开启定时器0
  24.         EA = 1;                                                           //开启总中断
  25.         ET0 = 1;                                                   //开启定时器0中断
  26. }

  27. void RelayProcess()                                          //继电器处理函数
  28. {
  29.         KEY = 0x01;                                                  //读外部状态时,先使端口输出高电平;
  30.         while (1)
  31.         {
  32.                 if(!KEY)                                          //判定有无按键按下
  33.                 {
  34.                         if(count >= 20)                          //判定秒数是否达到20MS,即去抖
  35.                         {
  36.                                 count = 0;
  37.                                 if(!KEY)
  38.                                 {
  39.                                         RelayEN = ~RelayEN;//当按键按下时,改变继电器的状态
  40.                                         while(!KEY);           //等待按键释放;
  41.                                 }
  42.                         }
  43.                 }
  44.         }
  45.        
  46. }

  47. void Timer0() interrupt 1                                //定时器0中断函数
  48. {
  49.         TH0 = 0xFC;                                                        //重新赋值给定时器0
  50.         TL0 = 0x67;
  51.         count++;                                                        //计秒数
  52. }


jackhwang 发表于 2016-7-31 22:22 | 显示全部楼层
你的程序初始化时,定时器0就已经打开了,count就不停在累加,不管按键有无按下。当你的按键在count大于20按下,无法实现去抖效果。
 楼主| 小分子 发表于 2016-8-1 21:47 | 显示全部楼层
jackhwang 发表于 2016-7-31 22:22
你的程序初始化时,定时器0就已经打开了,count就不停在累加,不管按键有无按下。当你的按键在count大于20 ...

哥们,你说得太对了,我这自学的,只是一个演示肯定有很多不足,这样的程序也上不了项目。多谢指点
 楼主| 小分子 发表于 2016-8-2 07:48 | 显示全部楼层
小分子 发表于 2016-8-1 21:47
哥们,你说得太对了,我这自学的,只是一个演示肯定有很多不足,这样的程序也上不了项目。多谢指点 ...
  1. /***************************
  2.         独立按键控制继电器
  3. ***************************/
  4. #include <reg52.h>

  5. #define uchar unsigned char

  6. sbit KEY = P1 ^ 0;
  7. sbit RelayEN = P0 ^ 0;                                   //定义继电器开启信号

  8. void Timer0Init();                                           //声明定时器0初始化函数
  9. void RelayProcess();                                   //声明断电器处理函数

  10. uchar count = 0;                                           //计秒数

  11. void main()                                                           //主函数
  12. {
  13.         RelayEN = 1;                                           //开机时关闭继电器,否则一上电继电器有动作;

  14.         Timer0Init();
  15.         RelayProcess();
  16.        
  17. }

  18. void Timer0Init()                                           //定时器初始化函数
  19. {
  20.         TMOD |= 0x01;                                           //“|”使用多个定时器时不受影响
  21.         TH0 = 0xFC;                                                   //定时1MS
  22.         TL0 = 0x67;
  23.         EA = 1;                                                           //开启总中断
  24.         ET0 = 1;                                                   //开启定时器0中断
  25. }

  26. void RelayProcess()                                          //继电器处理函数
  27. {
  28.         KEY = 0x01;                                                  //读外部状态时,先使端口输出高电平;
  29.         while (1)
  30.         {
  31.                 if(!KEY)                                          //判定有无按键按下
  32.                 {
  33.                         TR0 = 1;                                  //按键按下开启定时器0,溢出后开启中断
  34.                        
  35.                         if (count >= 20)                  //判定秒数是否达到20MS,即去抖
  36.                         {
  37.                                 count = 0;
  38.                                 if (!KEY)
  39.                                 {
  40.                                         RelayEN = ~RelayEN;//当按键按下时,改变继电器的状态
  41.                                         while(!KEY);           //等待按键释放;
  42.                                 }
  43.                         }
  44.                 }
  45.         }
  46.        
  47. }

  48. void Timer0() interrupt 1          //定时器0中断函数
  49. {
  50.         count++;                                  //计秒数
  51.         TR0 =0;                                          //关闭定时器,否则无按键按下也计数;
  52.         TH0 = 0xFC;                                  //重新赋值给定时器0
  53.         TL0 = 0x67;
  54.                                                                         
  55. }
xygyszb 发表于 2016-8-2 08:09 | 显示全部楼层
为啥不把处理函数放到定时器里面去?这样定时器还可以去处理其他的事情。
 楼主| 小分子 发表于 2016-8-2 16:26 | 显示全部楼层
xygyszb 发表于 2016-8-2 08:09
为啥不把处理函数放到定时器里面去?这样定时器还可以去处理其他的事情。 ...

防止影响定时时间。
xygyszb 发表于 2016-8-3 08:22 | 显示全部楼层
小分子 发表于 2016-8-2 16:26
防止影响定时时间。

哦,你这个定时器不是系统配置的。是计数形式的。
 楼主| 小分子 发表于 2016-8-3 11:21 | 显示全部楼层
xygyszb 发表于 2016-8-3 08:22
哦,你这个定时器不是系统配置的。是计数形式的。

还是有缺陷的。应该在键盘释放时,加一个计数清零
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

68

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部