单片机
基于51单片机开发计时器,使其实现以下功能:
(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增,最小间隔为1。
(2)数码管上显示当前计时时间(用小时-分钟-秒的格式显示),启动计时后数码管上实时显示计时剩余时长。(中间用-隔开)
(3)计时时间到了后启动蜂鸣器(按下计时器复位按键后蜂鸣器停止)
要求:能在设备中运行即可,软件用到keil和普中
附图:
关于#单片机#的问题:单片机基于51单片机开发计时器,使其实现以下功能:(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
5条回答 默认 最新
- qllaoda 2023-06-10 20:02关注
#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(); } }
解决 无用评论 打赏 举报
悬赏问题
- ¥15 win11系统打开软件很慢
- ¥30 XIAO esp32c3 读取FDC2214的数据
- ¥15 在工控机(Ubuntu系统)上外接USB蓝牙硬件进行蓝牙通信
- ¥15 关于PROCEDURE和FUNCTION的问题
- ¥100 webapi的部署(标签-服务器)
- ¥20 怎么加快手机软件内部计时的时间(关键词-日期时间)
- ¥15 C语言除0问题的检测方法
- ¥15 为什么四分管的内径有的是16mm有的15mm,四分不应该是12.7mm吗
- ¥15 macos13下 ios交叉编译的问题
- ¥15 bgz压缩文件怎么打开