找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3237|回复: 11
收起左侧

萌新关于秒表用中断方式做出启动停止复位

[复制链接]
ID:265318 发表于 2017-12-25 10:21 | 显示全部楼层 |阅读模式
20黑币
中断是个什么鬼,自学的,书上中断含含糊糊所以我一直用的查询,而且也做出来了,可是网上一直查不到中断的意思,有木有大佬为我解惑最好带一点例子。

回复

使用道具 举报

ID:266627 发表于 2017-12-26 20:35 | 显示全部楼层
比如你买了个手机打入电话不会响铃和振动,只有屏幕上会显示来电。

平时你手头工作又多,但电话也不能错过,可能是你老板的电话也可能是女朋友的,那怎么办?
这种情况下,你只能不时的停下来,拿起手机看一看,耽误工作效率不说,还经常错过电话。只因为有时电话只呼叫几秒,而你正是这几秒里没有停下查看,这样错过重要电话。

或许觉得这个手机够差的,有电话你直接响铃不好吗,我听到电话再停下来。这个响铃功能就是中断。


最早期的单片机没有中断,也是出于需要加入的。

评分

参与人数 1黑币 +60 收起 理由
admin + 60 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:231046 发表于 2017-12-25 14:20 | 显示全部楼层
中断就是 做什么 事时,突然有人来打扰了,中断会优先处理打扰的这件事,有优先级的
回复

使用道具 举报

ID:231046 发表于 2017-12-25 14:21 | 显示全部楼层
比查询快而且简单,不影响主程序时间
回复

使用道具 举报

ID:78322 发表于 2017-12-25 15:11 | 显示全部楼层
中断啊,就是你本来一直在跑步,可是突然你膀胱胀痛需要放水,然后去旁边放水,完事还需要回到原来的地方继续跑步。
回复

使用道具 举报

ID:213173 发表于 2017-12-25 16:31 | 显示全部楼层
给你一个6位显示百分秒表例程,单键控制开启、暂停、复位。你根据实际电路更改端口定义。
#include <AT89X52.H>
#define uint unsigned int
#define uchar unsigned char
sbit key1=P3^6;       
sbit dula=P2^6;                        //段选
sbit wela=P2^7;                        //位选
uchar code table[]={
        0x3f,0x06,0x5b,0x4f,
        0x66,0x6d,0x7d,0x07,
        0x7f,0x6f,0x77,0x7c,
        0x39,0x5e,0x79,0x71};
uchar Cntus=0,Cnt10ms=0,Cnt1s=0,Cnt1min=0;                //中断计时变量

bit zantin=0;                                        //暂停标志
void display();                                        //显示程序声明
void keyscan();                                        //按键扫描程序声明
/***********按键扫描程序****************/
void keyscan()       
{
        static uint count2=0,count1=0;        //计数变量                       
        static bit key_sign=0;                                        //按键状态标志
        if(key1==0)                                //检测输入如果为0
        {
                count1++;                                        //计数延时消抖
                if((count1>=500)&&(key_sign==0))//检测按键如果为0
                {                       
                        key_sign=1;                //按键状态标志置1,防止重复响应
                        count2++;
                        if(count2>=3)
                                count2=0;
                        switch(count2)
                        {
                                case 0:        Cntus=0;
                                                        Cnt10ms=0;
                                                        Cnt1s=0;
                                                        Cnt1min=0;        break;//清0
                                case 1:        zantin=1;   break;//计时
                                case 2:        zantin=0;        break;//暂停
                        }               
                }
        }
        else
        {
                count1=0;                                //计数变量清0
                key_sign=0;                                //按键状态标志清0
        }
}
/***********定时器初始化程序****************/
void Timer0Init(void)                //2500微秒@11.0592MHz
{
        TMOD = 0x01;                //设置定时器模式
        TL0 = 0x00;                //设置定时初值
        TH0 = 0xF7;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        EA=1;                                                        //开总中断
        ET0=1;                                                //开定时器0中断
}
/***************主程序****************/
void main()
{
        Timer0Init();                                //定时器初始化
        while(1)
        {
                keyscan();                                //按键扫描
        }
}
/**************中断服务程序*****************/
void timer0() interrupt        1//2500微秒@11.0592MHz
{
        TL0 = 0x00;                //设置定时初值
        TH0 = 0xF7;                //设置定时初值
        Cntus++;                                        //中断变量Cntus自+1
        if(Cntus>=4)                                //10ms
        {
                Cntus=0;                                //清0
                if(zantin==1)                        //暂停/启动
                        Cnt10ms++;                        //毫秒计数
                if(Cnt10ms>=100)
                {
                        Cnt10ms=0;
                        Cnt1s++;                                //秒计数
                        if(Cnt1s>=60)
                        {
                                Cnt1s=0;
                                Cnt1min++;                //分计数
                                if(Cnt1min>=100)
                                        Cnt1min=0;
                        }
                }
        }
        display();                                        //显示程序
}
void display()//显示程序
{
        static uchar count=0;        //计数变量
        switch(count)
        {
                case 0:
                   P0=table[Cnt1min/10];        //显示十分位
                   dula=1;
                   dula=0;
               
                   P0=0x7e;
                   wela=1;
                   wela=0;
                   count=1;
                break;
                case 1:                               
                   P0=table[Cnt1min%10]|0x80;        //显示分位加点
                   dula=1;
                   dula=0;

                   P0=0x7d;
                   wela=1;
                   wela=0;
                   count=2;
                break;
                case 2:                               
                   P0=table[Cnt1s/10];        //显示十秒位
                   dula=1;
                   dula=0;
               
                   P0=0x7b;
                   wela=1;
                   wela=0;
                   count=3;
                break;
                case 3:                                       
                   P0=table[Cnt1s%10]|0x80;//显示秒位加点
                   dula=1;
                   dula=0;
               
                   P0=0x77;
                   wela=1;
                   wela=0;
                   count=4;
                break;
                case 4:       
                   P0=table[Cnt10ms/10];                //显示十分秒位
                   dula=1;
                   dula=0;
               
                   P0=0xef;
                   wela=1;
                   wela=0;
                   count=5;
                break;
                case 5:       
                   P0=table[Cnt10ms%10];                //显示百分秒位
                   dula=1;
                   dula=0;
               
                   P0=0xdf;
                   wela=1;
                   wela=0;
                   count=0;
                break;
        }
}
回复

