找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1726|回复: 18
收起左侧

关于单片机定时器与中断的问题

[复制链接]
ID:969765 发表于 2021-10-4 12:06 | 显示全部楼层 |阅读模式
大佬们好,如果定时器T0已经初始化后,开始运行,这时候我一直初始化会发生什么样的情况。原本代码是将Timert0_init(); 放在while外面上电初始化,但是我想试一试放在按键里面会是什么样的效果。结果就是按键1需要一直按下,按键2只需点动,按键3,4在初始化后与按键2一样的效果。有没有大佬解释一下其中的原理。感谢
下面是单片机测试代码:

#include "regx52.h"
#include "timer0.h"
#include "keynum.h"
#include "intrins.h"
#include "Delay.h"

unsigned char wl,mode;//waterfall light 流水灯
void main()
{        
        P2=0xfe;
        while(1)
        {
                wl=keynum();
               
                if(wl>0)
                {
                        if(wl==1)
                        {
                                mode=1;
                                Timert0_init();      //这里按键一直按下流水灯一直工作,松手停下。
                        }
                        if(wl==2)
                        {
                                mode=2;
                                Delay(1);             //这里按键按下,松开流水灯继续工作
                                Timert0_init();
                        }
                        if(wl==3)
                        {
                                mode=3;
                        }
                        if(wl==4)
                        {
                                mode=4;
                        }
                }
        }
}
void Timer0_Rountine(void)        interrupt 1
{
        static unsigned int t0count;        //静态函数static,保证退出中断时t0count不清零。
        TL0 = 0x66;                //设置定时初始值
        TH0 = 0xFC;                //设置定时初始值                        //定时器溢出后的值会变成0,需要重新赋初值;        
        t0count++;
        if(t0count>=1000)
        {
                t0count=0;
                if(mode==1)
                {
                        P2=_crol_(P2,1);
                }
                                if(mode==2)
                {
                        P2=_cror_(P2,1);
                }
                if(mode==3)
                {
                        P2=_crol_(P2,1);
                }
                if(mode==4)
                {
                        P2=_cror_(P2,1);
                }

        }
}




回复

使用道具 举报

ID:969765 发表于 2021-10-4 12:07 | 显示全部楼层
有没有大佬帮下忙,解决一下我的困惑
回复

使用道具 举报

ID:57657 发表于 2021-10-4 14:57 | 显示全部楼层
你的文件不全,需要有 timer0.h 等头文件的内容才知道是什么问题。
回复

使用道具 举报

ID:624769 发表于 2021-10-4 18:36 | 显示全部楼层
LYN123188 发表于 2021-10-4 12:07
有没有大佬帮下忙,解决一下我的困惑

先说单片机具体型号,

然后说,希望达到的效果,
然后,说一下实际效果。

最后,标注一下,哪个是按键1,2,3,4
回复

使用道具 举报

ID:969765 发表于 2021-10-5 11:29 | 显示全部楼层
npn 发表于 2021-10-4 14:57
你的文件不全,需要有 timer0.h 等头文件的内容才知道是什么问题。

好的,我马上补发
回复

使用道具 举报

ID:969765 发表于 2021-10-5 11:29 | 显示全部楼层
188610329 发表于 2021-10-4 18:36
先说单片机具体型号,

然后说,希望达到的效果,

普中51单片机,stl89c51
回复

使用道具 举报

ID:429003 发表于 2021-10-5 11:55 | 显示全部楼层
单片机执行的每一个行为均是由程序逻辑所控制的,无论是放在循环外还是循环体内,其对执行结果的影响是由具体代码决定。你先搞明白TimerInit干了些什么事情,会给程序带来什么样的执行过程,同时你又希望怎么执行才能实现你的控制思路!!
回复

使用道具 举报

ID:969765 发表于 2021-10-5 11:57 | 显示全部楼层
希望大佬们指导指导

定时器中断问题.zip

43.24 KB, 下载次数: 5

回复

使用道具 举报

ID:969765 发表于 2021-10-5 15:43 | 显示全部楼层
xstong 发表于 2021-10-5 11:55
单片机执行的每一个行为均是由程序逻辑所控制的,无论是放在循环外还是循环体内,其对执行结果的影响是由具 ...

我现在分析不出原因,希望大佬指点。文件已经补发了
回复

使用道具 举报

ID:451718 发表于 2021-10-5 16:28 | 显示全部楼层
看了一下你的程序,问题很多,按键的响应程序效率太低了,主程序里面的判断语句也不严谨。建议你还是多看懂几个范列程序,再自己着手写功能。  
回复

使用道具 举报

