STC15F2K60S2/中断详细讲解

STC15F2K60S2中断程序详细讲解

T0中断
/****************************************************************/
/****************************2019.11.15**************************/
/********************吉林大学无线电爱好者协会********************/
/**************************单片机基础培训************************/
/************************Creat by Devilaboy**********************/
/****************************************************************/
/****************************************************************/


/*************************头文件+宏定义区************************/
#include <STC15FXXXX.H>
#define key1 P33
#define key2 P32
#define led1 P00
#define led2 P01
#define led3 P02
#define led4 P03
#define led5 P04
#define led6 P05
#define led7 P06
#define led8 P07
#define uchar unsigned char

/****************************函数声明*************************/
void breath();
void Timer0Init(void)	;
void delayus(unsigned int a);
/***************************主函数*****************************/
void main()	
{
	Timer0Init();
  breath();
}
/****************************中断函数*************************/
void Timer0Init(void)	//(我们的T0用的是16位自动重装定时器模式)
{
	TMOD=0x00;// 16位自动重装
	TL0 =( 65536-50000)%256;//低位装入	(对于晶振为12MHz的片子来说,65536-50000,意思是实现程序的50ms定时,因为一次指令周期是1us,这里执行了50000个指令周期才溢出)
	TH0 = (65536-50000)/256;//高位装入
	EA=1;   //打开全局中断
	ET0=1;  //打开定时器1中断
	//TF0 = 0;//中断溢出清零,对于TMOD=0x00模式来说,该操作由系统自动完成
	TR0 = 1;//开启定时器0
}

uchar a=0;
void TIME0() interrupt 1  //定义定时器0中断函数
{
  a=a++;
  if (a==20)//执行20次循环,即定时器中断效果显现设定为非常准确的1s
    {
      led2=~led2;led4=~led4;led6=~led6;led8=~led8;
	    a=0;
    }
}

/************breath***********/
void breath()//设计一个模拟PWM波控制的呼吸灯程序,大家可以自己想一下为什么会有这种效果
{
  int b=0,c=1600;
//  while(1)
//  { 
    for(b=1;b<c;b++)//大家可以试下让b=0,看一看灯会有什么效果,并想一想这是为什么
    {
	    led1=0;led3=0;led5=0;led7=0;
      delayus(b);
      led1=1;led3=1;led5=1;led7=1;
      delayus(c-b);
    }
	  for(b=1500;b>0;b--)
    {
	    led1=0;led3=0;led5=0;led7=0;
      delayus(b);
      led1=1;led3=1;led5=1;led7=1;
      delayus(c-b);
    }
//  }
}
void delayus(unsigned int a)		//@12.000MHz
{
	  while(--a);
}

一、上面程序涉及到的几个相关寄存器

1、TCON(可位寻址)

这里我们内部中断常用到的就是TF0/1 、TR0/1
可位寻址的意思就是,我们不用写整个寄存器的名字来设置这个寄存器,我们直接写寄存器中的某一位的名字就可以来设置了。
在这里插入图片描述

2、TMOD(不可位寻址)

