OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6245|回复: 17

为什么独立按键不能控制定时器0的开启

[复制链接]

1

主题

4

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2019-7-16
在线时间
1 小时
发表于 2019-7-16 20:07:27 | 显示全部楼层 |阅读模式
1金钱
代码如下,希望各位大佬解答



#include "reg52.h"                         

typedef unsigned int u16;          
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit K1=P3^0;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

u8 ssec,sec,min;
u8 DisplayData[8];

void delay(u16 i)
{
        while(i--);       
}


void Timer0Init()
{
        TMOD|=0X01;
        TH0=0Xd8;
        TL0=0Xf0;       
        ET0=1;
        EA=1;
        TR0=1;                       
}
        void Int0Configuration()
{
        IT0=1;
        EX0=1;
        EA=1;
}





void DigDisplay()
{
        u8 i;
        for(i=0;i<8;i++)
        {
                switch(i)       
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;
                        case(3):
                                LSA=1;LSB=1;LSC=0; break;
                        case(4):
                                LSA=0;LSB=0;LSC=1; break;
                        case(5):
                                LSA=1;LSB=0;LSC=1; break;
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;       
                }
                P0=DisplayData[i];
                delay(100);        
                P0=0x00;
        }
}

void datapros()
{
        DisplayData[0]=smgduan[ssec%10];
        DisplayData[1]=smgduan[ssec/10];
        DisplayData[2]=0x40;       
        DisplayData[3]=smgduan[sec%10];
        DisplayData[4]=smgduan[sec/10];
        DisplayData[5]=0x40;
        DisplayData[6]=smgduan[min%10];
        DisplayData[7]=smgduan[min/10];
}

void main()
{       
        Timer0Init();  
    Int0Configuration();
        while(1)
        {
                datapros();
                DigDisplay();       
        }               
}


void Timer0() interrupt 1
{
        TH0=0Xd8;       
        TL0=0Xf0;
        ssec++;
        if(ssec>=100)  
        {
                ssec=0;
                sec++;
                if(sec>=60)
                {
                        sec=0;
                        min++;
                        if(min>=60)
                        {
                                min=0;
                        }
                }       
        }       
}
void Int0() interrupt 0                 
{
          delay(1000);
                  if(K1==0)
                {
                   TR0=~TR0;
                }

}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165369
金钱
165369
注册时间
2010-12-1
在线时间
2110 小时
发表于 2019-7-17 01:47:10 | 显示全部楼层
回复

使用道具 举报

21

主题

211

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1420
金钱
1420
注册时间
2016-8-3
在线时间
575 小时
发表于 2019-7-17 14:49:18 | 显示全部楼层
延时太大了,K1是不是按键?
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2019-7-16
在线时间
1 小时
 楼主| 发表于 2019-7-17 15:12:32 | 显示全部楼层
1965969523 发表于 2019-7-17 14:49
延时太大了,K1是不是按键?

是的。但是我延时调整后,按下k1还是不能关闭定时器啊
回复

使用道具 举报

21

主题

211

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1420
金钱
1420
注册时间
2016-8-3
在线时间
575 小时
发表于 2019-7-18 08:35:15 | 显示全部楼层
y27046396 发表于 2019-7-17 15:12
是的。但是我延时调整后,按下k1还是不能关闭定时器啊

你可以把  if(K1==0)去了,直接关闭TR0,看看可以不?如果还是不行的话,你测试下中断是否正常
               
回复

使用道具 举报

0

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2019-7-16
在线时间
6 小时
发表于 2019-7-18 09:30:02 | 显示全部楼层
设置一个按键函数,当K1按下以后,给定一个变量为1,定时器0则判断这个变量是否为0,当为0时,TR0翻转。如果要重复控制开启关闭,按键函数里面,变量换成取反就好了。
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-7-26 13:34:07 | 显示全部楼层
你为啥把独立按键放外部中断里面呢?
放外面:
if(k1==0)
{
      delay(10);  // 延时10ms用于按键消抖
      if(k1==0)
      {
            TR0 = ~TR0;
      }
     delay(100);   // 避免按一次按键,多次进入
}
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-7-29 19:05:16 | 显示全部楼层
sbit INT0 = P3^2;

void T0_isr() interrupt 0
{
       if(INT0 == 0)
       {
               Delay_ms(10);
               if(INT0 == 0)
                     TR0 = ~TR0;
       }
}
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2019-7-16
在线时间
1 小时
 楼主| 发表于 2019-8-4 17:45:04 | 显示全部楼层
