51单片机笔记[2]-中断模块

2022/9/1 6:53:11

本文主要是介绍51单片机笔记[2]-中断模块,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

实验目的

  1. 熟悉Keil,Proteus软件的使用
  2. 熟悉中断的概念,以及编程中的应用

实验内容

开关中断控制发光二极管的亮灭

  1. 按下开关K3(P3.2),8个发光二极管点亮与熄灭循环交替
  2. 按下开关K4(P3.3),前4个发光二极管与后4个发光二极管交替点亮

定时器中断控制数码管显示

  1. 按下P3.2“计数”按键时,中断程序累加计数,通过数码管(连接在P2口)显示按键次数。(计数范围0-9)
  2. P3.3“清零按键”时,数码管清零

原理

中断(stc官方datasheet有详细介绍)

中断有如下几种类型:

  • 外部中断
  • 定时器中断
  • 串口中断
  • 低压检测中断
  • 比较器中断
  • PWM中断及PWM异常检测中断

为了能让大家更容易理解中断概念, 我们先来举一个生活事例: 你打开火, 烧上一壶水。然后去洗衣服,在洗衣服的过程中,突然听到水壶发出水开的报警 声,这时,你停止洗衣服动作,立即去关掉火,然后将开水灌入暖水瓶中,灌完 开水后,你又回去继续洗衣服。这个过程中实际上就发生了一次中断。引起 CPU 中断的根源称为中断源,每一个中断源有一个优先级别。

中断流程
中断程序流程

中断嵌套与中断优先级

中断嵌套
中断优先级
中断优先级硬件实现

中断函数与中断号


所用的stc15w4k32s4提供了21个中断请求源.我们主要用到外部中断0(interrupt 0或称INT 0),定时器0中断(interrupt 1),外部中断1(interrupt 2,INT 1),定时器1中断(interrupt 3).
我们可以通过操作「中断允许寄存器」或「中断优先级控制寄存器」来暂时屏蔽某个中断。

CPU中断对比RTOS中的任务管理

[https://www.cnblogs.com/dream397/p/15895220.html]
在RTOS内核中,不再单纯的只有一个main函数在跑,而是系统中「同时存在多个任务」,由内核根据不同的任务优先级进行抢占式调度执行。

RTOS内核中PendSV异常(任务切换/调度)的优先级被设为最低,有3个优点:

① 使得在「任何任务」的执行过程中,都可以被外设产生的中断请求所中断(假设中断都已经使能);

② 避免在中断处理程序中产生任务切换;

③ 使得中断处理程序可以按照中断优先级正常嵌套,不会受任务的影响;

这样一来,即使程序中有了RTOS内核,「从中断产生到执行中断处理程序的整个过程都和裸机程序没有什么不同」。

51单片机扩展外部中断源

[https://blog.csdn.net/billliu66/article/details/121572136]
主要有如下几种方法扩展外部中断:

  • 使用专用芯片,如8259A
  • 内部定时器做计数器用,计数值达到1时就触发中断,对条件进行判断,进行相应动作
  • 外部中断端口二极管并接输入,利用软件查询定位输入源

时钟

实验过程

流程图

开关控制LED灯 开关计数器

原理图

开关控制二极管亮灭 定时器中断

代码

文件:4.c

#include <stdio.h>
//#include <reg52.h>
#include <stc15f2k60s2.h>
sbit KEY_3 = P3^2;
sbit KEY_4 = P3^3;
//延时函数
void delay(int ms){
	int i,j;
	for(i=0;i<ms;i++){
		for (j=0;j<114;j++);
	}
}
//中断服务函数
	//8个LED点亮与熄灭循环交替
void LED_FN_1() interrupt 0{
	if(KEY_3==0){
	while(1){
  IT0=1; //外部中断0为下降沿触发
	IT1=1; //外部中断1为下降沿触发
	EX0=1; //开EX0中断
	EX1=1; //开EX1中断 
	EA = 1;   // 打开总中断
		
			P6=0xff;
			delay(200);
			P6=0x00;
			delay(200);
		
	 }
	}
}
	//前四个发光二极管与后4个发光二极管交替点亮
void LED_FN_2() interrupt 2{
	
	if(KEY_4==0){
	while(1){
	IT0=1; //外部中断0为下降沿触发
	IT1=1; //外部中断1为下降沿触发
	EX0=1; //开EX0中断
	EX1=1; //开EX1中断 
	EA = 1;   // 打开总中断
		P6=0xf0;
		delay(200);
		P6=0x0f;
		delay(200);
	 }
	}
}
//主函数
void main(void)
{
	unsigned int i = 0;
	IT0=1; //外部中断0为下降沿触发

	IT1=1; //外部中断1为下降沿触发

	EX0=1; //开EX0中断

	EX1=1; //开EX1中断 
	
	EA = 1;   // 打开总中断

	while(1)
	{
		//等待中断
	}
}

文件:5.c

#include <stdio.h>
//#include <reg52.h>
#include <stc15f2k60s2.h>
sbit KEY_3 = P3^2;
sbit KEY_4 = P3^3;
int count=0;
//段码表
unsigned char distab[16] = {
	0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};//0-F
//显示函数
void show_char(int input){
		P4=0xFF;
		P4=~distab[input];
}
//延时函数
void delay(int ms){
	int i,j;
	for(i=0;i<ms;i++){
		for (j=0;j<114;j++);
	}
}
//中断服务函数
	//8个LED点亮与熄灭循环交替
void LED_FN_1() interrupt 0{
	if(KEY_3==0){
		if(count>=9) count=0;
		count+=1;
			show_char(count);
			delay(2000);
			P6=0xff;
			delay(1000);
			P6=0x00;
			delay(1000);
	}
}
	//前四个发光二极管与后4个发光二极管交替点亮
void LED_FN_2() interrupt 2{
	if(KEY_4==0){
		count=0;
		show_char(count);
		delay(1000);
		//P6=0xf0;
		P6=0xf0;
		delay(200);
		P6=0x0f;
		delay(200);
	}
}
//主函数
void main(void)
{
	unsigned int i = 0;
	IT0=1; //外部中断0为下降沿触发

	IT1=1; //外部中断1为下降沿触发

	EX0=1; //开EX0中断

	EX1=1; //开EX1中断 
	
	EA = 1;   // 打开总中断

	while(1)
	{
		
		//等待中断
	}
}


这篇关于51单片机笔记[2]-中断模块的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程