找回密码
 立即注册

QQ登录

只需一步,快速开始

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

使用单片机定时器的方法,长按按键一分钟后吸合,吸合后延时5分钟后断开

[复制链接]
跳转到指定楼层
楼主
ID:272609 发表于 2018-11-19 00:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  使用89C52的单片机,用C语言编程,使用定时器的方法,长按按键一分钟后吸合,吸合后延时5分钟后断开,如果按键按压不足1分则不吸合。初步会用定时器,自己写了一个使用定时器的程序,1秒吸合1断开程序,编译后可以运行,又写了一个按键按下后,继电器吸合、断开的程序,也成功了,可是写上面这个程序的时候一片空白,求大神再帮忙写一个程序,可能你认为很简单的一个程序,可能会让我们这些小白能学到很多的东西。

下面是我写的程序,大神可自由修改,或者自行编写。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay1ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
        
}
sbit key=P2^4;
sbit relay=P3^4;
uint count;
void init()
{
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;
        TR0=1;
}
void main()
{
        init();
        while(1)
        {
                if(count==20)
                {
                  count=0;
                  relay=~relay;
                                
                }
        }
}
void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        count++;
        
}

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

使用道具 举报

沙发
ID:310519 发表于 2018-11-19 09:23 | 只看该作者
检测到按键按下,启动定时器开始计时。

长按则一直计时,到设定时间继电器吸合,计时继续,到设定时间继电器放开。

如果长按中没到设定时间松开,则关闭定时器并清零计时寄存器;

评分

参与人数 1黑币 +10 收起 理由
飞线 + 10 是这个意思,可是写不出来

查看全部评分

回复

使用道具 举报

板凳
ID:64825 发表于 2018-11-19 09:44 | 只看该作者
关键是有人愿意按键按一分钟吗?一分钟过程中如果有抖动,是不是重头再来,感觉不现实,超过5秒就不现实了,我们一般用按键就是长按和短按,你这个长按时间太长了

评分

参与人数 1黑币 +10 收起 理由
飞线 + 10 按键按下一分,只是一个比喻,前端其实是一.

查看全部评分

回复

使用道具 举报

地板
ID:379730 发表于 2018-11-19 10:39 | 只看该作者
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay1ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);

}
sbit key=P2^4;
sbit relay=P3^4;
uint16 count;
uint8  key_flag = 0,key_flag_num = 0;
void init()
{
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;

}
void main()
{
        init();
        while(1)
        {
                                        if((key_flag == 0) && (key_flag_num == 0))
                                        {
                        if(key == 0)
                        {
                                delay1ms(5);
                                if(key == 0)
                                        {
                                                key_flag = 1;
                                                TR0=1;
                                        }       
                         
                         
                                        
                        }
                }

        }
}
void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        count++;

        if((key != 0) && (key_flag == 1))
                {
                        count = 0;
                        TR0=0;
                        key_flag = 0;
                }
        if((count >= 1200) && (key_flag == 1))  
                {
                        relay=~relay;
                        count = 0;
                        key_flag = 0;
                        key_flag_num = 1;
                }
        if(count >= 6000)
                {
                        relay=~relay;
                        TR0=0;
                        key_flag = 0;
                        count = 0;
                        key_flag_num = 0;
                }


}

评分

参与人数 1黑币 +10 收起 理由
飞线 + 10 正在看你写的程序,因为本人水平低,还不能.

查看全部评分

回复

使用道具 举报

5#
ID:310519 发表于 2018-11-20 10:46 | 只看该作者
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key =P1^0;//按键

sbit relay =P1^1;//继电器控制 1关0开

uint count;//计时存储器


void init()
{
       
        TMOD=0x01;
       
          TH0=(65536-50000)/256;
          TL0=(65536-50000)%256;

        ET0                =1;
        //TR0        =1;
        EA        =1;
}


void main()
{
        init();

       

        while (1)
        {
                if (key==0)//按键按下
                {
                       
                        TR0 =1;//启动定时器
                       
                        while (!key);//长按
                }

               
        }
}

void timer0()interrupt 1
{
        TH0=(65536-50000)/256;
          TL0=(65536-50000)%256;

        count++;

        if (count ==100)//到达设定时间
        {
                relay =0;//继电器吸合
        }

        if (count==200)//到达设定时间
        {
                relay =1;//继电器放开

                count =0;//

                TR0 =0;

        }

        if (relay ==1 && key==1)//如果继电器放开状态并且按键松开
        {
                count =0;

                TR0 =0;

        }

}

评分

参与人数 1黑币 +10 收起 理由
飞线 + 10 很给力!

查看全部评分

回复

使用道具 举报

6#
ID:272609 发表于 2018-11-21 09:39 | 只看该作者
diy1997 发表于 2018-11-20 10:46
#include
#define uchar unsigned char
#define uint unsigned int

利害,只用一个关系表达式,就把程序的整个意思表达出来了,程序写的清晰明了,对我们初学者来说比较易懂,稍后我下载到开发板上,进行上机测试。
回复

使用道具 举报

