这段代码什么意思:void main(void) { unsigned char KEY,NUM; unsigned char i,j,k; P1=0xFF; TMOD=0x11; TL0=0xB0; TH0=0x3C; EA=1; ET0=1; TR0=0; Delay400Ms(); lcd_init(); write_1602com(yi); for(i=0;i<16;i++) { write_1602dat(name[i]); } write_1602com(er); for(i=0;i<16;i++) { write_1602dat(start_line[i]); } write_1602com(er+9); write_1602com(0x0f); Delay5Ms(); N=0; while(1) { if(key_disable==1) Alam_KeyUnable(); else ALAM=1; KEY=keynum(); if(KEY!=0) { if(key_disable==1) { second=0; } else { NUM=coding(KEY); { switch(NUM) { case ('A'): ; break; case ('B'): ; break; case ('C'): write_1602com(yi); for(i=0;i<16;i++) { write_1602dat(name[i]); } if(N>=1) N--; OneAlam(); for(j=N;j<16;j++) { write_1602com(er+6+j); write_1602dat(' '); } for(j=0;j<N;j++) { write_1602com(er+6+j); write_1602dat('*'); } break; case ('D'): ResetPassword(); break; case ('*'): Cancel(); break; case ('#'): Ensure(); break; default: { if(N<6) { write_1602com(er); for(i=0;i<16;i++) { write_1602dat(Input[i]); } OneAlam(); for(j=0;j<=N;j++) { write_1602com(er+6+j); write_1602dat('*'); } InputData[N]=NUM; for(k=0;k<6;k++) { InputData[k]+=InputData[N]+1; } N++; } else { N=6; break; } } } } } } } }
时间: 2024-04-27 08:24:57 浏览: 17
这段代码是一个基于单片机的密码锁程序,通过LCD1602显示屏显示提示信息和密码输入状态,通过按键输入密码,进行密码的设置、重置和验证,并且通过蜂鸣器进行密码错误提醒。其中,主函数中包含了初始化设置、LCD屏幕显示、按键扫描和密码验证等多个子函数。整个程序的核心是通过对按键输入进行判断,实现密码的输入和验证,并且根据不同的输入进行相应的操作。
相关问题
优化#include <reg52.h> // 引入51单片机头文件#define LED1 P1 // LED1控制端口#define LED2 P2 // LED2控制端口#define KEY P3 // 按键控制端口unsigned char second = 0; // 秒数计数器unsigned char isRunning = 0; // 是否正在计时unsigned char isPaused = 0; // 是否暂停计时void initTimer(); // 初始化定时器函数声明void display(unsigned char num); // 数码管显示函数声明void start(); // 启动计时器函数声明void pause(); // 暂停计时器函数声明void reset(); // 重置计时器函数声明void main() { initTimer(); // 初始化定时器 while (1) { // 主循环 if (KEY == 0) { // 检测按键是否按下 delay(10); // 延时去抖动 if (KEY == 0) { // 再次检测按键是否按下 if (!isRunning) { // 如果没有在计时 start(); // 启动计时器 } else if (isPaused) { // 如果正在暂停 start(); // 继续计时器 } else { // 如果正在计时 pause(); // 暂停计时器 } } while (KEY == 0); // 等待按键释放 } display(second); // 显示秒数 }}void initTimer() { TMOD = 0x01; // 定时器0工作在模式1 TH0 = 0xFC; // 定时器计数初值,1ms TL0 = 0x18; TR0 = 1; // 启动定时器 ET0 = 1; // 打开定时器中断允许 EA = 1; // 打开总中断允许}void display(unsigned char num) { LED1 = 0xFF; // 共阳极LED1 LED2 = 0xFF; // 共阴极LED2 LED1 = num % 10; // 显示个位数字 LED2 = ~(1 << (num / 10)); // 显示十位数字,通过移位实现 delay(5); // 稍微延时}void start() { isRunning = 1; // 设置正在计时 isPaused = 0; // 设置未暂停}void pause() { isPaused = 1; // 设置暂停}void reset() { isRunning = 0; // 设置未计时 isPaused = 0; // 设置未暂停 second = 0; // 秒数清零}void timer0() interrupt 1 { // 定时器0中断函数 TH0 = 0xFC; // 重新赋初值,1ms if (!isRunning) { // 如果未在计时 return; // 直接返回 } if (!isPaused) { // 如果未暂停 second++; // 秒数加1 if (second == 100) { // 如果秒数达到100,则清零并重置状态 reset(); } }}void delay(unsigned int t) { // 延时函数 unsigned int i, j; for (i = 0; i < t; i++) { for (j = 0; j < 110; j++); }}
可以使用预编译指令优化头文件的引用,避免引入不必要的头文件。比如,可以将头文件 `reg52.h` 中未使用的内容注释掉,或者使用更加精简的头文件 `8051.h`。另外,可以使用宏定义来代替具体的 I/O 端口号,增强代码的可维护性。例如:
```
#include <8051.h> // 引入8051单片机头文件
#define LED1 P1 // LED1控制端口
#define LED2 P2 // LED2控制端口
#define KEY P3 // 按键控制端口
unsigned char second = 0; // 秒数计数器
unsigned char isRunning = 0; // 是否正在计时
unsigned char isPaused = 0; // 是否暂停计时
void initTimer(); // 初始化定时器函数声明
void display(unsigned char num); // 数码管显示函数声明
void start(); // 启动计时器函数声明
void pause(); // 暂停计时器函数声明
void reset(); // 重置计时器函数声明
void main() {
initTimer(); // 初始化定时器
while (1) { // 主循环
if (!KEY) { // 检测按键是否按下
delay(10); // 延时去抖动
if (!KEY) { // 再次检测按键是否按下
if (!isRunning) { // 如果没有在计时
start(); // 启动计时器
} else if (isPaused) { // 如果正在暂停
start(); // 继续计时器
} else { // 如果正在计时
pause(); // 暂停计时器
}
}
while (!KEY); // 等待按键释放
}
display(second); // 显示秒数
}
}
void initTimer() {
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xFC; // 定时器计数初值,1ms
TL0 = 0x18;
TR0 = 1; // 启动定时器
ET0 = 1; // 打开定时器中断允许
EA = 1; // 打开总中断允许
}
void display(unsigned char num) {
LED1 = 0xFF; // 共阳极LED1
LED2 = 0xFF; // 共阴极LED2
LED1 = num % 10; // 显示个位数字
LED2 = ~(1 << (num / 10)); // 显示十位数字,通过移位实现
delay(5); // 稍微延时
}
void start() {
isRunning = 1; // 设置正在计时
isPaused = 0; // 设置未暂停
}
void pause() {
isPaused = 1; // 设置暂停
}
void reset() {
isRunning = 0; // 设置未计时
isPaused = 0; // 设置未暂停
second = 0; // 秒数清零
}
void timer0() interrupt 1 { // 定时器0中断函数
TH0 = 0xFC; // 重新赋初值,1ms
if (!isRunning) { // 如果未在计时
return; // 直接返回
}
if (!isPaused) { // 如果未暂停
second++; // 秒数加1
if (second == 100) { // 如果秒数达到100,则清零并重置状态
reset();
}
}
}
void delay(unsigned int t) { // 延时函数
unsigned int i, j;
for (i = 0; i < t; i++) {
for (j = 0; j < 110; j++);
}
}
```
void main() { unsigned char key3_flag=0,key4_flag=0; TMOD |=0x01; TH0=0xd8; TL0=0xf0; ET0=1; TR0=0; TMOD |=0x10; TH1=0xF8; TL1=0xf0; ET1=1; TR1=1; EA =1; sec=0; ms=0; P1=0xff; i=0; j=0; start: while(1) { //¿ªÊ¼¡¢ÔÝÍ£ if(!key1) { delay(50); if(!key1) while(!key1) {;} TR0=!TR0; } //¼Ç¼ if(!key2) { delay(50); if(!key2) { while(!key2) //µÈ´ý°´¼üÊÍ·Å {;} if(i==8) {TR0=0; goto start;} Sec[i]= sec; Ms[i]= ms; i++; } } //ÉÏ· if(!key3) { delay(50); if(!key3) { while(!key3) {;} TR0=0; key3_flag=1; //°´¼ü3±êÖ¾ if(j==i) goto start; else if(key4_flag) j+=2; key4_flag=0; sec=Sec[j];ms=Ms[j]; j++; } } //Ï· if(!key4) { delay(50); if(!key4) { while(!key4) {;} TR0=0; key4_flag=1; if(j<0) goto start; else if(key3_flag) j-=2; key3_flag=0; sec=Sec[j];ms=Ms[j]; j--; } } if(!key5) { delay(50); if(!key5) while(!key5) {;} TR0=0; ms=0; sec=0; for(i=0;i<8;i++) { Sec[i]=0;Ms[i]=0; } i=0; }} void time1_isr(void) interrupt 3 using 0 { static unsigned char num; TH1=0xF8; TL1=0xf0; switch(num) { case 0: P2=0xfe;P0=tab[sec/10];break; case 1: P2=0xfd;P0=tab1[sec%10];break; case 2: P2=0xfb;P0=tab[ms/10];break; case 3: P2=0xf7;P0=tab[ms%10];break; default:break; } num++; if(num==4) num=0; }
这是代码的第二部分,其中定义了一个名为 `time1_isr` 的中断处理函数。
1. 首先定义了一个静态无符号字符型变量 `num`,用于记录当前显示的数码管位数。
2. 在中断处理函数中,首先设置了定时器1的高位和低位初值,分别是 `TH1=0xF8` 和 `TL1=0xf0`。
3. 使用一个 `switch-case` 结构根据变量 `num` 的值来选择要显示的数码管位数。
4. 当 `num` 的值为0时,设置 P2 端口的状态为 0xfe,表示选择第一个数码管,并将要显示的数值 `sec/10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
5. 当 `num` 的值为1时,设置 P2 端口的状态为 0xfd,表示选择第二个数码管,并将要显示的数值 `sec%10` 通过 `tab1` 数组查找对应的显示值,并赋给 P0 端口。
6. 当 `num` 的值为2时,设置 P2 端口的状态为 0xfb,表示选择第三个数码管,并将要显示的数值 `ms/10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
7. 当 `num` 的值为3时,设置 P2 端口的状态为 0xf7,表示选择第四个数码管,并将要显示的数值 `ms%10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
8. `switch-case` 结构结束后,递增变量 `num`。
9. 如果 `num` 的值等于4,将其重置为0。
这个中断处理函数的作用是通过定时器1的中断来循环显示计时器的秒数和毫秒数在四个数码管上。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![jar](https://img-home.csdnimg.cn/images/20210720083455.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)