#include <reg51.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char uchar code meg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar shi,fen,miao,dshi,dfen,dmiao; uchar c,clock; uchar shi=5,fen=20,miao=0; uint n; uchar dshi=5,dfen=20,dmiao=10; sbit k1= P3^1; sbit k2= P3^2; sbit k3= P3^3; sbit k4= P3^5; sbit buzz=P3^0; void delay(uint ms) { uint x,y; for(x=ms;x>0;x--)//1ms for(y=114;y>0;y--); } void display(uchar s,uchar f,uchar m) { P2 = 0xff; P1 = 0xfe; P2 = meg[s / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[s % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m % 10]; delay(2); } //中断函数 void time200us() interrupt 1 { n++; if(n==5000) { n=0; miao++; if(miao==60) { fen++; miao=0; if(fen==60) { shi++; fen=0; if(shi==24) { shi=0; } }}}} //消抖 void Delay10ms() //@12MHz { unsigned char i, j; i = 20; j = 113; do { while (--j); } while (--i); } void key() { //按键k1查询 if(k1==0) { Delay10ms(); if(k1==0) { while(k1==0); c++; if(c==4) c=0; } } //k2 void jiatime() interrupt 0 { if(c==1) { miao++; if(miao==60) miao=0; } if(c==2) { fen++; if(fen==60) fen=0; } if(c==3) { shi++; if(shi==24) shi=0; } } //k3 void jiantime() interrupt 2 { if(c==1) { if(miao==0) miao=59; else miao--; } if(c==2) { if(fen==0) fen=59; else fen--; } if(c==3) { if(shi==0) shi=23; else shi--; } } //k4 void T1coun
理解问题#include <reg51.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char uchar code meg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar shi,fen,miao,dshi,dfen,dmiao; uchar c,clock; uchar shi=5,fen=20,miao=0; uint n; uchar dshi=5,dfen=20,dmiao=10; sbit k1= P3^1; sbit k2= P3^2; sbit k3= P3^3; sbit k4= P3^5; sbit buzz=P3^0; void delay(uint ms) { uint x,y; for(x=ms;x>0;x--)//1ms for(y=114;y>0;y--); } void display(uchar s,uchar f,uchar m) { P2 = 0xff; P1 = 0xfe; P2 = meg[s / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[s % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m % 10]; delay(2); } //中断函数 void time200us() interrupt 1 { n++; if(n==5000) { n=0; miao++; if(miao==60) { fen++; miao=0; if(fen==60) { shi++; fen=0; if(shi==24) { shi=0; } }}}} //消抖 void Delay10ms() //@12MHz { unsigned char i, j; i = 20; j = 113; do { while (--j); } while (--i); } void key() { //按键k1查询 if(k1==0) { Delay10ms(); if(k1==0) { while(k1==0); c++; if(c==4) c=0; } } //k2 void jiatime() interrupt 0 { if(c==1) { miao++; if(miao==60) miao=0; } if(c==2) { fen++; if(fen==60) fen=0; } if(c==3) { shi++; if(shi==24) shi=0; } } //k3 void jiantime() interrupt 2 { if(c==1) { if(miao==0) miao=59; else miao--; } if(c==2) { if(fen==0) fen=59; else fen--; } if(c==3) { if(shi==0) shi=23; else shi--; } } //k4 void T1coun
已完成理解「#include <reg51.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char uchar code meg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar shi,fen,miao,dshi,dfen,dmiao; uchar c,clock; uchar shi=5,fen=20,miao=0; uint n; uchar dshi=5,dfen=20,dmiao=10; sbit k1= P3^1; sbit k2= P3^2; sbit k3= P3^3; sbit k4= P3^5; sbit buzz=P3^0; void delay(uint ms) { uint x,y; for(x=ms;x>0;x--)//1ms for(y=114;y>0;y--); } void display(uchar s,uchar f,uchar m) { P2 = 0xff; P1 = 0xfe; P2 = meg[s / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[s % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[f % 10]; delay(2); P2 = 0xff; P1 = _crol_(P1, 1); P2 = 0xbf; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m / 10]; delay(1); P2 = 0xff; P1 = _crol_(P1, 1); P2 = meg[m % 10]; delay(2); } //中断函数 void time200us() interrupt 1 { n++; if(n==5000) { n=0; miao++; if(miao==60) { fen++; miao=0; if(fen==60) { shi++; fen=0; if(shi==24) { shi=0; } }}}} //消抖 void Delay10ms() //@12MHz { unsigned char i, j; i = 20; j = 113; do { while (--j); } while (--i); } void key() { //按键k1查询 if(k1==0) { Delay10ms(); if(k1==0) { while(k1==0); c++; if(c==4) c=0; } } //k2 void jiatime() interrupt 0 { if(c==1) { miao++; if(miao==60) miao=0; } if(c==2) { fen++; if(fen==60) fen=0; } if(c==3) { shi++; if(shi==24) shi=0; } } //k3 void jiantime() interrupt 2 { if(c==1) { if(miao==0) miao=59; else miao--; } if(c==2) { if(fen==0) fen=59; else fen--; } if(c==3) { if(shi==0) shi=23; else shi--; } } //k4 void T1coun」
展开阅读网页
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code meg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar shi,fen,miao,dshi,dfen,dmiao;
uchar c,clock;
uchar shi=5,fen=20,miao=0;
uint n;
uchar dshi=5,dfen=20,dmiao=10;
sbit k1= P3^1;
sbit k2= P3^2;
sbit k3= P3^3;
sbit k4= P3^5;
sbit buzz=P3^0;
void delay(uint ms)
{
uint x,y;
for(x=ms;x>0;x--)//1ms
for(y=114;y>0;y--);
}
void display(uchar s,uchar f,uchar m)
{
P2 = 0xff;
P1 = 0xfe;
P2 = meg[s / 10];
delay(1);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = meg[s % 10];
delay(2);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = 0xbf;
delay(1);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = meg[f / 10];
delay(1);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = meg[f % 10];
delay(2);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = 0xbf;
delay(1);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = meg[m / 10];
delay(1);
P2 = 0xff;
P1 = _crol_(P1, 1);
P2 = meg[m % 10];
delay(2);
}
//中断函数
void time200us() interrupt 1
{
n++;
if(n==5000)
{
n=0;
miao++;
if(miao==60)
{
fen++;
miao=0;
if(fen==60)
{
shi++;
fen=0;
if(shi==24)
{
shi=0;
}
}
}
}
}
//消抖
void Delay10ms() //@12MHz
{
unsigned char i, j;
i = 20;
j = 113;
do
{
while (--j);
} while (--i);
}
void key()
{
//按键k1查询
if(k1==0)
{
Delay10ms();
if(k1==0)
{
while(k1==0);
c++;
if(c==4)
c=0;
}
}
//k2
void jiatime() interrupt 0
{
if(c==1)
{
miao++;
if(miao==60)
miao=0;
}
if(c==2)
{
fen++;
if(fen==60)
fen=0;
}
if(c==3)
{
shi++;
if(shi==24)
shi=0;
}
}
//k3
void jiantime() interrupt 2
{
if(c==1)
{
if(miao==0)
miao=59;
else miao--;
}
if(c==2)
{
if(fen==0)
fen=59;
else
fen--;
}
if(c==3)
{
if(shi==0)
shi=23;
else
shi--;
}
}
//k4
void T1count() interrupt 3
{
if(c==1)
{
miao--;
if(miao==0)
miao=59;
}
if(c==2)
{
fen--;
if(fen==0)
fen=59;
}
if(c==3)
{
shi--;
if(shi==0)
shi=23;
}
}
}
🔧代码功能
- 定时器中断:使用定时器0(T0)每200微秒触发一次中断,用于更新时钟的秒、分、时。1
- 按键中断:通过外部中断0(INT0)和外部中断1(INT1)处理按键k2和k3的操作,分别用于增加和减少时间。2
- 显示函数:通过
display
函数显示当前的时、分、秒。3
📜中断配置
- 定时器0中断:使用
interrupt 1
,每200微秒触发一次,用于更新时钟。1 - 外部中断0:使用
interrupt 0
,处理按键k2的增加时间操作。2 - 外部中断1:使用
interrupt 2
,处理按键k3的减少时间操作。2
🔍关键代码
在51单片机中实现一个精确的时钟程序,涉及多个关键组件和步骤。核心是通过定时器中断来实现时间的精确计数,并通过外部中断处理按键输入,以调整时间显示。以下是对该程序的详细分析和优化建议。
🕒 定时器中断的实现
定时器中断的基本原理
51单片机的定时器中断是通过配置定时器寄存器来实现的。定时器在每个计数周期结束后会产生一个中断请求,程序可以通过中断服务程序(ISR)来处理这些请求。3
定时器寄存器的配置
在程序中,定时器0被配置为工作模式,通过interrupt 1
来处理定时器0的中断。定时器0的中断号为1,这是51单片机的标准配置。1
中断服务程序的优化
在time200us()
中断服务程序中,定时器每200微秒产生一次中断,通过累加计数器n
来实现1秒的计时。这种设计虽然简单,但存在一定的误差,特别是在长时间运行时。建议使用更精确的定时器配置,或者在每次中断时进行时间校准,以提高计时精度。
🔧 外部中断的处理
外部中断的基本原理
外部中断是通过外部引脚的电平变化来触发的。51单片机支持多个外部中断源,每个中断源都有对应的中断号和中断服务程序。2
按键输入的处理
在程序中,按键k1
、k2
、k3
和k4
分别用于调整时、分、秒的增加和减少。通过外部中断interrupt 0
和interrupt 2
来处理按键输入。这种设计虽然简单,但存在按键抖动的问题,可能导致误操作。建议在按键处理程序中加入消抖处理,以确保按键输入的可靠性。
中断服务程序的优化
在jiatime()
和jiantime()
中断服务程序中,按键输入的处理逻辑较为简单,直接对时间变量进行增减操作。这种设计虽然直观,但缺乏对边界条件的处理。例如,当时间变量达到最大值时,应自动归零,而不是继续增加。建议在这些中断服务程序中加入边界检查逻辑,以确保时间的正确性。
📊 时间显示的优化
时间显示的基本原理
时间显示是通过数码管来实现的。程序中通过display()
函数来更新数码管的显示内容。数码管的显示是通过P1和P2端口来控制的。4
显示函数的优化
在display()
函数中,数码管的显示是通过逐位扫描来实现的。这种设计虽然简单,但存在显示闪烁的问题。建议使用更高效的显示驱动方式,例如使用硬件扫描或增加显示缓冲区,以提高显示的稳定性和亮度。
时间变量的同步
在程序中,时间变量shi
、fen
和miao
分别表示时、分、秒。这些变量在中断服务程序中被更新,但在主程序中没有及时同步。建议在主程序中加入时间变量的同步逻辑,以确保显示的时间与实际时间一致。
🚀 程序的整体优化建议
定时器配置的优化
建议使用更精确的定时器配置,例如使用定时器1来实现更精确的计时。定时器1的频率可以通过外部晶振来调整,以提高计时的精度。5
按键处理的优化
建议在按键处理程序中加入消抖处理,以确保按键输入的可靠性。可以使用软件消抖或硬件消抖的方式,具体选择取决于系统的复杂度和成本。
显示驱动的优化
建议使用更高效的显示驱动方式,例如使用硬件扫描或增加显示缓冲区,以提高显示的稳定性和亮度。可以使用专用的显示驱动芯片,以减轻单片机的负担。
时间同步的优化
建议在主程序中加入时间变量的同步逻辑,以确保显示的时间与实际时间一致。可以使用全局变量或信号量来实现时间变量的同步。
通过以上优化,可以显著提高51单片机时钟程序的稳定性和精度,确保时间的准确显示和按键输入的可靠性。