单片机六位电子钟

发布时间:2019-04-09 10:55:54

单片机六位电子钟

一、原理说明:

1、显示原理: 显示部分主要器件为 2 位共阳红色数码管,驱动采用 PNP 型三极管驱动,各端口配有限流电阻,驱动方式为扫描,占用 P1.0P1.6 端口。冒号部分采用 4 Φ3.0的红色发光,驱动方式为独立端口驱动,占用P1.7端口。

2、键盘原理: 按键 S1S3 采用复用的方式与显示部分的 P3.5P3.4P3.2 口复用。其工作方式为,在相应端口输出高电平时读取按键的状态并由单片机支除抖动并赋予相应的键值。

3、迅响电路及输入、输出电路原理: 迅响电路由有源蜂鸣器和 PNP 型三极管组成。其工作原理是当 PNP 型三极管导通后有源蜂鸣器立即发出定频声响。驱动方式为独立端口驱动,占用P3.7端口。 输出电路是与迅响电路复合作用的,其电路结构为有源蜂鸣器,5.1K定值电阻R6,排针J3并联。当有源蜂鸣器无迅响时J3输出低电平,当有源蜂鸣器发出声响时J3输出高电平,J3可接入数字电路等各种需要。驱动方式为迅响复合输出,不占端口。 输入电路是与迅响电路复合作用的,其电路结构是在迅响电路的 PNP 型三极管的基极电路中接入排针J2。引脚排针可改变单片机I/O口的电平状态,从而达到输入的目的。驱动方式为复合端口驱动,占用P3.7端口。

4、单片机系统: 本产品采用AT89C2051为核心器件,并配合所有的必须的电路,只具有上电复位的功能,无手动复位功能。

二、使用说明:

1、功能按键说明: S1为功能选择按键,S2为功能扩展按键,S3为数值加一按键。

2、功能及操作说明:操作时,连续短时间(小于1)按动S1,即可在以上的6个功能中连续循环。中途如果长按(大于2)S1,则立即回到时钟功能的状态。

功能调节说明

1、时钟功能:上电后即显示101000 ,寓意十全十美。

2、校时功能:短按一次S1,即当前时间和冒号为闪烁状态,按动S2则小时位加1,按动S3则分钟位加1,秒时不可调。

3、闹钟功能:短按二次S1,显示状态为221000,冒号为长亮。按动S2刚小时位加1,按动S3则分钟位加1,秒时不可调。当按动小时位超过23时则会显示------,这个表示关闭闹钟功能。闹铃声为蜂鸣器长鸣3秒钟。

4、倒计时功能:短按三次S1,显示状态为 0,冒号为长灭。按动S2则从低位依此显示高位,按动S3则相应位加1,当S2按到第6次时会在所设定的时间状态下开始倒计时,再次按动S2将再次进入调整功能,并且停止倒计时。

5、秒表功能:短按四次S1,显示状态为000000,冒号为长亮。按动S2则开始秒表计时,再次按动S2则停止计时,当停止计时的时候按动S3则秒表清零。6、计数器功能:短按五次S1,显示状态为000000,冒号为长灭,按动S2则计数器加1,按动S3则计数器清零。

1)时钟功能:上电后即显示101000 ,寓意十全十美。

2)校时功能:短按一次 S1,即当前时间和冒号为闪烁状态,按动 S2 则小时位加 1,按动 S3则分钟位加1,秒时不可调。

3)闹钟功能:短按二次S1,显示状态为221000,冒号为长亮。按动S2刚小时位加1,按动S3则分钟位加1,秒时不可调。当按动小时位超过23时则会显示------,这个表示关闭闹钟功能。闹铃声为蜂鸣器长鸣3秒钟。

4)倒计时功能:短按三次S1,显示状态为 0,冒号为长灭。按动S2则从低位依此显示高位,按动S3则相应位加1,当S2按到第6次时会在所设定的时间状态下开始倒计时,再次按动S2将再次进入调整功能,并且停止倒计时。

5)秒表功能:短按四次 S1,显示状态为 000000,冒号为长亮。按动 S2 则开始秒表计时,再次按动S2则停止计时,当停止计时的时候按动S3则秒表清零。

6)计数器功能:短按五次S1,显示状态为000000,冒号为长灭,按动S2则计数器加1,按动S3则计数器清零

部分C语言源程序

#include

code senen_seg[10]={0x81,0xe7,0x92,0xa2,0xe4,0xa8,0x88,0xe3,0x80,0xa0}; //P1.7(冒号)口高电平

bit key1_enter=0,key2_enter=0,key3_enter=0,countdown_mark=0,stopwatch_mark=0,count_mark=0,bell_mark=0; //状态标志

