项目四 51单片机项目(数码管倒计时—定时器中断)
【实验内容】
1.熟悉软件流程(Proteus8Professional,KeiluVision5),熟悉烧录流程,熟悉定时器中断有关知识。
2.编写程序代码。
3.用软件搭建实验电路,实现数码管倒计时的功能。
【实验原理】
该项目的电路实验原理如下:
- 数码管接口
数码管共阴极的连接方式和端口定义如下:
- 数码管第一个引脚(最左边)连接到P0.0;
- 数码管第二个引脚连接到P0.1;
- 数码管第三个引脚连接到P0.2;
- 数码管第四个引脚连接到P0.3;
- 数码管第五个引脚连接到P0.4;
- 数码管第六个引脚连接到P0.5;
- 数码管第七个引脚连接到P0.6;
- 数码管第八个引脚(最右边)连接到P0.7。
- 控制端口
在本项目中,使用P1端口来控制数码管的选通。具体的控制方式是:
- P1.0用于控制个位数码管的选通,即P1=0x01;
- P1.1用于控制十位数码管的选通,即P1=0x02。
- 定时器
本项目中使用了定时器0来实现定时器中断功能。定时器0的接口及其工作原理如下:
- T0为定时器0的计数器;
- TMOD为定时器模式寄存器,用于设置定时器的工作模式;
- TH0和TL0为定时器0的高低字节计数器;
- ET0为定时器0的中断允许寄存器,用于使能定时器0中断;
- TR0为定时器0启动/停止控制位。
在本项目中,定时器0被设置为模式1,即16位定时器模式。同时,预装载值被设置为50000,以便实现大约10ms的定时器中断时间。当定时器计数器计数达到预装载值时,将会触发定时器中断,进而执行timer0()函数的内容。
- 倒计时实现
在main()函数中使用了两层循环来实现倒计时功能。在每次内层循环结束后调用show()函数显示当前倒计时的值。
- 延时函数
delay()函数用于实现延时,延时的时间由函数参数k控制。在函数中使用两个循环嵌套来实现延时,具体流程如下:
- 外层循环执行60次,控制延时的精度;
- 内层循环执行k次,根据参数k的值来控制延时的时间。
【实验记录与结果分析】
电路原理图:
程序代码
代码:
#include <reg51.h> // 包含头文件 reg51.h,用于引入 8051 微控制器的寄存器定义 |
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 数码管显示数字的编码表 |
void show(unsigned char n); // 声明显示函数 show() |
void delay(unsigned int k); // 声明延时函数 delay() |
void main() |
{ |
unsigned char i; // 定义变量 i 用于循环计数 |
int j; // 定义变量 j 用于循环计数,注意此处应为 unsigned int 类型 |
while(1) // 无限循环 |
{ |
for(i=60; j=60, i>10; i--) // 循环从 60 到 11 |
{ |
while(j--) // 内层循环,j 递减直到为 0 |
{ |
show(i); // 调用显示函数显示当前数字 |
} |
} |
} |
} |
void show (unsigned char n) |
{ |
P0=table[n%10]; // 显示个位数码管 |
P1=0x01; // 选通个位数码管 |
delay(10); // 延时一段时间 |
P1=0xFF; // 关闭所有数码管 |
P0=table[n/10]; // 显示十位数码管 |
P1=0x02; // 选通十位数码管 |
delay(10); // 延时一段时间 |
P1=0xFF; // 关闭所有数码管 |
} |
void delay (unsigned int k) |
{ |
unsigned char i, j; |
for(i=0; i<60; i++) // 外层循环执行 60 次 |
{ |
for(j=0; j<k; j++); // 内层循环根据参数 k 执行相应次数的延时 |
} |
} |
【实验小结】
电路原理分析小结:
这是一个基于51单片机的数码管倒计时项目,使用了共阴极数码管和定时器中断功能。数码管的引脚连接到P0端口,通过设置P0的输出来显示数字。P1端口用于控制数码管的选通,具体来说,P1.0控制个位数码管的选通,P1.1控制十位数码管的选通。定时器0被配置为16定时器模式,并设置了适当的预装载值来实现约10ms的定时器中断。在主循环中,通过两层循环来实现倒计时功能,每次内层循环结束后调用show()函数显示当前倒计时的值。
代码小结:
这段代码实现了倒计时功能,使用了简单的循环和延时函数来控制数码管的显示。show()函数根据参数n的个位和十位分别设置P0的值和P1的值来显示相应的数字。delay()函数用于实现延时,通过嵌套循环来实现精确的延时。在main()函数中,通过两层循环实现倒计时功能,内层循环结束后调用show()函数显示倒计时的值。整体代码逻辑清晰,易于理解和修改。
定时器中断总结
定时器中断是指在单片机中,通过定时器模块设置一定时间后触发中断,从而实现定时的功能。定时器中断可以用于许多应用场景,如数码管倒计时、红外遥控等。
在单片机中,定时器通常由一个或多个定时器模块组成,每个定时器模块都有一个计数器和一些控制寄存器。通过对这些控制寄存器的配置,可以设置定时器的工作模式、预装载值、时钟源等参数。当定时器的计数器达到预设值时,会触发定时器中断,单片机将跳转到相应的中断服务程序来处理中断事件。
定时器中断比起使用延时函数来实现定时更为可靠和精确,因为中断服务程序可以在任何时刻响应中断请求,而不受主程序的影响。此外,通过设置合适的定时器参数,可以实现非常精确的定时,并且不会浪费CPU资源。
在使用定时器中断时需要注意以下几点:
- 定时器的时钟源和预装载值需要根据实际需求来设置,以确保定时精度和计时范围。
- 定时器中断服务程序应该尽量简短,避免长时间占用 CPU 资源。
- 在定时器中断服务程序中,要注意保存和恢复被中断的寄存器,以避免对主程序造成影响。
- 定时器中断程序需要在主程序中开启相应的中断,否则定时器中断将无法启动。
总之,定时器中断是单片机中非常重要的一个功能模块,可以实现许多实用的应用。在使用定时器中断时,需要仔细考虑定时器参数的设置和中断服务程序的编写,以便实现精确、可靠的定时功能。