对于c51外部中断和程序调用的理解

Posted lanmanuesr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对于c51外部中断和程序调用的理解相关的知识,希望对你有一定的参考价值。

对于c51外部中断和程序调用的理解


四川师范大学工学院2018级 徐浩宇

首先介绍一下C51外部中断的基本概念

  • 中断的优点:
    1、实时处理。需要CPU立即做出相应或处理。
    2、异常处理。运行过程中,出现断电、程序出错等问题,就需要CPU对故障源进行处理。
    3、提高效率。采用中断技术可以大大提高CPU的运行效率。

  • 中断源:C51单片机有5个中断源(2个外部中断、2个定时器中断和一个串口中断)。对中断的配置操作,主要通过控制三个寄存器就可以(中断允许寄存器IE)、定时器控制寄存器(TCON)和中断优先级寄存器(IP)。即通过控制EA EX IT 的直接赋值,即可调用中断服务程序
    注:中断服务程序与while(1)中的程序调用是不一样的

  • 中断服务函数:在CPU接收到中断后,会执行相应中断的中断服务函数。而C51的中断服务函数需要在函数名括号后面加上interrupt 和标志号,即interrupt 0、interrupt 1。

//外部中断0程序:
EA=1;//打开总中断开关
EX0=1;//开外部中断0
IT0=0/1;//设置外部中断的触发方式```

//外部中断1程序:
EA=1;//打开总中断开关
EX1=1;//开外部中断0
IT1=0/1;//设置外部中断的触发方式

//外部中断0服务函数:
void EX0_ISR(void) interrupt 0
	
	
	
	
 //外部中断1服务函数:
void EX1_ISR(void) interrupt 2     //外部中断1的中断在此为2!!!! 
	
	
	

其次来说一下"真假"中断

外部中断的调用主要分为两种,

  • 一种是调用外部中断来作为定时器,较为精确的计时;
  • 另一种是将函数写在中断服务函数中,调用外部中断进行函数的执行。

下面举例程序,经过两个不同方式外部中断的调用,达到同一个效果。

首先是proteus原理图的建立,如图

方式一,通过外部中断建立较为精准的计时,在while(1)中进行程序的执行。

#include <REGX51.H>

#define  uchar unsigned char
#define ledPort  P0
sbit LED = P0^0;
sbit button = P3^2;
void delay_ms(uchar ms);
uchar scan_key();
void initTimer(void);

unsigned int g_uiCount;
uchar delay_6ms;
uchar g_keys[3];

void main()

	uchar uci,ucDir=0;
	initTimer();
	TR0=1;
	ET0=1;
	EA=1;
    uci=0;
   while(1)
   
	  if(g_keys[0]==1)
			
					g_keys[0]=0;
				//°´¼ü´¦Àí
				if(ucDir==0)
					
						ucDir=1;
						
				else
					
						ucDir=0;
					
			
	  if(g_uiCount==500)
			
				g_uiCount=0;
				if(ucDir)
					
						ledPort = ~(1<<uci) ;
						uci=(uci+1)%8;
					 
				else
					
						uci=uci;
					
			
   
	
void initTimer(void)

 TMOD=0x1;
 TH0=0xfc;
 TL0=0x18;


void fun_6ms_isf();
void timer0(void) interrupt 1

  TH0=0xfc;
  TL0=0x18;
  g_uiCount++;
  if(++delay_6ms==6)
  
  	delay_6ms=0;
		fun_6ms_isf();
  


uchar get_key()

	button=1;
	if(button==0)
		
				return 1;
		
	else 
		
				return 0;
		


void fun_6ms_isf()

	 uchar key;
	 key=get_key();
	 if(key==1)
		 
			if(g_keys[0]==0x80)
				
					 g_keys[0]=1;
					
		 
	 else
		 
				g_keys[0]=0x80;
		 
		   

方式二,将程序直接写在外部中断中

#include <REGX51.H>
#define  uchar unsigned char
#define ledPort  P0
sbit LED = P0^0;

unsigned int g_uiCount; //¼ÆÊýÁ¿
void main()

	uchar uci,ucDir=0;
	EA=1;
	EX0=1;   
	IT0=0;  
  uci=0;
  while(1)
	

void timer0(void) interrupt 0

		uchar uci,ucDir=0;
    g_uiCount++;
  	  if(g_uiCount==5000)
	  
	  	g_uiCount=0;
			ledPort = ~(1<<uci) ;
			uci=(uci+1)%8;
	  



程序功能:

两组程序的效果一模一样,都是在有按键控制的情况下,按下按键,流水灯开始运行,当按键没有按下时,流水灯停止在当前的LED灯上,待下次继续按下时,流水灯继续执行。

  • 但需注意的是第一方法的程序除了上述流水灯功能外,无法同时执行其他的程序,但第二个方法的程序就可以在while(1)主程序中添加其余程序,使之在按键按下的时候执行流水灯程序,其余时刻执行主程序。、

所以可以说方法一的程序是"假"中断程序,而方法二的程序才是"真"中断程序。


总结

C51单片机,仅仅有两个外部中断,非常适合理解外部中断、中断服务函数的概念。多次调用中断程序,可以使C51程序编写更加有条理性。

若将所有需要执行的语句,以及其条件判断语句统统放在while(1)中,不仅使得编写的程序看起来臃肿、无条理性,更容易使时序产生误差。

以上是关于对于c51外部中断和程序调用的理解的主要内容,如果未能解决你的问题,请参考以下文章

用C51单片机的外部中断设计1s定时器

用C51单片机的外部中断设计1s定时器

单片微机原理P2:80C51外部中断与定时器系统

单片机C51的中断程序应该怎么写

C语言中,用于设置中断、中断信号的函数都有哪些?怎么设置一个发送中断信号(自己定义的)的函数?

C51中定时器中断的函数中interrupt和using如何使用