unsigned char program=0,program_variable=0,count_bit=0,count=0;

unsigned char hour=10,minute=10,second=0; //时间变量

unsigned char delayed_hour=22,delayed_minute=10,delayed_second=0; //定时变量

unsigned char count_hour=0,count_minute=0,count_second=0; //计时计数变量

unsigned int count_time=0,count_count=0;

void delay(unsigned int t) //延时子程序

{

unsigned int i,j;

for(i=0;ifor(j=0;j<10;j++)

;

}

void time0_init(void){ //定时计数0器初始化

EA=0;

TR0=0;

TMOD=0x02;

TH0=0x4;

TL0=0x4;

ET0=1;

TR0=1;

EA=1;

}



static void timer0_isr(void) interrupt TF0_VECTOR using 1 //定时计数0器中断函数

{

count_time++; //时钟计时程序

if(count_time>=4020){

count_time=0;

second++;

if(second>=60){

second=0;

minute++;

if(minute>=60){

minute=0;

hour++;

if(hour>=24)hour=0;

}

}

}

if(delayed_hour==hour && delayed_minute==minute && second<4) P3_7=0;

else P3_7=1;

if(countdown_mark==1){ //倒计时程序

count_count++;

if(count_count>=4000 && (count_second!=0|count_minute!=0|count_hour!=0)){

count_count=0;

count_second--;

if(count_second>=60){

count_second=59;

count_minute--;

if(count_minute>=60){

count_minute=59;

count_hour--;

if(count_hour>=100) count_hour=99;

}

}

}

if(count_second==0&&count_minute==0&&count_hour==0&&count_count<=12000) P3_7=0;

else P3_7=1;

if(count_count>=15000) count_count=14000;

}

if(stopwatch_mark==1){ //秒表程序

count_count++;

if(count_count>=40){

count_count=0;

count_second++;

if(count_second>=100){

count_second=0;

count_minute++;

if(count_minute>=60){

count_minute=0;

count_hour++;

if(count_hour>=60) count_hour=0;

}

}

}

}

}

unsigned char show_key (void){

unsigned char x=0,y=0;

switch (program){

case 0: P1&=senen_seg[second%10]; //时钟秒的个位

break;

case 1: if(count_time>=2000) P1&=senen_seg[second%10]; //校正秒的个位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟秒的个位

else P1&=senen_seg[delayed_second%10];

break;

case 3: if(count_bit>=0) P1&=senen_seg[count_second%10];//倒计时秒的个位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_second%10]; //秒表秒的个位

break;

case 5: P1&=senen_seg[count_second%10]; //计数器个位

break;

}

P3_3=0;

delay(10);

if(P3_5==0){ //功能键1识别

key1_enter=1;

if(count<=254)count++;

}

if(P3_4==0) key2_enter=1; //功能键2识别

if(P3_2==0) key3_enter=1; //功能键3识别

P3_3=1;

P1|=0xff;

switch (program){

case 0: P1&=senen_seg[second/10]; //时钟秒的十位

break;

case 1: if(count_time>=2000) P1&=senen_seg[second/10]; //校正秒的十位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟秒的十位

else P1&=senen_seg[delayed_second/10];

break;

case 3: if(count_bit>=1) P1&=senen_seg[count_second/10];//倒计时秒的十位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_second/10]; //秒表秒的十位

break;

case 5: P1&=senen_seg[count_second/10]; //计数器十位

break;

}

P3_1=0;

delay(10);

P3_1=1;

P1|=0xff;

switch (program){

case 0: P1&=senen_seg[minute%10]; //时钟分的个位

break;

case 1: if(count_time>=2000) P1&=senen_seg[minute%10]; //校正分的个位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟分的个位

else P1&=senen_seg[delayed_minute%10];

break;

case 3: if(count_bit>=2) P1&=senen_seg[count_minute%10];//倒计时分的个位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_minute%10]; //秒表分的个位

break;

case 5: P1&=senen_seg[count_minute%10]; //计数器百位

break;

}

P3_2=0;

delay(10);

P3_2=1;

P1|=0xff;

switch (program){

case 0: P1&=senen_seg[minute/10]; //时钟秒的个位

break;

case 1: if(count_time>=2000) P1&=senen_seg[minute/10]; //校正秒的个位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟秒的个位

else P1&=senen_seg[delayed_minute/10];

break;

case 3: if(count_bit>=3) P1&=senen_seg[count_minute/10];//倒计时秒的个位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_minute/10]; //秒表秒的个位

break;

case 5: P1&=senen_seg[count_minute/10]; //计数器千位

break;

}

P3_5=0;

delay(10);

P3_5=1;

P1|=0xff;

switch (program){

case 0: P1&=senen_seg[hour%10]; //时钟时的个位

break;

case 1: if(count_time>=2000) P1&=senen_seg[hour%10]; //校正时的个位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟时的个位

else P1&=senen_seg[delayed_hour%10];

break;

case 3: if(count_bit>=4) P1&=senen_seg[count_hour%10];//倒计时时的个位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_hour%10]; //秒表时的个位

break;

case 5: P1&=senen_seg[count_hour%10]; //计数器万位

break;

}

P3_0=0;

delay(10);

if(P3_4==1 && key2_enter==1){

x=3; //确认功能键2识别,返回3

key2_enter=0;

}

P3_0=1;

P1|=0xff;

switch (program){

case 0: P1&=senen_seg[hour/10]; //时钟时的个位

break;

case 1: if(count_time>=2000) P1&=senen_seg[hour/10]; //校正时的个位

break;

case 2: if(delayed_hour==24) P1=0xfe; //闹钟时的个位

else P1&=senen_seg[delayed_hour/10];

break;

case 3: if(count_bit>=5)P1&=senen_seg[count_hour/10]; //倒计时时的个位

else P1=0xff;

break;

case 4: P1&=senen_seg[count_hour/10]; //秒表时的个位

break;

case 5: P1&=senen_seg[count_hour/10]; //计数器万位

break;

}

P3_4=0;

delay(10);

if(P3_5==1 && key1_enter==1){ //确认功能键1识别,执行退出或进入下一个功能

if(count>=127) x=1; //确认功能键1为长按,返回1

else x=2; //确认功能键1为短按,返回2

key1_enter=0;

count=0;

}

if(P3_2==1 && key3_enter==1){

x=4; //确认功能键3识别,返回4

key3_enter=0;

}

P3_4=1;

P1|=0xff;

if(program<=1 && count_time>=2000) P1&=0xff; //校时和显示功能时钟时冒号闪烁

if(program<=1 && count_time<=2000) P1&=0x7f;

if(program==2) P1&=0x7f; //设置闹钟功能时冒号长亮

if(program==3) P1&=0xff; //设置倒计时功能时冒号长灭

if(program==4) P1&=0x7f; //设置秒表功能时冒号长亮

if(program==5) P1&=0xff; //设置计数时冒号长灭

y=x;

x=0;

return y;

}

void main(){ //主程序

P1=0xff;

P3=0xff;

time0_init();

while(1){

switch(program){

case 0: while(program==0){ //时钟菜单

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=1;

break;

}

}

break; //校时菜单

case 1: while(program==1){

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=2;

break;

case 3: hour++;

if(hour>=24)hour=0;

break;

case 4: minute++;

if(minute>=60)minute=0;

break;

}

}

break;

case 2: while(program==2){ //闹钟菜单

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=3;

break;

case 3: delayed_hour++;

if(delayed_hour>=25)delayed_hour=0;

break;

case 4: delayed_minute++;

if(delayed_minute>=60)delayed_minute=0;

break;

}

}

break;

case 3: while(program==3){ //倒计时菜单

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=4;

break;

case 3: count_bit++;

if(count_bit>=7)count_bit=0;

break;

case 4: switch(count_bit){

case 0: count_second+=1;

break;

case 1: count_second+=10;

break;

case 2: count_minute+=1;

break;

case 3: count_minute+=10;

break;

case 4: count_hour+=1;

break;

case 5: count_hour+=10;

break;

case 6: break;

}

if(count_hour>=100) count_hour-=100;

if(count_minute>=60) count_minute-=60;

if(count_second>=60) count_second-=60;

break;

}

if(count_bit==6) countdown_mark=1;

else countdown_mark=0;

}

break;

case 4: count_hour=0; //秒表菜单

count_minute=0;

count_second=0;

while(program==4){

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=5;

break;

case 3: stopwatch_mark=~stopwatch_mark;

break;

case 4: if(stopwatch_mark==0){

count_hour=0;

count_minute=0;

count_second=0;

}

break;

}

}

break; //计数器菜单

case 5: count_hour=0;

count_minute=0;

count_second=0;

while(program==5){

switch(show_key()){

case 0: break;

case 1: program=0;

break;

case 2: program=0;

break;

case 3: count_second++;

if(count_second>=100){

count_second=0;

count_minute++;

if(count_minute>=100){

count_minute=0;

count_hour++;

if(count_hour>=100)count_hour=0;

}

}

break;

case 4: count_hour=0;

count_minute=0;

count_second=0;

break;

}

if(P3_7==0){

while(P3_7==0) show_key();

count_second++;

if(count_second>=100){

count_second=0;

count_minute++;

if(count_minute>=100){

count_minute=0;

-------------------------------------------------------------------------

单片机六位电子钟

相关推荐