单片机实验:外部中断系统实验 如何1357,2468灯交替亮

单片机实验:外部中断系统实验

Date: March 23, 2022


具体代码直接见最下面:

总结:

总结本次实验:

本次学会 单片机的外部中断响应

即通过 外部中断 来实现不同功能

Untitled


实验内容:

Untitled

Untitled

1

Untitled

Untitled

当我们切换开关,比如切换SW2,从高电频到低电频,就会产生下降沿,即,中断,从而引发相应功能

外部中断编程说明:

Untitled

(1)选中何种方式触发中断————选微信铃声

本实验采用 边沿触发有效:

TCON:定时器控制寄存器

如下图上行八位,这里注意IT1和IT0:

其中,IT1设置外部中断1,IT0设置外部中断0

若我们想要让外部中断0设置为边沿触发有效,那就让 IT0 = 1

若我们想要让外部中断0设置为低电频有效,那就让 IT0 = 0

(2)响应中断—————是否接电话

本实验采用开中断,即一中断,就响应

IE寄存器设置:

EA = 1, EX = 1, EX0 = 1 以上三者都设置为1,CPU才会响应中断

(3)设置中断优先级

本实验并没有设置

注意:外部中断0的优先级最高,外部中断1是其次

Untitled

由于本次实验,需要设置边沿触发方式有效,所以需要让 IT0 = 1 , IT1 = 1

程序分析:

Untitled

注意:uchar flag 默认为0

流水灯:1111 1110 ~ 0111 1111

void int1() interrupt 0 interrupt 0指外部中断0的函数

这是一个中断函数,至于它是几的中断函数,看interrupt后的数

  • 关于interrupt()函数的补充:

    interruput X 语句 X是中断标号 计算公式是 :(地址-3)/8=中断标号,其中“地址”*/

    指的是 中断服务程序 的入口地址,比如:

    外部中断0,入口地址为0003H,对应的中断标号为0

    外部中断1,入口地址为0013H(十进制为19),对应中断标号为2

    定时器0中断,入口地址为000BH(十进制为11),对应中断标号为1

    定时器1中断,入口地址为001BH(十进制为27),对应标号为3

    串口中断,入口地址为0023H(十进制为35),对应中断标号4

    入口地址在数据手册里有

Untitled

void int2() interrupt 2 interrupt 2指外部中断1的函数

Untitled

注意:EA EX1 EX0 = 1 意味着会响应边沿触发

IT1 IT0 = 1 意味着选择边沿触发方式

Untitled

Untitled

注意一开始 flag = 0, 当有 边沿触发时,即我们将开关从高电位切到低电位时,会有中断产生,具体情况如下:

比如切换开关SW2,从高电频到低电频,即 边沿触发,会有中断产生,

Untitled

当产生中断时,程序又会自动跳到中断函数处:

Untitled

此时会改变flag = 0x01

从而当程序再次进入main函数中时,switch就会切换到 flag = 1,从而选择case1

即选择 流水灯

case 1:
			for(i=0;i<8;i++){
		     	if(flag==0x02) break;
	       	P2=tab[i];
	       	delay(1);
	       	}
	     	if(flag==0x02) break;  //也许是异常处理
	     	P2=0x00;  //全亮
	     	delay(1);
	      	break;

思考题:

Untitled

Untitled

操作步骤:

程序设计思路:

1357亮

延时函数

2468亮

延时函数:

修改程序即可,加1s的延时即可,借助于STC的延时函数

Untitled

注意:0为低电位,7为高电位

最终代码:

#include "reg51.h"
#include<intrins.h>  //可以使用_nop_函数的头文件
#define uchar unsigned char

const tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f} ; //正向流水灯

uchar flag;

void delay(int x){	 //延时程序
   unsigned i,j,k;
   while(x--){
		for(i=0;i<0x01;i++)
    	for(j=0;j<0xff;j++)
      	for(k=0;k<0xff;k++);
   }
}

//延时1s:
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void int1()interrupt 0 //外部中断0的中断服务函数
{
    flag=0x01;
}

void int2()interrupt 2 //外部中断1的中断服务函数
{
    flag=0x02;
}

void main(){

	uchar i;
	EA=1;
	        //总中断允许
	EX0=1;
	        //允许外部中断0中断
	EX1=1;
	        //允许外部中断1中断
	IT0=1;
	        //选择外部中断0为跳沿触发方式
	IT1=1;
	        //选择外部中断1为跳沿触发方式
	P2=0xff;
	
	while(1)
	{
	  switch(flag){
	    case 1:
			for(i=0;i<8;i++){
	     	if(flag==0x02) break;
	       	P2=tab[i];
	       	delay(1);
	       	}
	     	if(flag==0x02) break;
	     	P2=0x00;
	     	delay(1);
	      	break;
		case 2:
			
		//功能:要让1357灯亮,2468灯灭
		  	
			P2 = 0xaa;
			Delay1000ms();
			P2 = 0x55;
			Delay1000ms();

			break;			

		//test:  success!
		//拓展:所有灯全亮,过1s,全灭
		/*
			P2=0x00;
			delay(1);
			P2=0xff;
			delay(1);
			break;
		*/
			
	    }
	}
  }
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值