在这里,我们主要设置
1、定时器的工作模式
2、是内部中断触发还是外部中断触发
其中我们常用的工作模式是
模式0:16位自动重装(在用内部时钟中断的时候常用)
模式2:8位自动重装(在设置波特率的时候常用,在我的另一篇介绍有关串口中断的文章中深有体现,附上文章链接https://blog.csdn.net/Star19180325/article/details/103396806
在这里插入图片描述

3、IE(中断允许寄存器)/IP(中断优先级设置寄存器)(可位寻址)

这里我们常用到的有
EA:开启全局中断
ET0/1:打开定时器0或者定时器1的中断
在这里插入图片描述

二、定时器0的介绍

设置一个定时器中断的大致过程就是
1、配置寄存器工作方式
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

三、中断级别以及中断程序的大致写法介绍

中断源默认中断级别序号(C语言用)入口地址(汇编语言用)
INT0,外部中断0最高00003H
T0,定时器/计数器0中断第21000BH
INT1,外部中断1第320013H
T1,定时器 /计数器1中断第43001BH
TI/RI,串行口中断第540023H
T2,定时器/计数器2中断最低5002BH

单片机在使用中断功能时候,通常需要设置两个与中断有关的寄存器
IE:中断允许寄存器
IP:中断优先级寄存器
具体的使用方法在上面的技术文档截图中已经介绍过了,在这里不再赘述。

void TIME0() interrupt 1  //定义定时器0中断函数
{
  a=a++;
  if (a==20)//执行20次循环,即定时器中断效果显现设定为非常准确的1s
    {
      led2=~led2;led4=~led4;led6=~led6;led8=~led8;
	    a=0;
    }
}

这里我们看到,是定时器0的中断程序的写法

普适格式如下

void 函数名() interrupt 中断号 using 工作组
{
   中断服务程序//(中断程序里面的东西最好能迅速的执行,不要有延时什么的,否则会影响正常程序的执行)
}

这里需要注意几点

  1. 中断程序不能有任何的返回值,所以函数定义的时候一定是void
  2. 函数名的名字可以随便起,但是一定要方便辨认,不要和已有的函数名冲突
  3. 中断函数里面应该不能带任何的参数,所以函数名后面的()里面是空的,或者写void
  4. 中断序号指的是单片机那几个中断源的序号,具体的请看上面的那个表;这个序号非常重要,是编译器识别不同中断的唯一符号,因此在写中断服务的时候一定一定一定要写好,写正确。
  5. using 工作组:是指这个中断函数使用单片机内存4组工作寄存器中的哪一组,对于KEIL,编译器在变异的时候会自动分配工作组,所以这个通常我们会直接忽略

四、附上其他的程序

T0+T1中断
/****************************************************************/
/****************************2019.11.15**************************/
/********************吉林大学无线电爱好者协会********************/
/**************************单片机基础培训************************/
/************************Creat by Devilaboy**********************/
/****************************************************************/
/****************************************************************/


/*************************头文件+宏定义区************************/
#include <STC15FXXXX.H>
#define key1 P33
#define key2 P32
#define led1 P00
#define led2 P01
#define led3 P02
#define led4 P03
#define led5 P04
#define led6 P05
#define led7 P06
#define led8 P07
#define uchar unsigned char

/****************************函数声明*************************/
void breath();
void Timer01Init(void)	;
void delayus(unsigned int a);
/****************************主函数*****************************/
void main()	
{
	while(1)
	{
	   Timer01Init();
       breath();
	}
}
/****************************中断函数*************************/
void Timer01Init(void)	
{
	TMOD=0x00;
	TL0 =( 65536-50000)%256;	
	TH0 = (65536-50000)/256;
	TL1 =( 65536-50000)%256;
	TH1 = (65536-50000)/256;
	EA=1;  
	ET0=1;  
	ET1=1;  
	//TF0 = 0;//中断溢出清零,对于方式0来说,由系统自动清零
	TR0 = 1;
	TR1 = 1;
}

uchar a=0,b=0;
void TIME0() interrupt 1
{
  a=a++;
  if (a==20)
    {
       led5=~led5;led6=~led6;
	   a=0;
    }
}

void TIME1() interrupt 3
{
  b=b++;
  if (b==10)
    {
       led7=~led7;led8=~led8;
	   b=0;
    }
}
/************breath***********/
void breath()
{
  int b=0,c=1600;
//  while(1)
//  { 
    for(b=1;b<c;b++)
    {
	   led1=0;led2=0;led3=0;led4=0;
       delayus(b);
       led1=1;led2=1;led3=1;led4=1;
       delayus(c-b);
    }  
	  for(b=1500;b>0;b--)
    {
	   led1=0;led2=0;led3=0;led4=0;
       delayus(b);
       led1=1;led2=1;led3=1;led4=1;
       delayus(c-b);
    }
//  }
}
void delayus(unsigned int a)		//@12.000MHz
{
	  while(--a);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值