keil5+proteus实现中断系统(流水灯为例子)

  • 实验目的

熟悉中断系统运用

掌握状态转换

  • 实验设备

Keil5与Peoteus8 电脑

  • 实验内容和结果

实验内容:

1. 利用开关控制8个LED的闪烁与点亮:当开关拨到1时,LED闪烁;当开关拨到0 时,LED点亮。

2. 利用开关控制8个LED的闪烁与流水:当开关拨到1时,LED流水;当开关拨到0 时,LED闪烁。

(1)实验代码与连线截图:

代码:

#include <REGX52.H>

#define MAIN_Fosc 24000000UL

sbit BUTTON=P3^2;

#define LED P2

unsigned char ledArr[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay_ms(unsigned int ms)

{

       unsigned int i;

       do{

              i = MAIN_Fosc / 6030;

              while(--i);

       }while(--ms);

}

void main(){

       IT0=1;                   //外部0中断边沿触发

       EA=1;                   //开总中断

       EX0=1;          //开外部0中断

while(1){

 LED=0xff;

 delay_ms(10);

 LED=0x00;

 delay_ms(10);     

 }

}

void ex0_int() interrupt 0{

  if(BUTTON==0){

              int i;

       for(i=0;i<8;i++){

       LED=~ledArr[i];

 delay_ms(5);

       }

}

}

实现效果截图:

启动八个灯自动闪烁。

  • 按钮按下开始流水

(2)实验2实验代码与连线截图:

连线:

代码:

#include <REGX52.H>

#define MAIN_Fosc 24000000UL

sbit BUTTON=P3^2;

#define LED P2

unsigned int count=0;

unsigned char ledArr[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay_ms(unsigned int ms)

{

       unsigned int i;

       do{

              i = MAIN_Fosc / 6030;

              while(--i);

       }while(--ms);

}

void button(){

if(BUTTON==0){

count++;

}

}

void main(){

IT0=1;                   //外部0中断边沿触发

EA=1;                   //开总中断

EX0=1;          //开外部0中断

button();

       while(1){

  if(count%2==0){

LED=0xff;

delay_ms(10);

LED=0x00;

delay_ms(10);      

}     

else if(count%2!=0){

       int i;

  for(i=0;i<8;i++){

       LED=~ledArr[i];

  delay_ms(5);

              }

}

              }

       }

void ex0_int() interrupt 0{

count++;

}

结果:

按下流水灯:

再次按下闪烁状态:

图表, 条形图  描述已自动生成

再次按下全灯闪烁:

四、实验问题思考

1. 单片机驱动继电器和蜂鸣器的电路设计

继电器电路设计

继电器通常需要较大的电流来驱动,因此单片机的I/O口通常不足以直接驱动继电器。为了解决这个问题,可以使用一个驱动芯片,例如ULN2003,它是一个大电流驱动阵列,常用于单片机控制电路中以驱动继电器等负载。ULN2003内部包含了七路达林顿管,可以提供足够的电流来驱动继电器。

电路设计时,单片机的I/O口连接到ULN2003的输入端,然后ULN2003的输出端连接到继电器的线圈。当单片机输出高电平时,ULN2003会导通,从而驱动继电器吸合。

蜂鸣器电路设计

蜂鸣器的驱动方式取决于是使用有源蜂鸣器还是无源蜂鸣器。有源蜂鸣器内部带有振荡电路,只需接入直流电源即可发声。无源蜂鸣器则需要外部提供方波信号才能发声。

对于有源蜂鸣器,可以直接通过单片机的I/O口输出高低电平来控制蜂鸣器的发声。而对于无源蜂鸣器,需要通过单片机输出特定频率的方波信号来驱动蜂鸣器发声。

2. 单片机的准双向口和双向口的区别

单片机的I/O口根据其电气特性可以分为准双向口和双向口。

**准双向口**:这种类型的口在输出模式下只能输出高电平,不能输出低电平。在输入模式下,它们可以读取高低电平。这种设计通常用于那些不需要输出低电平的应用场景。

**双向口**:双向口可以在输出模式下输出高低电平,也可以在输入模式下读取高低电平。这种设计提供了更大的灵活性,因为它允许I/O口在不同的操作模式下工作。

关于P0~P3口是否是准双向口还是双向口,这取决于具体的单片机型号。不同的单片机型号可能会有不同的I/O口配置。例如,某些8051系列单片机的P0口是双向口,而其他一些型号的P0口可能是准双向口。因此,需要查阅特定单片机型号的数据手册来确定其I/O口的类型。

····心得体会:

Keil C51编程软件编写程序,并通过仿真软件模拟了中断请求和中断服务程序的执行过程。我深刻体会到了中断服务程序的重要性。在中断服务程序中,我们需要快速、准确地处理中断请求,然后尽快返回,以便单片机能够继续执行其他任务。如果中断服务程序编写不当,可能会导致单片机无法及时响应其他中断请求,从而影响整个系统的性能。

中断在电流下降沿触发所以不能判断按钮按下抬起。直接按钮按下即可

  • 14
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是在 Keil 软件中实现读取 4*3 矩阵键盘键值和实现数码管显示的程序代码: ``` #include<reg52.h> #define KEY P0 //定义4*3矩阵键盘的端口为P0 #define DIG P2 //定义数码管的端口为P2 unsigned char code ledChar[] = { //定义数码管显示的字符集 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F }; void delay(unsigned int t) //延迟函数 { unsigned int i,j; for(i=0;i<t;i++) for(j=0;j<125;j++); } unsigned char getKey() //读取键盘键值函数 { unsigned char key = 0xFF; unsigned char i,j; for(i=0;i<4;i++) //扫描行 { KEY = ~(1<<i); for(j=0;j<3;j++) //读取列 { if(!(KEY & (1<<(j+4)))) //检测键是否按下 { delay(5); //延时去抖动 if(!(KEY & (1<<(j+4)))) //再次检测键是否按下 { key = i*3+j; //计算键值 break; } } } if(key != 0xFF) //如果检测到键按下,则退出循环 break; } while(KEY != 0xFF); //等待键释放 return key; } void main() { unsigned char key, i; while(1) { key = getKey(); //读取键值 if(key != 0xFF) //如果有键按下 { DIG = ledChar[key]; //在数码管上显示键值 delay(500); //延时一段时间 DIG = 0x00; //关闭数码管 } } } ``` 代码中定义了 `getKey()` 函数来读取键盘的键值,使用了双重循环来扫描矩阵键盘的行和列,并在检测到按键按下时计算出键值。在 `main()` 函数中使用了一个无限循环来不断检测键盘是否有键按下,并在数码管上显示键值。代码中使用了一个 `ledChar` 数组来存储数码管显示的字符集,使用了 `DIG` 变量来控制数码管的显示,使用了 `delay()` 函数来实现延时操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值