逐行解释以下代码:#include<reg51.h> unsigned char hour = 0; unsigned char min = 0; unsigned char sec = 0; unsigned char count = 0; unsigned char shu[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned dat; void delay(unsigned int k); void display(void); void show(void); void main(void) { TMOD=0x21; SCON=0x50; PCON=0x00; TH0=(65535-50000)/256; TL0=(65535-50000)%256; TH1=0xf4; TL1=0xf4; TR1=1; EA=1; ES=1; PS=1; ET0=1; TR0=1; while(1) { display(); } } void display(void) //数码管扫描显示函数 { unsigned char i; for(i=0;i<6;i++) { switch(i) { case 0: {P2=shu[hour/10];P1=0xdf;break;} case 1: {P2=shu[hour%10];P1=0xef;break;} case 2: {P2=shu[min/10];P1=0xf7;break;} case 3: {P2=shu[min%10];P1=0xfb;break;} case 4: {P2=shu[sec/10];P1=0xfd;break;} case 5: {P2=shu[sec%10];P1=0xfe;break;} } delay(200); P1=0xff; //消隐 } } void delay(unsigned int k) //延时 { unsigned int i; for(i=0;i<k;i++); } void shou(void) interrupt 4 { if(RI==1) { dat=SBUF; RI=0; switch(dat) { case 1: TR0=!TR0; break; case 2:hour++;if(hour==24) hour=0;break; case 3: min++;if(min==60) min=0;break; case 4:sec++;if(sec==60) sec=0;break; case 5:hour=0;min=0;sec=0;P2=shu[0];P1=0xc0;TR0=!TR0;break; default: break; } } } void time(void) interrupt 1 //定时1s { TH0=(65535-50000)/256; TL0=(65535-50000)%256; count++; if(count==20) { count=0; sec++; if(sec==60) { sec=0; min++; if(min==60) { min=0; hour++; if(hour==24) { hour=0; } } } } }
时间: 2023-06-25 19:07:53 浏览: 91
80c51 C51电子钟
这段代码是一个基于 8051 单片机的计时器程序,用于控制数码管显示时间。下面是代码的逐行解释:
```C
#include<reg51.h>
```
引入 8051 单片机的头文件。
```C
unsigned char hour = 0;
unsigned char min = 0;
unsigned char sec = 0;
unsigned char count = 0;
```
定义了四个无符号字符型变量,分别是时、分、秒和计数器。
```C
unsigned char shu[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
```
定义了一个数组 shu,里面存放了数字 0~9 在数码管上对应的编码。
```C
unsigned dat;
```
定义了一个无符号整型变量 dat。
```C
void delay(unsigned int k);
void display(void);
void show(void);
```
声明了三个函数,分别是延时函数 delay(),数码管扫描显示函数 display() 和 show()。
```C
void main(void)
{
TMOD=0x21;
SCON=0x50;
PCON=0x00;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TH1=0xf4;
TL1=0xf4;
TR1=1;
EA=1;
ES=1;
PS=1;
ET0=1;
TR0=1;
while(1)
{
display();
}
}
```
主函数,初始化了计时器、串口、中断等相关配置,然后进入了一个无限循环,不断调用数码管扫描显示函数 display()。
```C
void display(void)
{
unsigned char i;
for(i=0;i<6;i++)
{
switch(i)
{
case 0: {P2=shu[hour/10];P1=0xdf;break;}
case 1: {P2=shu[hour%10];P1=0xef;break;}
case 2: {P2=shu[min/10];P1=0xf7;break;}
case 3: {P2=shu[min%10];P1=0xfb;break;}
case 4: {P2=shu[sec/10];P1=0xfd;break;}
case 5: {P2=shu[sec%10];P1=0xfe;break;}
}
delay(200);
P1=0xff; //消隐
}
}
```
数码管扫描显示函数,通过循环遍历 0~5 位数码管,根据当前时间的时、分、秒值来显示对应数字。
```C
void delay(unsigned int k)
{
unsigned int i;
for(i=0;i<k;i++);
}
```
延时函数,用于控制数码管扫描的速度。
```C
void shou(void) interrupt 4
{
if(RI==1)
{
dat=SBUF;
RI=0;
switch(dat)
{
case 1: TR0=!TR0; break;
case 2:hour++;if(hour==24) hour=0;break;
case 3: min++;if(min==60) min=0;break;
case 4:sec++;if(sec==60) sec=0;break;
case 5:hour=0;min=0;sec=0;P2=shu[0];P1=0xc0;TR0=!TR0;break;
default: break;
}
}
}
```
串口中断函数,当有数据从串口接收时,将数据存入 dat 中,并根据数据的不同值来进行相应的操作。例如,当数据为 1 时,控制计时器的启停;当数据为 2 时,增加小时数,如果当前小时数已经是 23 时,则归零;当数据为 5 时,将小时、分钟、秒钟和数码管都清零。
```C
void time(void) interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
count++;
if(count==20)
{
count=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
}
```
定时器中断函数,每隔一秒钟计数器 count 加 1,当 count 等于 20 时,也就是计满了 20 秒,就将计数器和秒钟都归零,并增加分钟数和小时数。如果当前小时数已经是 23 时,则归零。
阅读全文