项目三 51项目(使用外部按键倒计时)
【实验内容】
1.熟悉软件流程(Proteus 8 Professional,Keil uVision5),熟悉烧录流程,熟悉51芯片的引脚。
2.编写程序代码
3.用软件搭建实验电路,实现倒计时的功能。
【实验原理】
使用外部按键进行倒计时的实验原理如下:
- 外部按键输入:在单片机开发板上连接一个或多个外部按键,通过端口将外部按键与单片机连接。当按下外部按键时,对应的端口信号会发生变化。
- 中断服务函数:通过单片机的中断服务函数,可以检测外部按键的状态变化。当外部按键被按下时,中断服务函数会被触发执行相应的操作。
- 倒计时功能:当外部按键被按下时,触发中断服务函数来开始倒计时。倒计时的实现可以通过单片机的定时器功能来完成,例如可以使用定时器中断来进行倒计时操作。
- 数码管显示:倒计时过程中,将剩余时间通过数码管显示出来可以通过修改display()函数来实现倒计时数字的显示。
总的来说,实验原理是通过中断服务函数检测外部按键状态变化,启动倒计时功能,然后通过数码管显示剩余时间。这样就可以实现使用外部按键进行倒计时的功能。
【实验记录与结果分析】
电路原理图:
程序代码:
程序主要分为以下几个部分:
1.头文件和全局变量的定义。使用reg51.h头文件,定义了8个无符号字符型变量和一个数组,用于存储数码管需要显示的数字。 |
2.display()函数。该函数用于循环调用,实现数码管的显示功能。在函数内部,通过P0端口给数码管发送对应的显示编码,再通过P1端口选择哪个数码管进行显示,并通过delay()函数控制LED的闪烁速度和频率。 |
3.delay()函数。该函数是一个简单的延时函数,通过两重循环实现一定的延时效果。 |
4.tree()函数。该函数是定时器0中断服务函数,主要用于计时器的功能实现。在每次中断时将temp自增,并根据temp计算出需要显示的数码管显示的内容。 |
在main()函数中,启用定时器0并开启总中断允许,然后进入一个死循环,不断调用display()函数,实现程序的运行。 |
#include <reg51.h> // 包含 8051 单片机的头文件 |
#define u8 unsigned char // 定义无符号 8 位字符类型 |
#define u16 unsigned int // 定义无符号 16 位整型类型 |
u8 a,b,c,d,e,f,g,h,temp; // 定义全局变量 a 到 h 和 temp,用于数码管显示和临时存储 |
u8 lzs[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; // 定义共阳极数码管显示 0-9 的编码 |
void display(); // 声明数码管显示函数 |
void delay(u8 x); // 声明延时函数 |
void main() // 主函数 |
{ |
EA=1; // 开启总中断允许 |
ET0=1; // 开启定时器 0 中断允许 |
TMOD=0x06; // 设置定时器 0 工作在方式 1(8 位自动重装)并启用定时器 1 工作在方式 1 |
TH0=TL0=255; // 定时器 0 初始值设为 255 |
TR0=1; // 启动定时器 0 |
while(1) // 无限循环 |
{ |
display(); // 调用数码管显示函数 |
} |
} |
void delay(u8 x) // 定义延时函数,参数为延时时间 |
{ |
u8 i , j; // 定义局部变量 i 和 j |
for(i=0;i<x;i++) // 循环 x 次 |
{ |
for(j=0;j<10;j++) // 再次循环 10 次,延时 |
{ |
|
} |
} |
} |
void tree() interrupt 1 // 定义定时器 0 中断服务函数 |
{ |
temp++; // temp 自增 |
a=temp%10; // a 为 temp 对 10 取余 |
b=temp/10; // b 为 temp 除以 10 的商 |
} |
void display() // 定义数码管显示函数 |
{ |
P0=lzs[a]; P1=0x80; delay(50); P1=0x00; // 显示 a 位数码管,并控制选择端口 |
P0=lzs[b]; P1=0x40; delay(50); P1=0x00; // 显示 b 位数码管,并控制选择端口 |
P0=lzs[c]; P1=0x20; delay(50); P1=0x00; // 显示 c 位数码管,并控制选择端口 |
P0=lzs[d]; P1=0x10; delay(50); P1=0x00; // 显示 d 位数码管,并控制选择端口 |
P0=lzs[e]; P1=0x08; delay(50); P1=0x00; // 显示 e 位数码管,并控制选择端口 |
P0=lzs[f]; P1=0x04; delay(50); P1=0x00; // 显示 f 位数码管,并控制选择端口 |
P0=lzs[g]; P1=0x02; delay(50); P1=0x00; // 显示 g 位数码管,并控制选择端口 |
P0=lzs[h]; P1=0x01; delay(50); P1=0x00; // 显示 h 位数码管,并控制选择端口 |
} |
【实验小结】
在完成外部按键进行倒计时项目的过程中,我获得了很多宝贵的经验和体会。
首先,我深入理解了单片机的中断服务功能。通过连接外部按键到单片机的中断引脚,我学会了如何利用外部事件来触发中断,并在中断服务函数中实现倒计时逻辑。这让我对单片机的中断处理有了更深入的了解。
其次,我掌握了单片机定时器的使用方法。在倒计时功能中,我使用了单片机的定时器模块来实现精确的时间计数,从而实现了准确的倒计时功能。这让我对单片机定时器的原理和使用有了更清晰的认识。
另外,通过这个项目,我也加深了对数字电路的理解。在将剩余时间显示在数码管上时,我需要对数码管的工作原理和接口连接有所了解,这让我对数字电路的应用有了更多的实践经验。
总的来说,通过这个外部按键进行倒计时的项目,我不仅学会了具体的硬件连接和编程实现,还提升了自己在单片机、中断处理、定时器和数字电路方面的能力。
中断原理总结:
中断是计算机系统中一种重要的机制,用于在处理器执行程序时,对特定事件的发生做出及时响应。中断可以分为外部中断和内部中断两种类型。
1.外部中断:外部中断是由外部设备(如传感器、按键等)发送的信号触发的中断。当外部设备发生特定事件时(如按下按键),会向处理器发送一个中断请求信号。处理器在接收到中断请求信号后,会立即中断当前执行的程序,保存当前状态并跳转到相应的中断处理程序来处理这个事件。处理完中断服务程序后,再返回到之前被中断的程序继续执行。
2.内部中断:内部中断是由处理器内部某些特定事件(如定时器溢出、指令执行错误等)引起的中断。处理器在内部发生这些事件时,会自动发起中断请求,跳转到相应的中断服务程序进行处理,处理完后再返回到原程序继续执行。
在处理中断时,通常会有中断优先级的概念,处理器会根据中断请求的优先级来确定响应的顺序。同时,中断处理过程中需要保存和恢复相关的寄存器和状态,以保证中断处理完后能够正确返回到原程序。
总的来说,中断机制使得处理器能够及时响应外部或内部事件,提高了系统的实时性和可靠性,广泛应用于各种计算机系统和嵌入式系统中。
要将Keil uVision5中的代码烧录到Proteus 8 Professional中,可以按照以下步骤进行操作:
1)在Keil uVision5 中编写、调试并生成可执行文件(通常是.hex格式)。 |
2)打开Proteus 8 Professional,创建一个新的电路设计或打开现有的设计。 |
3)在 Proteus 8 Professional 的工具栏中选择 "PICK DEVICE" 工具来选择目标芯片。在弹出的窗口中输入芯片型号,并选择正确的芯片。 |
4)在 Proteus 8 Professional 的库管理器中,找到 "Virtual Instruments" 分类下的 "Hex File" 组件,并将其拖放到电路设计中。 |
5)右键单击"Hex File"组件,选择"Edit Properties"。 |
6)在"Edit Hex File Properties" 窗口中,点击"..."按钮来浏览并选择生成的可执行文件(.hex文件)。 |
7)确认所选文件的地址范围与目标芯片的存储器空间匹配。如果需要,可以修改"Start Address" 字段来设置代码的起始地址。 |
|
|
10)单击Proteus 8 Professional的仿真按钮(通常是绿色播放按钮)来开始仿真。 |