7#
ID:272609 发表于 2018-11-21 09:48 | 只看该作者
MMU_FS 发表于 2018-11-19 10:39
#include
#define uchar unsigned char
#define uint unsigned int

程序的写有很条理,思路也很清晰,下载的单片机的开发板上,也可以正常运行,并且多次按压按键,只要达不到1分钟,继电器就不会吸合,写的很棒,谢谢了。
另外,如果是按键按下1分钟后,继电器开始吸合,然后松开按键后,继电器开始延时5分钟再断开,这个程序要怎么样修改呢。
还有我今天会花一个小时,来仔细学习你写的程序,然后达到活学活用定时器的目的。
回复

使用道具 举报

8#
ID:310519 发表于 2018-11-21 19:09 | 只看该作者
if 继电器吸合状态 && 按键松开

清除计数器重新计时
回复

使用道具 举报

9#
ID:425206 发表于 2018-11-22 16:50 | 只看该作者
MMU_FS 发表于 2018-11-19 10:39
#include
#define uchar unsigned char
#define uint unsigned int

编译错误,最后发现少了uint8和unit16的宏定义
回复

使用道具 举报

10#
ID:272609 发表于 2018-11-24 10:32 | 只看该作者
林森 发表于 2018-11-22 16:50
编译错误,最后发现少了uint8和unit16的宏定义

程序没有问题,你把uint8和uint16都修改成uint就行了,我编辑完成后,下载到开发板上是可以的
回复

使用道具 举报

11#
ID:272609 发表于 2018-11-24 11:28 | 只看该作者
diy1997 发表于 2018-11-21 19:09
if 继电器吸合状态 && 按键松开

清除计数器重新计时

我按照你的思路,试着修改一下
回复

使用道具 举报

12#
ID:272609 发表于 2018-12-7 10:44 | 只看该作者
MMU_FS 发表于 2018-11-19 10:39
#include
#define uchar unsigned char
#define uint unsigned int

MMU_FS 你好,你写的程序下载的开发板上,可以实现上述功能,当时要求是使用单片机定时器的方法,长按按键一分钟后吸合,吸合后延时5分钟后断开 ,我想修改一下,变成按键按下1分钟后,继电器开始吸合,然后松开按键后,继电器开始延时5分钟再断开。我是水平有限,修改了很长时间也不行,不过看了你的代码,学会了软件调试,还有关系表达式和逻辑表达式。我再试着修改一下,15号之前要是还是不行,我再请教你。
回复

使用道具 举报

13#
ID:405193 发表于 2018-12-8 17:15 | 只看该作者
我学单片机3个月了,也写了一个,楼主可以测试一下
#include <reg52.h>
sbit relay = P1^3;              //继电器,0线圈吸合,1线圈断开
sbit   key = P3^0;                //按键,0为按下,1为松开
bit flag=0;
#define uchar unsigned char
#define uint unsigned int
      

void Init_T0(void)             //50毫秒@11.0592MHz
{
    TMOD = 0x01;
     TL0 = 0x00;                           //设置定时初值
     TH0 = 0x4C;                           //设置定时初值
     TF0 = 0;                          //清除TF0标志
     TR0 = 1;                          //定时器0开始计时
    ET0 = 1;
    EA = 1;
}
void main(void)
{
        
        Init_T0();
        relay = 1;                         //断开继电器
       while(1)
        {
             //想实现其他功能,再这里添加代码
        }
}
void T0_ISR() interrupt 1              
{          
     static uint mm,nn;
        TL0 = 0x00;                             //设置定时初值          50毫秒
            TH0 = 0x4C;                            //设置定时初值

       if(key==0)                   //判断按键是否被按下
         nn++;
           if((key==0)&&( nn>=1200))   // 按键按下并且到达1分钟
         {   
            while(!key); nn=0;       //等待按键释放
              relay=0;         flag=1;
                 }          
           if(flag==1)                  
                  mm++;
               {
              if( mm>=6000)                                   //吸合5分钟断开
                { mm=0; relay=1; flag=0;}
                }
}      
回复

使用道具 举报

14#
ID:272609 发表于 2018-12-8 22:10 | 只看该作者
yong761228 发表于 2018-12-8 17:15
我学单片机3个月了,也写了一个,楼主可以测试一下
#include
sbit relay = P1^3;              //继电器 ...

好的,我在外地出差,回去了我试一下,谢谢你的分享
回复

使用道具 举报

15#
ID:405193 发表于 2018-12-9 08:45 | 只看该作者
飞线 发表于 2018-12-8 22:10
好的,我在外地出差,回去了我试一下,谢谢你的分享

不客气,我的定时器配置是根据STC配置的,你的51单片机如果时间不准, 可以修改一下。
回复

使用道具 举报

16#
ID:272609 发表于 2018-12-16 20:02 | 只看该作者
MMU_FS 发表于 2018-11-19 10:39
#include
#define uchar unsigned char
#define uint unsigned int

苦思冥想了半个月,还是改不好,麻烦给说一下怎么改吧
回复

使用道具 举报

17#
ID:275479 发表于 2018-12-16 20:50 | 只看该作者
好像看到了那年的自己,真的很高兴,入门之后就好了,一切知识都变得很开朗
回复

