1、功能描述
数码管显示的计数器,按键按下暂定,再次按下继续。(按键功能使用中断实现)
2、实验原理
· 按键与中断:使用单片机的外部中断功能来检测按键动作,实现非阻塞的按键检测。
· 中断服务程序:编写中断服务程序来处理按键动作,切换暂停和继续的状态。
· 动态显示:通过分时控制两个数码管(或一个数码管的两个位置)来动态显示计数器的值。
3、编程思路
· 主循环:在主循环中,根据暂停标志位决定是否继续计数和更新数码管显示。
· 显示逻辑:编写数码管显示函数,用于显示计数器的当前值。由于只有一个数码管,需要实现动态扫描来交替显示十位和个位的数字。
· 中断服务程序: 在按键按下时,通过中断服务程序切换暂停标志位。使用边沿检测机制来避免抖动和多次触发的问题。
· 去抖动处理:在中断服务程序中加入防抖动逻辑,确保按键状态稳定后再进行处理。
· 暂停与继续:
当暂停标志位为非激活状态时,单片机继续计数并更新数码管显示。
当暂停标志位为激活状态时,单片机停止计数,但可以通过再次按下按键来继续计数。
4、代码
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit k3 = P3^2; // 连接到P3.2的按键
bit pause_flag = 0; // 定义一个标志位,用于控制计数器的暂停和继续
uchar count = 0; // 计数器变量
// 延时函数
void delay(uint xms) {
uint i, j;
for (i = xms; i > 0; i--)
for (j = 110; j > 0; j--);
}
// 数码管显示函数
void display(uchar num) {
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
P0 = table[num]; // 显示数码管
}
// 外部中断0服务程序
void external0_isr() interrupt 0 {
if (k3 == 0) { // 检测按键是否按下
pause_flag = !pause_flag; // 切换暂停标志位
while (k3 == 0); // 等待按键释放
}
}
void main() {
// 初始化设置
IT0 = 1; // 设置INT0为边沿触发
EX0 = 1; // 使能INT0中断
EA = 1; // 使能全局中断
P0 = 0x3f; // 初始数码管显示0
while (1) {
if (!pause_flag) { // 检查是否处于暂停状态
display(count / 10); // 显示计数器的十位数
display(count % 10); // 显示计数器的个位数
count++; // 计数器增加
delay(1000); // 计数间隔延时
}
}
}