1965969523 发表于 2019-7-18 08:35
你可以把  if(K1==0)去了,直接关闭TR0,看看可以不?如果还是不行的话,你测试下中断是否正常
         ...

把TR0关闭和用独立按键控制LED都正常,但是用按键就是控制不了定时器的关闭。我也很纳闷。
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2019-7-16
在线时间
1 小时
 楼主| 发表于 2019-8-4 17:49:35 | 显示全部楼层
七月的风 发表于 2019-7-26 13:34
你为啥把独立按键放外部中断里面呢?
放外面:
if(k1==0)

你提供的两种方案我都试过了,但是独立按键按下后定时器还是不起作用。
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-8-4 19:20:02 | 显示全部楼层
y27046396 发表于 2019-8-4 17:49
你提供的两种方案我都试过了,但是独立按键按下后定时器还是不起作用。

端口P3.0是串口发送TXD吧,是的话是不能当按键使用的
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-8-4 19:25:47 | 显示全部楼层
你的是普中的板子吧,我用你的程序改了一下按键,把K1
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-8-4 19:26:17 | 显示全部楼层
换成P3.2就能用了
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-8-4 19:36:33 | 显示全部楼层
串口RXD P3.1也不能用做按键
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-8-4 20:18:25 | 显示全部楼层
#include "reg52.h"                        

typedef unsigned int u16;         
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit K1=P3^0;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

u8 ssec,sec,min;
u8 DisplayData[8];

void delay(u16 i)
{
        while(i--);        
}


void Timer0Init()
{
        TMOD|=0X01;
        TH0=0Xd8;
        TL0=0Xf0;        
        ET0=1;
        EA=1;
        TR0=1;                        
}
        void Int0Configuration()
{
        IT0=1;
        EX0=1;
        EA=1;
}





void DigDisplay()
{
        u8 i;
        for(i=0;i<8;i++)
        {
                switch(i)        
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;
                        case(3):
                                LSA=1;LSB=1;LSC=0; break;
                        case(4):
                                LSA=0;LSB=0;LSC=1; break;
                        case(5):
                                LSA=1;LSB=0;LSC=1; break;
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;        
                }
                P0=DisplayData[i];
                delay(100);         
                P0=0x00;
        }
}

void datapros()
{
        DisplayData[0]=smgduan[ssec%10];
        DisplayData[1]=smgduan[ssec/10];
        DisplayData[2]=0x40;        
        DisplayData[3]=smgduan[sec%10];
        DisplayData[4]=smgduan[sec/10];
        DisplayData[5]=0x40;
        DisplayData[6]=smgduan[min%10];
        DisplayData[7]=smgduan[min/10];
}

void main()
{        
        Timer0Init();  
    Int0Configuration();
        while(1)
        {
                               
                  if(K1==0)
                {
                                        delay(1000);
                                        if(K1 == 0)
                                                TR0=~TR0;
                }

                datapros();
                DigDisplay();        
        }
               
}


void Timer0() interrupt 1
{
        TH0=0Xd8;        
        TL0=0Xf0;
        ssec++;
        if(ssec>=100)  
        {
                ssec=0;
                sec++;
                if(sec>=60)
                {
                        sec=0;
                        min++;
                        if(min>=60)
                        {
                                min=0;
                        }
                }        
        }        
}
void Int0() interrupt 0                 
{
         
}


我发现一个现象:当把按键判断放到主函数中时,你定义的按键是P3^0(串口的TXD)按下不管用,
当你这时按P3^1(串口RXD)时,发现定时器竟然停了。现象就是这个现象,原因就不知道了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165369
金钱
165369
注册时间
2010-12-1
在线时间
2110 小时
发表于 2019-8-5 01:28:06 | 显示全部楼层
帮顶
回复

使用道具 举报

0

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2019-6-14
在线时间
15 小时
发表于 2019-8-28 08:44:17 | 显示全部楼层
把定时器初始化TR0=1去掉。
回复

使用道具 举报

36

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2015-12-13
在线时间
243 小时
发表于 2019-8-28 11:38:14 | 显示全部楼层
本帖最后由 HER107 于 2019-8-28 11:47 编辑

if(K1==0)
                {
                                        delay(1000);
                                        if(K1 == 0)
                                                TR0=~TR0;
                }

这么写, 如果K1按下来 TR0 岂不是一直在翻转?

你可以照着教程里面写

if( !K1)
       {
       delay(1000);
       if(!K1)TR0=~TR0;
        while(!K1);    //等待按键释放
        }

这样应该行得通。。 但是我觉得这么写没有实用性! 因为如果按键按着不放,就卡死在这不动了。

回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-1 06:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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