单片机
基于51单片机开发计时器,使其实现以下功能:
(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增,最小间隔为1。
(2)数码管上显示当前计时时间(用小时-分钟-秒的格式显示),启动计时后数码管上实时显示计时剩余时长。(中间用-隔开)
(3)计时时间到了后启动蜂鸣器(按下计时器复位按键后蜂鸣器停止)
要求:能在设备中运行即可,软件用到keil和普中
附图:

单片机
基于51单片机开发计时器,使其实现以下功能:
(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增,最小间隔为1。
(2)数码管上显示当前计时时间(用小时-分钟-秒的格式显示),启动计时后数码管上实时显示计时剩余时长。(中间用-隔开)
(3)计时时间到了后启动蜂鸣器(按下计时器复位按键后蜂鸣器停止)
要求:能在设备中运行即可,软件用到keil和普中
附图:

#include <reg51.h>
// 数码管位选控制端口
sbit digit1 = P2^0;
sbit digit2 = P2^1;
sbit digit3 = P2^2;
// 数码管段选控制端口
sbit segmentA = P1^0;
sbit segmentB = P1^1;
sbit segmentC = P1^2;
sbit segmentD = P1^3;
sbit segmentE = P1^4;
sbit segmentF = P1^5;
sbit segmentG = P1^6;
sbit segmentDP = P1^7;
// 按键控制端口
sbit startStopButton = P3^0; // 启停按键
sbit resetButton = P3^1; // 复位按键
sbit toggleButton = P3^2; // 切换按键
sbit incrementButton = P3^3; // 递增按键
// 蜂鸣器控制端口
sbit buzzer = P3^4;
unsigned char displayData[3]; // 数码管显示数据(小时、分钟、秒)
unsigned char currentTime[3]; // 当前计时时间(小时、分钟、秒)
unsigned char targetTime[3]; // 目标计时时间(小时、分钟、秒)
unsigned char displayIndex = 0; // 数码管显示索引
bit timerRunning = 0; // 计时器运行状态
// 数码管段选码表
unsigned char code digitSegments[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
// 延时函数
void delay(unsigned int ms) {
unsigned int i, j;
for(i = 0; i < ms; i++) {
for(j = 0; j < 120; j++);
}
}
// 数码管位选函数
void selectDigit(unsigned char digit) {
digit1 = 1;
digit2 = 1;
digit3 = 1;
switch(digit) {
case 0: digit1 = 0; break;
case 1: digit2 = 0; break;
case 2: digit3 = 0; break;
}
}
// 数码管段选函数
void displayDigit(unsigned char digit, unsigned char data) {
segmentA = (data & 0x01) ? 1 : 0;
segmentB = (data & 0x02) ? 1 : 0;
segmentC = (data & 0x04) ? 1 : 0;
segmentD = (data & 0x08) ? 1 : 0;
segmentE = (data & 0x10) ? 1 : 0;
segmentF = (data & 0x20) ? 1 : 0;
segmentG = (data & 0x40) ? 1 : 0;
segmentDP = (data & 0x80) ? 1 : 0;
}
// 数码管显示函数
void updateDisplay() {
selectDigit(displayIndex);
displayDigit(displayIndex, displayData[displayIndex]);
}
// 数码管刷新中断服务函数
void timer0Interrupt() interrupt 1 {
TH0 = 0x3C;
TL0 = 0xB0;
if (timerRunning) {
if (currentTime[0] == 0 && currentTime[1] == 0 && currentTime[2] == 0) {
buzzer = 1; // 计时时间到了,启动蜂鸣器
timerRunning = 0; // 停止计时器
} else {
if (currentTime[2] > 0) {
currentTime[2]--;
} else {
if (currentTime[1] > 0) {
currentTime[1]--;
currentTime[2] = 59;
} else {
if (currentTime[0] > 0) {
currentTime[0]--;
currentTime[1] = 59;
currentTime[2] = 59;
}
}
}
}
if (displayIndex == 0) {
displayData[0] = currentTime[0] / 10;
displayData[1] = currentTime[0] % 10;
} else if (displayIndex == 1) {
displayData[0] = currentTime[1] / 10;
displayData[1] = currentTime[1] % 10;
} else if (displayIndex == 2) {
displayData[0] = currentTime[2] / 10;
displayData[1] = currentTime[2] % 10;
}
updateDisplay();
}
}
// 按键中断服务函数
void buttonInterrupt() interrupt 0 {
if (!startStopButton) { // 启停按键
if (!timerRunning) {
timerRunning = 1;
} else {
timerRunning = 0;
}
}
if (!resetButton) { // 复位按键
currentTime[0] = 0;
currentTime[1] = 0;
currentTime[2] = 0;
buzzer = 0; // 停止蜂鸣器
}
if (!toggleButton) { // 切换按键
displayIndex++;
if (displayIndex > 2) {
displayIndex = 0;
}
}
if (!incrementButton) { // 递增按键
if (timerRunning) {
buzzer = 0; // 停止蜂鸣器
if (displayIndex == 0) {
if (currentTime[0] < 23) {
currentTime[0]++;
} else {
currentTime[0] = 0;
}
} else if (displayIndex == 1) {
if (currentTime[1] < 59) {
currentTime[1]++;
} else {
currentTime[1] = 0;
}
} else if (displayIndex == 2) {
if (currentTime[2] < 59) {
currentTime[2]++;
} else {
currentTime[2] = 0;
}
}
if (currentTime[0] == targetTime[0] && currentTime[1] == targetTime[1] && currentTime[2] == targetTime[2]) {
buzzer = 1; // 计时时间到了,启动蜂鸣器
timerRunning = 0; // 停止计时器
}
}
}
delay(50); // 延时去抖动
}
// 主函数
void main() {
TMOD = 0x01; // 设置定时器0为模式1
TH0 = 0x3C; // 设置定时器0初值,用于定时1ms
TL0 = 0xB0;
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
TR0 = 1; // 启动定时器0
EX0 = 1; // 允许外部中断0(按键中断)
IT0 = 1; // 设置外部中断0为下降沿触发
displayIndex = 0;
displayData[0] = 0;
displayData[1] = 0;
displayData[2] = 0;
currentTime[0] = 0;
currentTime[1] = 0;
currentTime[2] = 0;
targetTime[0] = 0;
targetTime[1] = 0;
targetTime[2] = 10; // 设置目标计时时间为10秒
while (1) {
if (timerRunning) {
targetTime[0] = currentTime[0];
targetTime[1] = currentTime[1];
targetTime[2] = currentTime[2];
}
updateDisplay();
}
}