精华内容
下载资源
问答
  • 单片机中断程序
    万次阅读 多人点赞
    2017-07-29 10:21:41

    来源:http://www.51hei.com/mcu/2477.html

    什么是中断?就是打断当前要做的事,转而去执行别的事情。比如小七我现在正在电脑前写帖子,突然老妈叫我帮她下楼拿点东西,于是我就收到了老妈给我的一个中断(可以叫做外部中断),当我去拿东西时,突然尿急(内部中断,尿袋快要撑爆了),这又是一个中断,!我们把引起中断的事件叫做中断源(如老妈给我的任务,以及我的尿意。。。外部引起的叫外部中断,内部引起的叫内部中断),产生中断后就要去处理它,这称为中断的响应

        由于尿急这个内部中断的优先级比老妈给我的外部中断还要高,尿急了,我总得先去撒尿吧?所以我就先去执行撒尿这个语句(小七:怎么我觉得这个比喻很别扭呢?!)。当我撒完尿后(还是觉得很别扭。。。)我会返回来帮老妈拿东西(高优先级的中断处理完后返回执行优先级较低的中断),拿完东西了我再回到电脑前继续写帖子(全部中断处理完后继续接手中断前的工作)。这个就叫做中断的返回。这么通俗的比喻,大家对中断的概念应该都明白了吧,那么在单片机里面,中断有什么用呢?


        当单片机正在执行程序的时候,突然某个按键按下了(产生外部中断),单片机就必须得去处理那个按键(中断的响应),看看是发生了什么事,按键处理完后继续回来执行程序(中断的返回)。

        同样,单片机正在执行程序的时候,内部的定时器溢出(定时器后面会单独讲到),或者检测到单片机的电压低于正常值等等(单片机内部产生的中断叫内部中断),单片机就得去处理这些事情,然后再返回来。

    在单片机里面,中断是有特殊的功能寄存器控制的,单片机里面一共有两个中断,一个是中断0,一个是中断1 ,和两个定时器T0,T1,定时器就是你打开它后,它会自动数数,当数到你给它限定的值时,它就会溢出,产生中断让CPU处理(就像一个桶,你打开水龙头后,水越来越多,当达到你需要的水位时,就会产生中断叫你去处理它)。这些我们先不深入了解他是什么东西,我们只需知道中断是用下面这几个关键词控制的就行了:

    IT0      声明外部中断0的类型,IT0=1是边沿触发,0是电平触发
    边沿触发就是当检测到外部电平发生变化,即由低变高,或者由高变低时,就会产生一个中断
    电平触发就是检测到高电平或者低电平时,产生中断

    IE0     外部边沿触发产生中断后,它的值会变1,当CPU响应后,会自动变为0

    IT1      和IT0一样的含义
    IE1     和IT0一样的含义


    EX0    外部中断0控制器,EX0=1是允许外部中断,0是禁止外部中断,也就是不理会外部中断
    ET0    这个是定时器中断控制器,ET1=1是允许定时器产生中断,0是禁止
    EX1,ET1的含义跟上面的都一样。
    EA      总中断控制器,1是允许有中断产生,0是禁止所有中断,就算天打雷劈也不理会

        另外,还有一个中断优先级的控制器,就是控制是去帮妈妈拿东西的优先级高还是去撒尿的优先级高。


    PX0 外部中断0的优先级控制,假如内外都产生了中断,1就是优先处理外部中断,0就是优先处理内部中断

    PT0 定时器0优先级控制器,1就是优先相应定时器0

    PT1 定时器1优先级控制器,1就是优先相应定时器1

    另外还有串口的RI,TI,PS等我们先不学习了,不然大伙该乱了
    (众人:其实我们早已凌乱了。。。一头雾水!)

        还有个概念,就是中断请求的撤销,也就是说,产生中断后,会产生一个中断请求,为1,当CPU处理完中断后,必须清除这个请求,不然CPU又会认为这个中断没有处理又跑去处理它……

        对于两个定时器产生的中断,当CPU响应后,会自动清除TF0,TF1这两个定制器中断请求,处理完后就跳出来,回到原来的地方继续执行。

        对于外部中断INT0,INT1,如果中断类型是边沿触发,单片机会自动清除中断请求IE0,IE1
    若是电平触发,如果有一个电平,使中断产生后,这个电平仍然还保持着,那么这个电平还会触发中断,这样CPU就死在中断的石榴裙下出不来了。。。

    (众人:说了那么多,没例子你说个J8)

    例子来啦!用外部中断来控制一个LED的亮灭。对了,外部中断并不是单片机的每个引脚都能产生,标有INT0或INT1的才行,我们看看11F02E的引脚图





        中断的引脚是INT0:P3^2和 INT1:P3^3,我们用边沿触发(由高电平变成低电平时,就会触发)的中断方式来控制LED,


        当我们没按下按键的时候,由于上拉电阻(不懂的问百度姐姐哦~)的原因,P3^2是高电平,当我们按下按键后,P3^2的电平就会变低,这个从高变低的过程就会产生一个中断(边沿触发),CPU会第一时间来相应这个中断,看看是谁看帖不回贴,看完帖子不评分,然后根据小七写的中断处理程序去处理他!


    O(∩_∩)O 。

    程序怎么写呢?

     #include <reg52.h> 
    sbit led=P1^7;  //定义LED 
    void zhongduan() interrupt 0 using 1       //声明中断处理函数,由于是外部中断,所以 interrupt X 里X的值是 0 

      led=!led;  //CPU响应中断后会跑来这里执行(让led的状态取反) 

    void main()      //主函数,程序执行的起点 

      EA=1;              //允许CPU响应所有中断 
      IT0=1;             //设外部中断0的响应模式为边沿触发 
      EX0=1;             //允许中断0产生中断 
      while(1);         //CPU不断在这里死循环,中断产生后放下工作去响应中断,处理完后然后再返回来继续死循环 
    }

    按下按键,CPU会跑去中断处理函数执行,执行完中断处理后返回原处继续执行




    (众人:这个中断跟我们前面学习的按键有什么区别么?)


        当然有区别啦!虽然都是控制LED,但是按键是当CPU执行到按键检测如 if(key==0) 语句后,才去改变LED的状态,如果没有执行到,那么即使你按下按键单片机也不会响应的,也就是CPU主动去问按键有没有被按下。而中断呢,就是无论CPU在干嘛,只要触发中断后,CPU就会放下手中的活,第一时间赶回来处理,也就是按键被按下后主动告诉CPU。。。就像windows 系统的 ctrl+alt+del 组合键,你一按下这个组合键,无论系统在做什么,都会弹出任务管理器。


        另外中断的处理函数是这样声明的


    void abc() interrupt X using n
    {
        处理语句;



    我们看到,只是普通的函数 加上了 interrupt X using Y 了而已,X 的取值是有规定的:


    如果是外部中断0的中断处理函数,则X为0 即void abc() interrupt 0 using n


    若是定时器0的中断处理函数,则 X 为1


    若是外部中断1的中断处理函数,则 X 为2


    若是定时器1的中断处理函数,则 X 为3 


    若是串口中断的中断处理函数,则 X 为4

    n 是中断号,取值范围为 0 - 31




    关于中断的学习,也到此告一段落了,当然还有一些问题没解决.......

    Q1: 为什么count==40的时候数码管也不能闪烁???



     
    /*
    实现目的:
    让LED灯以1000ms(即1s)产生流水灯效果,并用定时器0让数码管以500ms从0~F闪烁
    */
    #include<reg52.h>
    #include<intrins.h>
    #define uint unsigned int
    #define uchar unsigned char
    sbit d1=P2^1;
    uchar weixuan=0x00;//位选全开
    uchar code table[]={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71};//段选
    uchar temp,count,num;
    void delay(uint z)
    {
        uint x,y;
        for(x=z;x>0;x--)
    {
    for(y=0;y<113;y++)
    {
    }
    }
    }
    void main()
    {
    count=0;
    num=0;
    P1=weixuan;
    P0=table[num];
    temp=0xfe;
    P2=temp;
    TMOD=0x01;
    TH0=(65535-50000)/256;
    TL0=(65535-50000)%256;
    EA=1;
    ET0=1;
    TR0=1;
    while(1)
    {
    delay(1000);
    temp=_crol_(temp,1);
    P2=temp;
    /*
    if(count==10)
    {
    count=0;
    num++;
    if(num==16)
    {
    num=0;
    }
    P0=table[num];
    } */
    }
    }
    void time0() interrupt 1
    {
    TH0=(65535-50000)/256;
    TL0=(65535-50000)%256;
    count++;
    if(count==10)
    {
    count=0;
    num++;
    if(num==16)
    {
    num=0;
    }
    P0=table[num];
    }  
    }

     

     
    /*
    PS:我们不能把数码管500ms闪烁时间是否到达的语句写在主程序中,
    若写在主程序中,有可能发生如下错误情况:当主程序在LED灯显示语句当中时,
    此时恰好定时器0进入中断并且count刚好加到了10,当定时器0中断再次进入时,
    主程序仍未退出LED流水灯的显示程序,那么此时count的值便变成了11,
    这样的话,count==10这个点永远检测不到,因此数码管闪烁失去了控制


    在调试代码当中发现delay(uint z)函数与中断是同时执行的。。。 
    */  
    更多相关内容
  • 文章介绍了PIC单片机中断程序的设计技巧。
  • 51单片机中断程序大全

    千次阅读 2021-12-31 10:51:41
    51 单片机中断

    在这里插入图片描述

    实例 1:用定时器T1查询方式控制单片机发出1KHz音频

    #include<reg51.h>        //  包含51单片机寄存器定义的头文件
    sbit sound=P3^7;   //将sound位定义为P3.7引脚
    void main(void)
    {
        EA=1;                  //开总中断
    	ET0=1;                 //定时器T0中断允许         
    	TMOD=0x10;            //使用定时器T1的模式1
    	TH1=(65536-921)/256;  //定时器T1的高8位赋初值
    	TL1=(65536-921)%256;  //定时器T1的高8位赋初值
    	TR1=1;                //启动定时器T1
    	TF1=0;
    	while(1)//无限循环等待查询
        {
    	   while(TF1==0);
    		 TF1=0;
    		sound=~sound;  //将P3.7引脚输出电平取反
           TH1=(65536-921)/256;  //定时器T0的高8位赋初值
    	    TL1=(65536-921)%256;  //定时器T0的高8位赋初值
    	 }
     }
    

    实例 2:将计数器T0计数的结果送P1口8位LED显示

    #include<reg51.h>        //  包含51单片机寄存器定义的头文件
    
    sbit S=P3^4;   //将S位定义为P3.4引脚
    
    void main(void)
    {
        EA=1;                  //开总中断
     	ET0=1;                 //定时器T0中断允许         
    	TMOD=0x02;            //使用定时器T0的模式2
    	TH0=256-156;  //定时器T0的高8位赋初值
    	TL0=256-156;  //定时器T0的高8位赋初值
    	TR0=1;                //启动定时器T0
    	while(1)//无限循环等待查询
        {
    	   while(TF0==0)  //如果未计满就等待
      	    {
               if(S==0)  //按键S按下接地,电平为0
    			    P1=TL0; //计数器TL0加1后送P1口显示
            } 
    	    TF0=0;  //计数器溢出后,将TF0清0
    	 }
    }
    

    实例 3:用定时器T0的中断控制1位LED闪烁

    #include<reg51.h>  //  包含51单片机寄存器定义的头文件
    
    sbit D1=P2^0;  //将D1位定义为P2.0引脚
    
    void main(void)
    {
       	EA=1;                  //开总中断
    	ET0=1;                 //定时器T0中断允许         
    	TMOD=0x01;             //使用定时器T0的模式2
    	TH0=(65536-46083)/256; //定时器T0的高8位赋初值
    	TL0=(65536-46083)%256; //定时器T0的高8位赋初值
    	TR0=1;                 //启动定时器T0
    	while(1);
    }
    
    //函数功能:定时器T0的中断服务程序
    **************************************************************/
    void Time0(void) interrupt 1 using 0   //寄存器 
     {
       	D1=~D1;  //按位取反操作,将P2.0引脚输出电平取反
      	TH0=(65536-46083)/256; //定时器T0的高8位重新赋初值
    	TL0=(65536-46083)%256; //定时器T0的高8位重新赋初值
     }
    
    

    实例 4:用定时器T0的中断实现长时间定时

    #include<reg51.h>  //  包含51单片机寄存器定义的头文件
    
    sbit D1=P2^0;  //将D1位定义为P2.0引脚
    unsigned char Countor; //设置全局变量,储存定时器T0中断次数
    
    void main(void)
    {
        EA=1;                  //开总中断
    	ET0=1;                 //定时器T0中断允许         
    	TMOD=0x01;             //使用定时器T0的模式2
    	TH0=(65536-46083)/256; //定时器T0的高8位赋初值
    	TL0=(65536-46083)%256; //定时器T0的高8位赋初值
    	TR0=1;                 //启动定时器T0
    	Countor=0;            //从0开始累计中断次数
    	while(1);
    }
    /**************************************************************
    函数功能:定时器T0的中断服务程序
    **************************************************************/
    void Time0(void) interrupt 1 using 0 
    {
        Countor++;   //中断次数自加1
    	if(Countor==20)  //若累计满20次,即计时满1s
    	{
    	   D1=~D1;     //按位取反操作,将P2.0引脚输出电平取反
    		Countor=0;  //将Countor清0,重新从0开始计数
    	}
      	TH0=(65536-46083)/256; //定时器T0的高8位重新赋初值
    	TL0=(65536-46083)%256; //定时器T0的高8位重新赋初值
    }
    

    实例 5:用定时器T1中断控制两个LED以不同周期闪烁

    #include<reg51.h>  //  包含51单片机寄存器定义的头文件
    
    sbit D1=P2^0;  //将D1位定义为P2.0引脚
    sbit D2=P2^1;  //将D2位定义为P2.1引脚
    unsigned char Countor1; //设置全局变量,储存定时器T1中断次数
    unsigned char Countor2; //设置全局变量,储存定时器T1中断次数
    
    void main(void)
    {
        EA=1;                  //开总中断
    	ET1=1;                 //定时器T1中断允许         
    	TMOD=0x10;             //使用定时器T1的模式1
    	TH1=(65536-46083)/256; //定时器T1的高8位赋初值
    	TL1=(65536-46083)%256; //定时器T1的高8位赋初值
    	TR1=1;                 //启动定时器T1
    	Countor1=0;            //从0开始累计中断次数
    	Countor2=0;            //从0开始累计中断次数 
    	while(1);
    }
    
    // 定时器1
    void Time1(void) interrupt 3 using 0 
    {
        Countor1++;   //Countor1自加1
    	Countor2++;   //Countor2自加1
    	if(Countor1==2)  //若累计满2次,即计时满100ms
    	{
    		D1=~D1;     //按位取反操作,将P2.0引脚输出电平取反
    	    Countor1=0;  //将Countor1清0,重新从0开始计数
    	}
    	if(Countor2==8)  //若累计满8次,即计时满400ms
    	{
    	   D2=~D2;     //按位取反操作,将P2.1引脚输出电平取反
    	   Countor2=0;  //将Countor1清0,重新从0开始计数
    	}		
      	TH1=(65536-46083)/256; //定时器T1的高8位重新赋初值
    	TL1=(65536-46083)%256; //定时器T1的高8位重新赋初值
    }
    

    实例 6:输出50个矩形脉冲

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    
    sbit u=P1^4;    //将u位定义为P1.4
    
    /*************************************************
    函数功能:延时约30ms (3*100*100=30 000μs =30m
    *************************************************/
    void delay30ms(void)
    { 
        unsigned char m,n;
     for(m=0;m<100;m++)
         for(n=0;n<100;n++);
    }
    
    void main(void)
    {
        unsigned char i;
        u=1;    //初始化输出高电平
        for(i=0;i<50;i++) //输出50个矩形脉冲
        { 
            u=1;
         delay30ms();
         u=0;
         delay30ms(); 
        }
        while(1) :
    } 
    

    实例 7:计数器T0统计外部脉冲数

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    
    void main(void)
      {
     	  TMOD=0x06;    // TMOD=0000 0110B,使用计数器T0的模式2
         EA=1;         //开总中断
    	  ET0=0;        //不使用定时器T0的中断     
    	  TR0=1;        //启动T0
    	  TH0=0;       //计数器T0高8位赋初值
    	  TL0=0;       //计数器T0低8位赋初值
    	  while(1)  //无限循环,不停地将TL0计数结果送P1口
         P1=TL0;		
    }
    
    

    实例 8:定时器T0的模式2测量正脉冲宽度

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    
    sbit ui=P3^2;  //将ui位定义为P3.0(INT0)引脚,表示输入电压
    
    void main(void)
    {
        TMOD=0x0a;   // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1
        EA=1;         //开总中断
        ET0=0;        //不使用定时器T0的中断     
        TR0=1;        //启动T0
        TH0=0;        //计数器T0高8位赋初值
        TL0=0;        //计数器T0低8位赋初值
        while(1)       //无限循环,不停地将TL0计数结果送P1口
        {
            while(ui==0) : //INT0为低电平,T0不能启动
            TL0=0;       //INT0为高电平,启动T0计时,所以将TL0清0
            while(ui==1): //在INT0高电平期间,等待,计时
            P1=TL0;    //将计时结果送P1口显示		
        } 
    }
    

    实例 9:输出负脉宽为200微秒的方波

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    
    sbit u=P1^4;    //将u位定义为P1.4
    
    void main(void)
      {
       TMOD=0x02;            //TMOD=0000 0010B,使用定时器T0的模式2
       EA=1;                    //开总中断
    	ET0=1;                  //定时器T0中断允许         
    	TH0=256-200;   //定时器T0的高8位赋初值
    	TL0=256-200;  //定时器T0的高8位赋初值
    	TR0=1;                 //启动定时器T0
    	while(1) : 
    }             //无限循环,等待中断
    void Time0(void) interrupt 1 using 0 //"interrupt"声明函数为中断服务函数
    {
        u=~u;  //将P1.4引脚输出电平取反,产生方波
    }
    
    

    实例 10:测量负脉冲宽度

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    
    sbit u=P3^2;    //将u位定义为P3.2
    
    void main(void)
    {
        TMOD=0x02;  //TMOD=0000 0010B,使用定时器T0的模式2
        EA=1;   //开放总中断
        EX0=1;  //允许使用外中断
        IT0=1;  //选择负跳变来触发外中断
        ET0=1;  //允许定时器T0中断
        TH0=0;  //定时器T0赋初值0
        TL0=0;   //定时器T0赋初值0
        TR0=0;   //先关闭T0
        while(1)    ; //无限循环, 不停检测输入负脉冲宽度
    }
    
    void int0(void) interrupt 0 using 0 //外中断0的中断编号为0
    {   
        TR0=1;   //外中断一到来,即启动T0计时
        TL0=0;  //从0开始计时
        while(u==0)  //低电平时,等待T0计时
            ;
        P1=TL0; //将结果送P1口显示
        TR0=0;  //关闭T0
    }
    

    实例 11:方式0控制流水灯循环点亮

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    #include<intrins.h> //包含函数_nop_()定义的头文件
    
    unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码,该数组被定义为全局变量
    sbit P17=P1^7;
    
    /**************************************************************
    函数功能:延时约150ms
    **************************************************************/
    void delay(void)   
    {
        unsigned char m,n;
        for(m=0;m<200;m++)
            for(n=0;n<250;n++);    
    }
    
    /**************************************************************
    函数功能:发送一个字节的数据
    **************************************************************/
    void Send(unsigned char dat)
    {
        P17=0;     //P1.7引脚输出清0信号,对74LS164清0
        _nop_();   //延时一个机器周期
        _nop_();  //延时一个机器周期,保证清0完成
        P17=1;    //结束对74LS164的清0
        SBUF=dat;  //将数据写入发送缓冲器,启动发送
        while(TI==0)  //若没有发送完毕,等待
            ;
        TI=0;   //发送完毕,TI被置“1”,需将其清0
    }
    
    /*******************************************
    函数功能:主函数
    ******************************************/	
    void main(void)
    {
        unsigned char i;
        SCON=0x00;  //SCON=0000 0000B,使串行口工作于方式0   
        while(1)  
        {
            for(i=0;i<8;i++)
            {
                Send(Tab[i]);  //发送数据
                delay();       //延时
            }
        }
    }
    
    展开全文
  • 51单片机中断程序大全.doc51单片机中断程序大全.doc51单片机中断程序大全.doc51单片机中断程序大全.doc51单片机中断程序大全.doc
  • 本文主要讲了PIC单片机中断程序实例,希望对你的学习有所帮助。
  • 所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断
  • 任务三单片机中断程序设计 西安航空职业技术学院 自动化教研室王曙霞 任务三单片机中断程序设计 中断处理过程 中断处理过程分为三个阶段:中断响应中断 处理和中断返回 中断响应 中断处理(又称中断服务) 三中断返回 ...
  • 单片机中断程序模块应用
  • 单片机中断程序(简单版),仅供参考:#include int0()interrupt 0 { P1; if(P1==0x00) P1=0x01; }
  • 单片机在自主运行的时候一般是在执行一个死循环程序,在没有外界干扰(输入信号)的时候它基本处于一个封闭状态。比如一个电子时钟,它会按时、分、秒的规律来自主运行并通过输出设备(如液晶显示屏)把时间显示出来...
  • c语言编写51单片机中断程序,执行过程是怎样的?

    千次阅读 多人点赞 2017-10-11 09:53:00
    Q:c语言编写51单片机中断程序,执行过程是怎样的?   例如程序:#include&lt;reg52.h&gt; void main(void) { EA=1; //开放总中断 EX0=1; //允许使用外中断 IT0=1; //选择负跳变来触发外中断 P0=0...

    Qc语言编写51单片机中断程序,执行过程是怎样的?

     

    例如程序:
    #include<reg52.h>  
    void main(void)
      {
       EA=1;      //开放总中断
       EX0=1;     //允许使用外中断
       IT0=1;    //选择负跳变来触发外中断 
       P0=0xff;         //关闭所有P0口的LED灯
            while(1); //无限循环,
    }
    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0
    {

      P0=~P0;  //每产生一次中断请求,P0取反一次。
      
    }
    当有中断时,这个程序的执行过程是怎样的???

     

     

     

    A1main开始,开放总中断,允许使用外中断,选择负跳变来触发外中断,到这时负跳变没来没就一直while(1),等待。来了后执行
    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0
    {

      P0=~P0;  //每产生一次中断请求,P0取反一次。
      
    }

     

     

     

     

    A2有中断时直接跑到中断服务去

     

     

     

    A3:CPU会一直在检测是否有中断请求的。当收到中断请求EX 时,进行软件设置,开启总中断EA ,再设置中断的触发方式IT。

    转载自:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=220199

     

     

     

     

    外部中断定时器c语言程序详解

    1. 利用外部中断0,定时器0从数码管到流水灯显示

    2.  

      #include "reg52.h"//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

      #include "intrins.h"

      外部中断定时器c语言程序详解(1)
    3.  

      #define uint unsigned int

      #define uchar unsigned char

      外部中断定时器c语言程序详解(1)
    4.  

      uchar led,n,i,count=0;

      uchar smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f

                ,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F

      uchar sm[]={0x00,0x01};//数码管扫描

      uchar str[2];//显示两位数码管

      外部中断定时器c语言程序详解(1)
    5.  

      /******************************************************************/

      /*                    延时函数声明                                */

      /******************************************************************/

      /*void mdelay(uint t)

      {

        uchar n;

      for(;t>0;t--)

       for(n=0;n<125;n++)

        {;}

      }*/

      /*大约一毫秒的延时函数*/

      void mdelay(uint t)

      {

        uchar n;

      while(t--)

      {

      for(n=0;n<123;n++)

        {;}

        }  

      }

      外部中断定时器c语言程序详解(1)
    6.  

      /******************************************************************/

      /*                   主函数 1                                      */

      /******************************************************************/

      void main()

      {

      EA=1;//开总中断开关

      EX0=1;//打开外部中断0

      INT0=1;//触发方式为下降沿触发

      TH0=0x3c;//设置初值

      TL0=0xb0;

      ET0=1;//打开定时器中断

      TR0=1;//启动定时器

      TMOD=0x01;//设置定时器0为工作方式1

      外部中断定时器c语言程序详解(1)
    7.  

      while(1)

      {

      for(i=0;i<2;i++)//数码管显示数据

      {

      P1=0xff;

      P2=sm[i];

      P0=smg[str[i]];

      mdelay(5);

      }

      }

      }

      外部中断定时器c语言程序详解(1)
    8.  

      void int0() interrupt 0

      {

        uchar c; 

      led=0xfe;

        P2=0x00;

      for(c=0;c<8;c++)//流水灯循环一次

      {

      P1=led;

      led=_crol_(led,1);//左移函数

      mdelay(1000);

      }

      }

      外部中断定时器c语言程序详解(1)
    9.  

      void time0() interrupt 1

      {

      TH0=0x3c;

      TL0=0xb0;

      count++;

        if(count==20)//延时一秒0-60显示

        {

      count=0;

      str[0]=n/10;

      str[1]=n%10;

      n++;

      if(n==60)

      {

       n=0;

          }

        }

      }

    10. 10

      本经验只供参考,如有不足,还请见谅。。。

       

      转载自:https://jingyan.baidu.com/article/870c6fc304cff6b03ee4be45.html

    展开全文
  • 单片机里面有很多中断资源,例如外部中断、定时器中断、串口中断等,这些中断资源应当用于处理相应的紧急事件,而不是顺序执行的常规事件,所以在编写中断程序的时候应当十分注意。 具体的事务处理语句不应放在...

    单片机里面有很多中断资源,例如外部中断、定时器中断、串口中断等,这些中断资源应当用于处理相应的紧急事件,而不是顺序执行的常规事件,所以在编写中断子程序的时候应当十分注意。

    具体的事务处理语句不应放在中断函数里面,中断子程序中的语句应当简洁明了,不应当有太多的语句。假如你在编写中断子程序的时候像在main函数中那样写一大串处理具体事务的指令的话,会在此中断中占用太多的时间,假如当有其他低优先级的中断信号来临的时候也可能导致中断丢失,发生程序的逻辑错误。所以,在中断子程序中的指令语句应当做到最短。

    中断子程序中的语句不应当使用延时函数,不使用whiledo-whiledo-until等有等待延时功能的指令。在中断子程序中使用while、do-while、do-until等指令也会导致单片机在执行过程中在该位置延时或者等待太长的时间,当其他中断信号来临的时候同样也可能导致中断丢失。

    那么应该怎么做呢?

    在编写中断子程序的时候,应当巧用全局状态变量,在中断子程序中只改变状态变量值,在main函数中while(1)程序段内部判断该状态变量的值,根据状态变量的值再分别执行对应的事务处理语句。这就像你接到一个电话要你办某事,你也不能在一直接着电话把这件事做完吧,你需要把事情记下来,挂了电话再安排时间处理。

    举个例子,一个串口触摸屏需要根据触屏中按键来执行对应的操作,需要使用到串口中断。假设触屏在触摸按键1时会发送数据A,触摸到按键2时会发送数据B,那么我们可以定义一个全局状态变量command:

    unsigned char command;

    在串口中断子程序中,根据接收到的不同串口数据改变command的值:

    void 串口1中断函数()

    {

    switch (收到的串口数据)

    {case A:  //假如收到按键1的动作,command赋值x1

    {command=x1;

    break;

    }

    case B:  //假如收到按键2的动作,command赋值x2

    {command=x2;

    break;

    }

    default: break;

    }

    }

    在上面这个串口1的中断子程序中,switch是一个条件选择指令,当串口收到数据A,那么给command赋值x1, 当串口收到数据B,那么给command赋值x2。当然,上面的程序段只是一个说明的示意,不能直接复制编译到单片机中运行,在实际工程中需要根据不同单片机程序的编写规则进行开发。

    接着在main函数中根据command的值执行不同的事务处理语句:

    main函数()

    {

    while(1)

    {

    Switch (command)

    {case x1:   //假如收到按键1的动作,执行事务处理1的程序

    {事务处理1;

    break;

    }

    case x2:  //假如收到按键2的动作,执行事务处理2的程序

    {事务处理2;

    break;

    }

           default: break;

    }

    }

    }

    按照这样的程序,单片机在接收到触屏发出的代表不同按键的串口数据时,在串口中断子程序中改变全局状态变量的值command,这个语句很少,执行时间也短。再到main函数中根据command的不同值分别执行非常耗时间的具体事务处理程序。这样的程序分配,将使单片机运行高效而且合理。

    更多精彩,微 信 公 众 号:yonkotech

    中秋快乐!

    沙鸥  2019.9.13

    展开全文
  • 51单片机 中断程序

    2013-04-21 18:49:14
    51单片机 中断程序 讲述的是51单片机中的中断程序的简单例子,
  • 51单片机程序汇编语言-9中断方式独立按键.zip
  • 单片机MSP430G2553的定时器中断控制LED亮灭一定频率闪烁程序,其他程序比如PWM等单片机MSP430G2553系列代码我会陆续上传,敬请期待。
  • 51单片机中断系统程序实例 (STC89C52RC)51单片机有了中断,在程序设计中就可以做到,在做某件事的过程中,停下来先去响应中断,做别的事情,做好别的事情再继续原来的事情。中断优先级是可以给要做的事情排序。...
  • 蓝桥杯单片机中断请求源 部分中断源信息如下表所示: 外部中断0(INT0)和外部中断1(INT1)既可以上升沿触发,也可以下降沿触发; 部分中断寄存器 包含:中断允许寄存器IE、中断优先级控制寄存器IP、定时器/...
  • 单片机中断就是类似的一个过程,发生中断时,就会打断正在执行的主程序,先处理完中断任务,返回主程序继续运行,当然在执行中断函数之前,单片机需要把关键的数据保存下来,中断函数执行完成后才可以正确的恢...
  • 51单片机的5大中断源:串行口中断、定时中断1、外部中断1、定时中断0、外部中断0;下面一起来学习一下
  • 51单片机中断程序

    2012-07-24 00:13:08
    51单片机中断程序演示。可以进行中断控制
  • PIC单片机按键中断程序的设计技巧,内含按键 长按键代码及注释!
  • 单片机C语言程序设计 INT0中断计数(有源码)单片机C语言程序设计 INT0中断计数(有源码)单片机C语言程序设计 INT0中断计数(有源码)单片机C语言程序设计 INT0中断计数(有源码)单片机C语言程序设计 INT0中断计数(有...
  • proteus单片机中断程序 利用单片机的P0口做输出接8只发光二极管,P3.2引脚接独立按键产生外部中断信号。编写程序,当程序正常运行时8个发光二极管做流水灯显示,当外部中断0有中断请求信号时,8只发光二极管全部点亮...
  • 实现51单片机的外部中断,下降沿触发中断,实现中断功能。
  • 本文主要介绍了单片机中断服务程序中的变量应该如何使用。
  • 本文介绍的是PIC单片机端口RB中断程序设计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 67,934
精华内容 27,173
关键字:

单片机中断程序