使用道具 举报

18#
ID:272609 发表于 2018-12-16 23:02 | 只看该作者
通天塔 发表于 2018-12-16 20:50
好像看到了那年的自己,真的很高兴,入门之后就好了,一切知识都变得很开朗

还没入门,不过我不会放弃的,前面很多人给我写的程序,我把它打印下来,对照着在keil中抄2遍,理解他们写的意思,写的目的。
在学习的过程,学习了if语句、for语句、关系表达式,逻辑表达式,初步会使用了keil的软件仿真调试。
回复

使用道具 举报

19#
ID:405193 发表于 2018-12-20 21:51 | 只看该作者
  if((key==0)&&( nn>=1200))   // 按键按下并且到达1分钟 继电器吸合
         {   relay=0;
            while(!key); nn=0;       //按键释放后开始延时计时
                      flag=1;
          }
   if(flag==1)                  
       mm++;
      {
         if( mm>=6000)                                   //延时5分钟断开
             { mm=0; relay=1; flag=0;}
       }   
你看看对不对,我也才学3个月。      
回复

使用道具 举报

20#
ID:272609 发表于 2018-12-30 23:15 | 只看该作者
yong761228 发表于 2018-12-20 21:51
if((key==0)&&( nn>=1200))   // 按键按下并且到达1分钟 继电器吸合
         {   relay=0;
          ...

好的,我出差回去下载试试,不过看语句应该是没有问题的
回复

使用道具 举报

21#
ID:272609 发表于 2018-12-30 23:33 | 只看该作者
yong761228 发表于 2018-12-20 21:51
if((key==0)&&( nn>=1200))   // 按键按下并且到达1分钟 继电器吸合
         {   relay=0;
          ...

学了三个月,真的很利害了,我把程序完整的写了下来,你看是这个意思吗,编译的时候没有错误
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay1ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);

}
sbit key=P2^4;
sbit relay=P3^4;
uint count,mm;
uint key_flag=0,key_flag_num=0;
void init()
{
         TMOD=0x01;
         TH0=(65536-50000)/256;
         TL0=(65536-50000)%256;
         EA=1;
         ET0=1;

}
void main()
{
         init();
         while(1)
         {
                 if((key_flag==0)&&(key_flag_num==0))
                  {
        if(key==0)
         {
                                         delay1ms(5);
                                         if(key==0)
                                         {
                                                 key_flag=1;
                                                 TR0=1;
                                         }        
         
                }
                        }

         }
}
void timer0() interrupt 1
{
         TH0=(65536-50000)/256;
         TL0=(65536-50000)%256;
         count++;
         mm++;

         if((key!=0) && (key_flag==1))
                                         {
                                                 count = 0;
                                                 TR0=0;
                                                 key_flag = 0;
                                         }
         if((count>=1200)&&(key_flag==1))  
                                         {
                                                 relay=0;
                                                 while(!key);
                                                 count=0;
                                                 key_flag_num=1;
                                         }
         if(key_flag_num=1)
                                         {
                                                 mm++;
                                                 {
                                                        if(mm>=6000)
                                                        {
                                                                mm=0;
                                                                relay=1;
                                                                key_flag_num=0;
                                                        }
                                                 }
                                                 
                                         }


}
回复

使用道具 举报

22#
ID:272609 发表于 2019-1-3 06:46 | 只看该作者
MMU_FS 发表于 2018-11-19 10:39
#include
#define uchar unsigned char
#define uint unsigned int

改不好你的程序,把你写的程序理解下来,然后凭着自己的理解又写了一遍
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay1ms (uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
uint count;
uint key_num=0,key_nums=0;
sbit key=P2^1;
sbit relay=P3^4;
void init()
{       
        EA=1;
        ETO=1;
        TMOD=0x01;
        THO=(65536-50000)/256;
        TL0=(65536-50000)%256;
        TRO=0;
        relay=1;
}       
void main()
{
        init();
        while(1)
        {
                if((key_num==0)&&(key_nums==0))
                {
                        if(key==0)
                        {
                                delay1ms(5);
                                if(key==0);
                                        {
                                                key_num=1;
                                                TR0=1;
                                        }
                                               
                        }
               
                }
        }
       
}
void timer0() interrupt 1
{
        THO=(65536-50000)%256;
        TL0=(65536-50000)/256;
        count++;
        if((count>=1200)&&(key_num=1))
        {
                relay=~relay;
                count=0;
                key_num=0;
                key_nums=1;
        }
        if(count>=6000)
        {
                relay=~relay;
                count=0;
                key-num=0;
                key_nums=0;
                TR0=0;
               
        }
        if((key!=0&&key_nums==1))
        {
                key_num=0;
                TR0=0;
                count=0;
        }
}

回复

使用道具 举报

23#
ID:405193 发表于 2019-1-3 09:25 | 只看该作者
飞线 发表于 2018-12-30 23:33
学了三个月,真的很利害了,我把程序完整的写了下来,你看是这个意思吗,编译的时候没有错误
#include
...

基本是这个意思。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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