实验三 外部中断实验

该实验旨在理解和掌握单片机中断概念,通过Proteus8.9仿真了一个使用外部中断的项目。实验内容包括按键次数显示、清零和报警功能,涉及3个按键与中断INT0-INT2的连接,以及6位数码管和1个LED灯的控制。程序设计中,按键K1计数显示,K2清零,K3切换报警阈值,且当计数超过阈值时LED报警。代码包括主程序、中断服务函数等,实验报告提供了详细的设计思路和调试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验三题目

一、实验目的

  1. 理解单片机中断的概念。
  2. 掌握外部中断的编程方法。

二、实验内容

  1. 验证课堂例题
    编译下载运行课堂例题——“按键次数显示”(INT_EX1)和“按键次数显示清零”(INT_EX2),查看运行结果。理解程序的编程思想和程序执行过程。
  2. 设计程序
    参考上述例题的电路和编程思路,自行设计电路,包括三个按键K1、K2和K3,分别连接外部中断INT0-INT2,6位数码管显示,1个LED报警灯;编程实现K1按键次数的显示,显示数据清零和次数越限报警等功能。
    具体要求如下:
    (1)初始状态下,数码管显示“200000”,其中后两位用于K1按键次数显示,前两位用于当前按键次数报警阈值显示(报警阈值初始为20);
    (2)每当K1按下时,后两位数码管显示K1按下次数,计数到报警阈值时不再进行累加;
    (3)当计数超过当前设置的报警阈值时,LED进行点亮报警,此时再按下K1不再进行计数;
    (4)K2按下时,显示计数值清零并且LED熄灭,即解除报警。
    (5)K3每按下一次,按键次数报警阈值在20、15、10、5间进行循环转换,并在数码管前两位进行当前报警阈值的显示,并且显示计数归零。
    在设计报告中,需进行总体设计思路描述,给出所涉及到的主程序、中断程序、关键功能子函数的流程图和设计代码。描述程序调试结果及出现的问题。## 实验代码
#include <iom16v.h>
#include <macros.h>

#define uchar unsigned char 
#define uint unsigned int 
/*
a-用于KEY1按键次数,按下KEY1,a就会+1
b-用于阈值比较,a>b,就会报警
C用于6位数码管显示,初始值为200000
*/
long a=0,b=20,c=200000; 
//本组改进了数码管显示函数,直接显示int型数据即可
//void LEDshow(int num)    调用:LEDshow(202210);即可显示202210 
//uchar LEDBuf[6]={2,0,0,0,0,0};//存放数码管显示数据,0-9数字格式

//延时函数
void delay(uint ms)         //延时函数
{
   uint p,q;
   
   for(p=0;p<ms;p++)
   {
	  for(q=0;q<1141;q++);
   }
}	

//系统初始化
void Init(void)
{  
   DDRA|=BIT(PA3); //PA3设置为输出状态
   DDRA|=BIT(PA4); //PA4设置为输出状态
   
   DDRC=0xFF; //PB口设置为输出状态 
    
   DDRD = 0X00; //K1 K2按键设置为输入端口
   DDRB&= ~BIT(PB2);//K3按键设置为输入端口
   DDRB|=BIT(PB7);//LED报警灯端口初始化
   PORTD = 0XFF; //使能K1 K2上拉电阻
   PORTB|=BIT(PB2);//使能K3上拉电阻
   
   MCUCR=0x0A; //下降沿INT0 K1,下降沿INT1 K2
   MCUCSR&=0XBF;//下降沿INT2 K3
   GICR|=0b11100000; //允许INT0 INT1 INT2
}

//6位共阴极数码管 
//uchar const DuanXuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9
uchar const WeiXuan[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//从左到右第0-5位数码管

//数码管显示函数
//数码管从左到右刷新一次 
//num-显示的数字
void LEDshow(long num)//本组对数码管的显示做了改进,直接显示整形数据即可  
{   
   uchar i;
   long s;
   s=num;

   for(i=0;i<6;i++)//循环扫描一次
   {   
      PORTC=WeiXuan[i];		     //选择第i位数码管
      PORTA|=BIT(PA4);		     //PA4输出高电平,位选端拉高
	  //delay(1);
      PORTA&=~BIT(PA4);	         //PA4输出低电平,位选端拉低,位选锁存
	     switch(s%10)//显示段码数字,这个是共阴码
    {
      case 0:PORTC=0X3F;break;
      case 1:PORTC=0X06;break;
      case 2:PORTC=0X5b;break;
      case 3:PORTC=0X4f;break;
      case 4:PORTC=0X66;break;
      case 5:PORTC=0X6d;break;
      case 6:PORTC=0X7d;break;
      case 7:PORTC=0X07;break;
      case 8:PORTC=0X7f;break;
      case 9:PORTC=0X6f;break;
    }
      PORTA|=BIT(PA3);		    //PA3输出高电平,段选端拉高
	  //delay(1);
      PORTA&=~BIT(PA3);	        //PA3输出低电平,段选端拉低,段选锁存   
	  delay(1);
	  s=s/10;//显示进位
   }	
}
void main(void)
{  
   Init(); 	 			  //调用IO初始化函数
   SREG|=0x80;			  //开总中断  
   while(1)
    {
     LEDshow(c+a);//调用数码管显示函数
    }
}
#pragma interrupt_handler Increase_INT0_Ir:2
void Increase_INT0_Ir(void)//按键1外部中断服务函数
{
   a++;//按键次数+1
   if(a>(b-1))//大于阈值
      {
	  a=b;//按键次数不在增加
	  PORTB|=BIT(PB7);//报警灯亮起
	  }
	  
}

#pragma interrupt_handler Increase_INT1_Ir:3
void Increase_INT1_Ir(void)//按键2外部中断服务函数
{
c=0;//数码管显示清零
a=0;//按键次数清零
PORTB&=~BIT(PB7);//报警灯熄灭
}
int flag=0;//用于按键循环的标志位
#pragma interrupt_handler Increase_INT2_Ir:19
void Increase_INT2_Ir(void)//按键3外部中断服务函数
{

flag++;
if(flag==1)//按下第一次
   {
   a=0;//按键次数清零
   c=200000;//阈值显示
   b=20;//阈值比较值
   PORTB&=~BIT(PB7);//报警灯熄灭
   }
   if(flag==2)
      {
	  a=0;//按键次数清零
      c=150000;//阈值显示
	  b=15;//阈值比较值
	  PORTB&=~BIT(PB7);//报警灯熄灭
	  }
      if(flag==3)
         {
		 a=0;//按键次数清零
         c=100000;//阈值显示
	     b=10;//阈值比较值
		 PORTB&=~BIT(PB7);//报警灯熄灭
		 }
		     if(flag==4)
                {
		         a=0;//按键次数清零
                 c=50000;//阈值显示
	             b=5;//阈值比较值
				 flag=0;//循环结束,开启下一轮循环
				 PORTB&=~BIT(PB7);//报警灯熄灭
		        }
		 
}

proteus8.9仿真在这里插入图片描述

完整代码工程-实验报告-PROTEUS工程仿真工程在在这个链接下载

实验由林学长完成,希望学弟学妹可以点个赞并且关注我一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁芜~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值