使用道具 举报

ID:265318 发表于 2018-1-3 21:46 | 显示全部楼层
wulin 发表于 2017-12-25 16:31
给你一个6位显示百分秒表例程,单键控制开启、暂停、复位。你根据实际电路更改端口定义。
#include
#def ...

抱歉,前几天考试没时间回复我觉得您的回复算是比较有帮助了,但是如果键盘要用外部中断呢?
回复

使用道具 举报

ID:265318 发表于 2018-1-3 21:49 | 显示全部楼层
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

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

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k0=P3^2;
sbit k1=P3^3;

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

u8 ssec,sec,min;
u8 DisplayData[8];
/*******************************************************************************
* 函 数 名         : delay
* 函数功能                   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)  
{
        while(i--);       
}

/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能                   : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0Init()
{
        TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
        TH0=0Xd8;        //给定时器赋初值,定时10ms
        TL0=0Xf0;       
        ET0=1;//打开定时器0中断允许
        EA=1;//打开总中断
        TR0=1;//打开定时器
                               
}
                                                               
/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能                   : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
        u8 i;
        for(i=0;i<8;i++)
        {
                switch(i)         //位选,选择点亮的数码管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//显示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//显示第1位
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;//显示第2位
                        case(3):
                                LSA=1;LSB=1;LSC=0; break;//显示第3位
                        case(4):
                                LSA=0;LSB=0;LSC=1; break;//显示第4位
                        case(5):
                                LSA=1;LSB=0;LSC=1; break;//显示第5位
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;//显示第6位
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;//显示第7位       
                }
                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];
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{       
        Timer0Init();  //定时器0初始化
                    IT0=0;   //外部中断0下降沿触发
     IT1=0;   //外部中断1 下降沿触发
     EX0=1;   //外部中断0允许
     EX1=1;   //外部中断1
         EA=1;
                while(1)
        {
                datapros();
                DigDisplay();       
        }               
}

/*******************************************************************************
* 函 数 名         : void Timer0() interrupt 1
* 函数功能                   : 定时器0中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0() interrupt 1
{
        TH0=0Xd8;        //给定时器赋初值,定时10ms
        TL0=0Xf0;
        ssec++;
        if(ssec>=100)  //1s
        {
                ssec=0;
                sec++;
                if(sec>=60)
                {
                        sec=0;
                        min++;
                        if(min>=60)
                        {
                                min=0;
                        }
                }       
        }       
}
void key0() interrupt 0
{                  delay(1000);
if(k0=0)


           {TR0=!TR0;}
                   while(!k0);
           }
             
             
void key1() interrupt 2
{        delay(1000);
if(k1=0)

         {sec=0;
          min=0;
       
          }
          while(!k1);
           }
            
回复

使用道具 举报

ID:265318 发表于 2018-1-3 21:50 | 显示全部楼层
wulin 发表于 2017-12-25 16:31
给你一个6位显示百分秒表例程,单键控制开启、暂停、复位。你根据实际电路更改端口定义。
#include
#def ...

另外我把我做的放在了楼下如果您有时间可以帮忙看一下的话感激不敬
回复

使用道具 举报

ID:213173 发表于 2018-1-4 06:35 | 显示全部楼层
zjjmw 发表于 2018-1-3 21:50
另外我把我做的放在了楼下如果您有时间可以帮忙看一下的话感激不敬

这样写:if(k0==0)、if(k1==0)。
回复

使用道具 举报

ID:265318 发表于 2018-1-4 18:17 来自手机 | 显示全部楼层
wulin 发表于 2018-1-4 06:35
这样写:if(k0==0)、if(k1==0)。

感谢,确实是这样。。。。但是又有个新问题。k1复位键我加了一个TR0=0使它复位后暂停,但是安完后毫秒位会变成1,得再按一下才会为零。。(另外k1=0为啥要用==啊)
回复

使用道具 举报

ID:130231 发表于 2018-1-8 23:37 | 显示全部楼层
zjjmw 发表于 2018-1-4 18:17
感谢,确实是这样。。。。但是又有个新问题。k1复位键我加了一个TR0=0使它复位后暂停,但是安完后毫秒位 ...

k1=0的意思就是 使之等于0.  并不是测试K1是否等于0。用if(k1==0)的意思就是测试K1是否等于0.如果你硬是暴力把它去掉一个等于。if语句可能就不同意了呀!。if语句可能就不成立了呀!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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