在这个代码上增加一个功能叫闹钟,进入功能数码管显示0000,K1按键按一开始正计时(计时1分钟);K2按键按一下进行位选用小数点来控;K3按键按一进行段选,每按一下加一;K4按键按一下清零(重新进入闹钟功能)。K4按键连选双按一下切换功能;功能顺序是计算器,秒表,定时器。下载程序到单片机里面,一开始功能是计算器功能。工作流程:以按一下K2进行位选用小数点控制,K3进行段选,按一下加1→ K1按一下确认 显示0000进入运算符选择→ 按一下K1,显示运算符(加号显示1111,减号显示2222,乘号显示3333,除号显示44444) → K2确认显示0000 → 输入第二个数 → K4确认 → 显示结果,K4在按一下重新计算。双击一下K4,进入秒表功能,数码管显示0001,按一下K1正计时以一秒的形式加一,按一下K2到计时以一秒的形式加一,按一下K3暂停,按一下K4清0。在双击一下K4按键,进入定时器功能,数码管显示000.0,按一下K2进行位选用小数点来控,K3进行段选,按一下加1(例如:我输入了2010,意思是20分钟10秒)→按一下K1开始以一秒的形式开始倒计时会显示(20.10),开始以一秒倒计时,在按一下K1清零,数码管显示00.00。在双击一下K4,进入闹钟模式,数码管显示000.0,按一下K2进行位选用小数点来控,K3进行段选,按一下加1(例如:我输入了0810,意思8点10分,代表开始的时间)→按一下K1开始计时,数码管显示0000,然后开始计时(0000→0001→0002…一直计时一分钟),一分钟过后,数码管开始显示08.11反复闪烁(相当于在个位加了一),按一下K4清零,重新输入。双击一下K4,又回到计算器功能,在代码中可以根改一下延迟函数。下面代码已经有计算器功能,秒表功能,定时器功能。代码符合以下程序。帮我重新写一份#include <REGX51.H>
// 共阳数码管段码表(0-9)
unsigned char cc[10] = {0Xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
// 状态定义
#define STATE_INPUT_NUM1 0 // 输入第一个数
#define STATE_SELECT_OP 1 // 选择运算符
#define STATE_INPUT_NUM2 2 // 输入第二个数
#define STATE_SHOW_RESULT 3 // 显示结果
// 模式定义
#define MODE_CALCULATOR 0
#define MODE_STOPWATCH 1
#define MODE_TIMER 2
// 全局变量
unsigned char current_mode = MODE_CALCULATOR;
unsigned char current_state = STATE_INPUT_NUM1;
unsigned char current_operator = 0;
unsigned char current_digit = 0;
unsigned char input_num[4] = {0,0,0,0};
unsigned long num1 = 0, num2 = 0;
// 秒表相关变量
unsigned int stopwatch_time = 0;
bit stopwatch_running = 0;
bit stopwatch_dir = 0; // 0:正计时 1:倒计时
// 定时器相关变量
unsigned char timer_digits[4] = {0,0,0,0};
unsigned char timer_edit_pos = 0;
unsigned int timer_remaining = 0;
bit timer_running = 0;
// 按键检测相关
volatile unsigned int ms_counter = 0;
bit k4_pending = 0;
unsigned int k4_pending_time = 0;
void Delay(unsigned int xms) {
while(xms–) {
unsigned char i = 2, j = 239;
do { while(–j); } while(–i);
}
}
void timer0_init() {
TMOD = 0x01; // 定时器0模式1
TH0 = 0x3C; // 50ms定时初值
TL0 = 0xB0;
ET0 = 1; // 允许定时器0中断
EA = 1; // 开总中断
TR0 = 1; // 启动定时器
}
void nn(unsigned char location, unsigned char num, bit show_dp) {
P1 = 0xFF;
switch(location) {
case 1: P1_0 = 0; break;
case 2: P1_1 = 0; break;
case 3: P1_2 = 0; break;
case 4: P1_3 = 0; break;
}
P2 = show_dp ? (cc[num] & 0x7F) : cc[num];
Delay(1);
P2 = 0xFF;
}
void resetInput() {
input_num[0] = input_num[1] = input_num[2] = input_num[3] = 0;
current_digit = 0;
}
void handleCalculatorKeys() {
// K1处理
if (!P3_4) {
Delay(20);
if (!P3_4) {
if(current_state == STATE_SELECT_OP) {
current_operator = (current_operator + 1) % 4;
}
while(!P3_4);
}
}
// K2处理
if (!P3_5) {
Delay(20);
if (!P3_5) {
if(current_state == STATE_SELECT_OP) {
current_state = STATE_INPUT_NUM2;
resetInput();
} else {
current_digit = (current_digit + 1) % 4;
}
while(!P3_5);
}
}
// K3处理
if (!P3_6) {
Delay(20);
if (!P3_6) {
if(current_state != STATE_SHOW_RESULT) {
input_num[3 - current_digit] = (input_num[3 - current_digit] + 1) % 10;
}
while(!P3_6);
}
}
}
void handleStopwatchKeys() {
// K1: 正计时
if (!P3_4) {
Delay(20);
if (!P3_4) {
stopwatch_dir = 0;
stopwatch_running = 1;
while(!P3_4);
}
}
// K2: 倒计时
if (!P3_5) {
Delay(20);
if (!P3_5) {
stopwatch_dir = 1;
stopwatch_running = 1;
while(!P3_5);
}
}
// K3: 暂停/继续
if (!P3_6) {
Delay(20);
if (!P3_6) {
stopwatch_running = !stopwatch_running;
while(!P3_6);
}
}
}
void handleTimerKeys() {
// K1: 开始/停止倒计时
if (!P3_4) {
Delay(20);
if (!P3_4) {
if (!timer_running) {
unsigned char minutes = timer_digits[0]*10 + timer_digits[1];
unsigned char seconds = timer_digits[2]*10 + timer_digits[3];
timer_remaining = minutes * 60 + seconds;
if (timer_remaining > 0) timer_running = 1;
} else {
timer_running = 0;
timer_remaining = 0;
for(int i=0; i<4; i++) timer_digits[i] = 0;
timer_edit_pos = 0;
}
while(!P3_4);
}
}
// K2: 切换编辑位
if (!P3_5) {
Delay(20);
if (!P3_5) {
timer_edit_pos = (timer_edit_pos + 1) % 4;
while(!P3_5);
}
}
// K3: 当前位加1
if (!P3_6) {
Delay(20);
if (!P3_6) {
timer_digits[timer_edit_pos] = (timer_digits[timer_edit_pos] + 1) % 10;
while(!P3_6);
}
}
}
void checkKeys() {
// K4处理(模式切换)
if (!P3_7) {
Delay(20);
if (!P3_7) {
if(k4_pending) {
k4_pending = 0;
current_mode = (current_mode + 1) % 3;
if(current_mode == MODE_STOPWATCH) {
stopwatch_time = 0;
stopwatch_running = 0;
} else if(current_mode == MODE_CALCULATOR) {
current_state = STATE_INPUT_NUM1;
resetInput();
} else {
for(int i=0;i<4;i++) timer_digits[i]=0;
timer_edit_pos = timer_running = timer_remaining =0;
}
} else {
k4_pending = 1;
k4_pending_time = ms_counter;
}
while(!P3_7);
}
}
switch(current_mode) {
case MODE_CALCULATOR: handleCalculatorKeys(); break;
case MODE_STOPWATCH: handleStopwatchKeys(); break;
case MODE_TIMER: handleTimerKeys(); break;
}
}
void displayCalculator() {
switch(current_state) {
case STATE_SELECT_OP:
nn(1, current_operator+1, 0);
nn(2, current_operator+1, 0);
nn(3, current_operator+1, 0);
nn(4, current_operator+1, 0);
break;
case STATE_SHOW_RESULT:
nn(1, input_num[0], 0);
nn(2, input_num[1], 0);
nn(3, input_num[2], 0);
nn(4, input_num[3], 0);
break;
default:
nn(1, input_num[0], (current_digit==3));
nn(2, input_num[1], (current_digit==2));
nn(3, input_num[2], (current_digit==1));
nn(4, input_num[3], (current_digit==0));
}
}
void displayStopwatch() {
unsigned char digits[4];
digits[0] = (stopwatch_time / 1000) % 10;
digits[1] = (stopwatch_time / 100) % 10;
digits[2] = (stopwatch_time / 10) % 10;
digits[3] = stopwatch_time % 10;
nn(1, digits[0], 0);
nn(2, digits[1], 0);
nn(3, digits[2], 0);
nn(4, digits[3], 0);
}
void displayTimer() {
if(timer_running) {
unsigned char min = timer_remaining / 60;
unsigned char sec = timer_remaining % 60;
unsigned char d1 = min/10, d2 = min%10;
unsigned char d3 = sec/10, d4 = sec%10;
nn(1, d1, 0); nn(2, d2, 1); nn(3, d3, 0); nn(4, d4, 0);
} else {
nn(1, timer_digits[0], (timer_edit_pos==0));
nn(2, timer_digits[1], (timer_edit_pos==1));
nn(3, timer_digits[2], (timer_edit_pos==2));
nn(4, timer_digits[3], (timer_edit_pos==3));
}
}
void calculateResult() {
unsigned long result = 0;
switch(current_operator) {
case 0: result = num1 + num2; break;
case 1: result = (num1 > num2) ? num1 - num2 : 0; break;
case 2: result = num1 * num2; break;
case 3: result = (num2 != 0) ? num1 / num2 : 0; break;
}
input_num[3] = result % 10;
input_num[2] = (result / 10) % 10;
input_num[1] = (result / 100) % 10;
input_num[0] = (result / 1000) % 10;
}
void timer0_isr() interrupt 1 {
static unsigned int count = 0;
TH0 = 0x3C; TL0 = 0xB0;
count++;
ms_counter += 50;
if(count >= 20) {
count = 0;
if(current_mode == MODE_STOPWATCH && stopwatch_running) {
if(stopwatch_dir) {
if(stopwatch_time > 0) stopwatch_time--;
else stopwatch_running = 0;
} else stopwatch_time = (stopwatch_time +1) % 10000;
}
if(current_mode == MODE_TIMER && timer_running && timer_remaining >0)
timer_remaining--;
}
if(k4_pending && (ms_counter - k4_pending_time >= 500)) {
switch(current_mode) {
case MODE_CALCULATOR:
switch(current_state) {
case STATE_INPUT_NUM1:
num1 = input_num[0]*1000 + input_num[1]*100 + input_num[2]*10 + input_num[3];
resetInput();
current_state = STATE_SELECT_OP;
break;
case STATE_INPUT_NUM2:
num2 = input_num[0]*1000 + input_num[1]*100 + input_num[2]*10 + input_num[3];
current_state = STATE_SHOW_RESULT;
break;
case STATE_SHOW_RESULT:
resetInput();
current_state = STATE_INPUT_NUM1;
break;
}
break;
case MODE_STOPWATCH:
stopwatch_time = 0;
stopwatch_running = 0;
break;
case MODE_TIMER:
for(int i=0;i<4;i++) timer_digits[i]=0;
timer_edit_pos = timer_remaining = timer_running =0;
break;
}
k4_pending = 0;
}
}
void main() {
timer0_init();
while(1) {
checkKeys();
switch(current_mode) {
case MODE_CALCULATOR:
if(current_state == STATE_SHOW_RESULT) calculateResult();
displayCalculator(); break;
case MODE_STOPWATCH: displayStopwatch(); break;
case MODE_TIMER: displayTimer(); break;
}
}
}