ID:883031 发表于 2021-10-5 16:33 | 显示全部楼层
可以将初始化程序放在外边,先不要启动定时器,需要的时候再打开,在条件满足时在关闭,控制定时器的开关就行了。
回复

使用道具 举报

ID:161164 发表于 2021-10-5 16:44 | 显示全部楼层
LYN123188 发表于 2021-10-5 15:43
我现在分析不出原因,希望大佬指点。文件已经补发了

                        if(wl==1)
                        {
                                mode=1;
                                Timert0_init();      //这里按键一直按下流水灯一直工作,松手停下。
                        }
                        if(wl==2)
                        {
                                mode=2;
                                Delay(1);             //这里按键按下,松开流水灯继续工作
                                Timert0_init();
                        }
在你第一次贴的代码中
mode1 和 mode2 的分别就是多了Delay(1);
说个比喻:
Timert0_init();->网贷收钱
Delay(1);->让你有时间挣钱
mode1:
当你挣到一两毛的时候网贷收钱把你的户口清零了,你只好继续去搬砖
mode2:
Delay(1)让你有时间挣钱,等你挣到一千零一毛的时候网贷才来收钱,你有一毛留下,立刻走去消费(流水灯位移)

如果有键按着
因为键按程序中有松开等待
就等于白白延长了还款时间
让你有钱(时间)去消费(流水灯位移)

然而,在你上传的Keil 文件中已经在mode1中补回了Delay(1);
别人重现不了你的问题

如何验证我的比喻?
可以把Delay()函数中的i=2改为i=1(缩短还款期)
就会令到按键1和2都要按着才能流水


回复

使用道具 举报

ID:970053 发表于 2021-10-6 08:53 | 显示全部楼层
你的文件不全,需要有 timer0.h 等头文件的内容才知道是什么问题。
回复

使用道具 举报

ID:969765 发表于 2021-10-8 15:23 | 显示全部楼层
lkc8210 发表于 2021-10-5 16:44
if(wl==1)
                        {
                                mode ...

你好,你说的非常好,就是有一点我不明白,mode1的定时计数一直在清零,我一直按着流水灯流动,我松开他就不动是为什么,不是已经初始化过了吗
回复

使用道具 举报

ID:161164 发表于 2021-10-8 21:46 | 显示全部楼层
LYN123188 发表于 2021-10-8 15:23
你好,你说的非常好,就是有一点我不明白,mode1的定时计数一直在清零,我一直按着流水灯流动,我松开他 ...

对不起,原来我分析错了
我上个回覆只找到为什么按着会流水
而没有找到真正的原因
刚刚再看一次代码
才发现keynum.c里
反回的keynumber不会清零
只会维持上一次按键的数值
引致if(wl==1)不断成立
不断初始化,进不了中断

解决方法是把keynumber放到keynum()内
  1. int keynum()
  2. {
  3. unsigned char keynumber=0;
  4.         if(P3_1==0){Delay(200);while(P3_1==0);Delay(20);keynumber=1;}
  5.         if(P3_0==0){Delay(200);while(P3_0==0);Delay(20);keynumber=2;}
  6.         if(P3_2==0){Delay(200);while(P3_2==0);Delay(20);keynumber=3;}
  7.         if(P3_3==0){Delay(200);while(P3_3==0);Delay(20);keynumber=4;}
  8.         return keynumber;
  9. }
复制代码
回复

使用道具 举报

ID:969765 发表于 2021-10-14 15:46 | 显示全部楼层
lkc8210 发表于 2021-10-8 21:46
对不起,原来我分析错了
我上个回覆只找到为什么按着会流水
而没有找到真正的原因

大佬,照你这么说,按完之后和一直按着应该一个效果啊,为什么一直按着流水灯会动,松开就不行了。
回复

使用道具 举报

ID:969765 发表于 2021-10-14 15:47 | 显示全部楼层
lkc8210 发表于 2021-10-8 21:46
对不起,原来我分析错了
我上个回覆只找到为什么按着会流水
而没有找到真正的原因

mode1那里的delay(1)去掉后
回复

使用道具 举报

ID:969765 发表于 2021-10-14 15:48 | 显示全部楼层
LYN123188 发表于 2021-10-14 15:46
大佬,照你这么说,按完之后和一直按着应该一个效果啊,为什么一直按着流水灯会动,松开就不行了。

感谢大佬的细心解答
回复

使用道具 举报

ID:969765 发表于 2021-10-14 15:51 | 显示全部楼层
lkc8210 发表于 2021-10-8 21:46
对不起,原来我分析错了
我上个回覆只找到为什么按着会流水
而没有找到真正的原因

大佬,刚开机需要先按一下,然后松开,再一直按就能动,第1下百分百不能动
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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