设计二:51单片机外部中断控制

目录

一、设计内容

二、中断相关知识

1、51单片机中断源

2、中断系统特殊功能寄存器

3、中断函数与函数调用区别

三、仿真原理图

四、程序设计

五、仿真结果

六、思考题

作者有话说


一、设计内容

       本次设计使用2个按键,在无按键按下时,最下面一位发光二极管点亮;当KEY1按下,外部中断0请求中断,控制发光二极管从下到上循环点亮3圈;当KEY2按下,外部中断1请求中断,控制发光二极管闪烁3次。(要求外部中断1优先级高于外部中断0,即KEY2按下后能够打断流水灯的动作,当外中断1处理完后,恢复外中断0的处理,并且能从上次打断的那个LED开始循环)。

二、中断相关知识

1、51单片机中断源

中断源

中断号

入口地址

外部中断0

0

0003H

外部中断1

2

0013H

定时器T0

1

000BH

定时器T1

3

001BH

串口中断

4

0023H

2、中断系统特殊功能寄存器

     中断允许寄存器IE、定时器/计数器T0/T1控制寄存器TCON、定时器/计数器T2控制寄存器T2CON 、串口控制寄存器SCON

3、中断函数与函数调用区别

      中断函数不能有返回值、中断函数不能传递参数、中断函数程序应该短小精悍

三、仿真原理图

四、程序设计

/*******************************************************************************
* 函 数 名  				: main
* 函数功能		      : 外部中断
* 创作者  					: 薄情书生
* 创作时间  				: 2022.9.27
*******************************************************************************/
main.c文件

#include "reg52.h"         
#include "led.h"
#include "exit.h"

/*************38译码器**************/
void SelectHC138(unsigned char channel)
{
   switch(channel)
	 {
		 case 0:
        P1 = (P1 & 0x1f)|0x00;break;    //发光二极管(LEDS0)
   }
}

/*************主函数******************/
void main()
{
  SelectHC138(0);
	Exint_Init();
	while(1)
	{
		P0 = 0x7f;
	}
}


delay.c文件

#include "delay.h"

/*********毫秒延时*********/
void delay_ms(u16 ms)
{
	u16 x,y;
	for(x=ms;x>0;x--)
		for(y=114;y>0;y--);
}


led.c文件

#include "led.h"
#include "reg52.h"
#include "delay.h"
#include "intrins.h"

/*************LED由下至上**************/
void Bottom_Up()
{
	u8 i,j;
	for(j=0;j<3;j++)
	{
		for(i=0,P0 = 0xff;i<8;i++)
		{
			P0 = P0<<1;	 
			delay_ms(200); 
		}
	}
	P0 = 0xff;
}

/*************LED由上至下**************/
void Up_Bottom()
{
	u8 i,j;
	for(j=0;j<3;j++)
	{
		for(i=0,P0 = 0xff;i<8;i++)
		{
			P0 = P0>>1;	 
			delay_ms(100); 
		}
	}
	P0 = 0xff;
}

/*************LED齐闪烁**************/
void LED_twinkle()
{
	u8 i,j;
	for(j=0;j<3;j++)
	{
		for(i=0,P0 = 0x00;i<3;i++)
		{
			P0 = ~P0;	 
			delay_ms(500); 
		}
	}
	P0 = 0xff;
}

/*************LED保持3s**************/
void Hold_3s()
{
	P0 = 0x00;	 
	delay_ms(3000); 
	P0 = 0xff;
}

/*************两边至中间**************/
void LED_sides()
{
	u8 i,j,ri,lf;
	for(j=0;j<3;j++)
  {
		for(i=0,ri=0x7f,lf=0xfe;i<4;i++)
		{
			P0 = ri&lf;
			ri = _cror_(ri,1);
			lf = _crol_(lf,1);
			delay_ms(1000);
		}
  }
	P0 = 0xff;
}

/*************中间至两边**************/
void LED_middle()
{
	u8 i,j,ri,lf;
	for(j=0;j<3;j++)
	{
		for(i=0,ri=0xef,lf=0xf7;i<4;i++)
		{
			P0 = ri&lf;
			ri = _crol_(ri,1);
			lf = _cror_(lf,1);
			delay_ms(1000);
		}
	}
	P0=0xff;
}


exit.c文件

#include "exit.h"
#include "reg52.h"
#include "led.h"

/*********外部中断0、1初始化***********/
void Exint_Init()
{
	IT0 = 0;
	IT1 = 0;
	PX0 = 0;
	PX1 = 1;
	EA = 1;
	EX0 = 1;
	EX1 = 1;
}

/*********外部中断0服务函数***********/
void Exint0_Service() interrupt 0
{
	Up_Bottom();
}

/*********外部中断1服务函数***********/
void Exint1_Service() interrupt 2
{
	LED_twinkle();
}

五、仿真结果

无按键按下时,最下面一位发光二极管点亮。

 KEY1按下,外部中断0请求中断,控制发光二极管从下到上循环点亮3圈。

 KEY2按下,外部中断1请求中断,控制发光二极管闪烁3次。

KEY2按下后能够打断KEY1流水灯的动作,当外中断1处理完后,恢复外中断0的处理,并且能从上次打断的那个LED开始循环。

、思考题

请修改程序,将INT0和INT1的优先级都设置成0,先按下KEY2,在LED的闪烁过程中按下KEY1,看能否打断LED的闪烁?原因是什么?思考题参考程序将在设计三:51单片机数码管显示控制给出。

作者有话说

本专栏为51单片机实战教程,旨在以练促学,帮助小伙伴快速入门51单片机,学习51单片机相应理论知识请自行学习。本次设计涉及的相关理论知识:51单片机外部中断控制、独立按键的使用、模块化编程,请自行参考资料学习。

本次设计源程序及仿真源文件百度网盘链接:链接:https://pan.baidu.com/s/1TNwn74gbOoMzb3Wcqopvrg 
提取码:vga5 
 

设计一:51单片机控制流水灯思考题参考源程序及仿真源文件百度网盘链接:https://pan.baidu.com/s/1bdtvHcNLI8ydR_t94DWQXw 
提取码:gnv6 

猜你喜欢

转载自blog.csdn.net/weixin_53402301/article/details/130978988