单片机电子时钟实验报告

发布时间:2014-06-11 18:15:30   来源:文档文库   
字号:

电子时钟

预备知识:

数码管:

内部接线

C语言程序:

一、电子时钟

(一) 设计目的

通过电子时钟综合设计,使学生学会利用8051定时器时间计时处理功能,了解按键扫描及控制LED数码管显示原理,掌握单片机和按键以及LED数码管硬件电路设计及控制程序的设计方法。思考按键消除抖动、LED动态显示与静态显示的特点,从而提高学生解决实际问题的能力。

(二) 设计任务及要求

利用实验平台上4LED数码管, 设计带有闹铃功能的数字时钟,要求:

1 4位数码管上显示当前时间。显示格式时时分分

2 LED闪动做秒显示。

3 利用按键可对时间及闹玲进行设置,并可显示闹玲时间。当闹玲时间到蜂鸣器发出声响,按停止键使可使闹玲声停止。

()我采用的是TB-22766板子,单片机类型是STC89C52RC

()软件设计思想:

采用语言:C语言,主要中断:内部T0中断为唯一的中断,主程序大体分为两部分:无按键被按下时的显示,有按键被按下时,输入定时时间或者书输入当前时间,然后的显示软件,最后是一个蜂鸣器的控制程序。前面是三个子程序:两个按键扫描和一个延时小程序。

按键的扫描程序设置:

N

Y

N

具体的C语言程序:

/*---------------------------------------------------------------------------------------------------------------------

=======================================

基于JD51开发板的电子闹钟程序

=======================================

************************************程序功能说明************************************************************************

1、基础功能为计时,并显示当前时间。

2、秒表功能,按下key1键进入秒表模式,再次按下key3开始计时,再次按下key1停止,按下key1再次开始计时,按key4跳出秒表程序。

3、调时功能,按下key2进入调时模式,key3调小时,key4调分钟,key2确定并退出。

4、闹钟功能,按下key3进入闹钟设定模式,key3调小时,key4调分钟,key2确定并退出,当设定时间到达是,响铃,key3可以退出响铃。

5、观看当前具体时刻,按key4进入,观看当前秒数,约12s后自动退出。

Planed by LD.

************************************************************************************************************************/

#include "reg52.h"

//#include "delay.c"

#define uchar unsigned char

sbit CE573=P2^5; //

sbit BUZZER=P2^4;

sbit KEY1=P3^3;

sbit KEY2=P3^2;

sbit KEY3=P3^4;

sbit KEY4=P3^5;

sbit KEY5=P3^7;

code unsigned char digseg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

// 0 1 2 3 4 5 6 7 8 9 A b C d E F

code unsigned char segsel[]={0xfe,0xfd,0xfb,0xf7};

//数码管段选

int sum=0;

int s=30; //当前时间

int mi=0; //当前时间

int h=0; //当前时间

int a;

int b;

int k;

int x,y,z,x1,x2;

int swt=1;

int swt2=1;

int min=1; //闹钟分

int hour=0; //闹钟时

int m=1; //设定初始参数

unsigned char beat;

code unsigned song[]={0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04,0x82,0x01,0x81,0x94,0x84,0xC4,0xB4,0x04,0x82,0x01,0x81,0xF4,0xD4,0xB4,

0xA4,0x94,0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04,0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04,0x82,0x01,0x81,0x94,

0x84,0xC4,0xB4,0x04,0x82,0x01,0x81,0xF4,0xD4,0xB4,0xA4,0x94,0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04,0x00};

code int note[]={0x0000,0xFB03,0xFB8E,0xFC0B,0xFC43,0xFCAB,0xFD08,0xFD32,0xFD81,0xFDC7,0xFE05,0xFE21,0xFE55,0xFE83,0xFE99,0xFEC0};

unsigned char hi_note,low_note;

void delay();

void initmpu(void) //初始化程序,确定计数器工作方式,装填工作数,确定确定终端模式。

{

TMOD=0x11; //定时器01 都以方式1计数

TL0=0xff;

TH0=0xdb;

TL1=0xFF;

TH1=0xDB;

PCON=0x00;

IE=0x8f; //开放所有中断

}

void Delay(int m)//延时程序

{

while(--m);

}

void Delay1(int m)//延时程序 用来播放音乐

{ int kk,jj;

for(;m>0;m--)

{ for(kk=180;kk>0;kk--)

for(jj=125;jj>0;jj--);}

}

void test_led(void)//测试led

{

int i;

P1=0x7F;

Delay(40000);

for(i=0;i<7;i++)

{

P1=P1>>1;

Delay(40000);

}

P1=0xFF;

Delay(40000);

P1=0x00;

Delay(40000);

P1=0xFF;

Delay(40000);

P1=0x00;

Delay(40000);

P1=0xFF;

}

void prt(int hour,int min)//数码管显示子程序

{

int a,b,c,d;

a=hour/10;

b=hour%10;

c=min/10;

d=min%10;

{//P2=0xfe;

P2=segsel[0];

P0=digseg[a];

Delay(100);

P2=segsel[1];

P0=digseg[b];

Delay(100);

P2=segsel[2];

P0=digseg[c];

Delay(100);

P2=segsel[3];

P0=digseg[d];

Delay(100);

}

}

void test_digseg(void)//测试数码管

{

char i,j;

CE573=1;

for(i=0;i<16;)

{

for(j=0;j<4;j++)

{

P2=segsel[j];

P0=digseg[i];

i++;

Delay(40000);

}

}

P2=0xF0; // 4只数码管同时开启

P0=0xFF;

Delay(40000);

P0=0x00;

Delay(40000);

P0=0xFF;

Delay(40000);

P0=0x00;

Delay(40000);

P0=0xFF;

}

void test_beep(char n) //测试蜂鸣器

{

char i;

for(i=0;i

{

BUZZER=0;

Delay(9000);

BUZZER=1;

Delay(9000);

}

}

char check_K3(void) // 按键去抖

{

if(KEY3==0)

{

Delay(2000);

{

if(KEY3==0)

{

return 1;

}

}

}

return 0;

}

char check_K4(void)//按键去抖

{

if(KEY4==0)

{

Delay(2000);

{

if(KEY4==0)

{

return 1;

}

}

}

return 0;

}

char key1_flag=0;

char key2_flag=0;

void ext_int0() interrupt 0 //外部中断0服务程序

{

EA = 0;

Delay(4000);

key1_flag=1;

EA = 1;

}

void ext_int1() interrupt 2 //外部中断1服务程序

{

EA = 0;

Delay(4000);

key2_flag=1;

EA = 1;

}

void time() interrupt 1//计时器0计数器中断程序,用于确定当前时间

{

EA=0;

x1++;

TR0=0;

swt=1;

TL0=0xff; //计数一百就是一秒

TH0=0xdb;

TR0=1;

if(x1==100)

{x1=0;

s++;

if(P1==0x7f) //LED闪烁表示一秒

P1=0xff;

else

P1=0x7f;

}

if(s==60)

{

s=0;

m=1;

mi++;

}

if(mi==60)

{

mi=0;

h++;

}

if(h==24)

h=0;

EA=1;

}

void time2() interrupt 3//计数器1中断程序,用于播放音乐

{

TR1=0;

TL1=low_note;

TH1=hi_note;

TR1=1;

BUZZER=~BUZZER;

}

void singing()

{

// unsigned char beat,temp;

unsigned char temp;

int ii=0;

while(1)

{

prt(h,mi); //显示当前时间

temp=song[ii]; // 读出乐谱的一个byte

if (temp==0)

{ // 如果是0就表示音乐结束

TR1=0; // 停止计时计数器1

return; // 返回

}

beat=temp&0x0f; //取出低阶的4位,这是拍子

temp=(temp>>4)&0x0f; //取出高阶4位当成音符的频率

if (temp==0)

TR1=0; //如果拍子是0就表示休止符

else {

hi_note=note[temp]>>8; //根据音符的频率得到Timer1计数值

low_note=note[temp]&0x00FF;

TR1=1; //启动计时计数器1

}

Delay1(beat); // 延迟拍子的时间

TR1=0; //计时器1停止计数

BUZZER=1;

ii++;

if(key2_flag) //2键退出闹铃

{

key2_flag=0;

P2=0xff;

m=0;

TR1=0;

BUZZER=1;

break;

}

}

}

main()//主程序

{

initmpu();

test_beep(4);

test_led();

test_digseg();

P0=0XBF;

TR0=1; //计时器0开始工作

while(1) // 不断刷新程序

{

prt(h,mi); //显示当前时间

if(key1_flag) //以中断方式响应按键,秒表

{

key1_flag=0; //去除外部中断1标志位

P2=0xff;

test_beep(1); //驱动蜂鸣器

a=0;

b=0;

while(1) //不断刷新程序

{

prt(0,0);

if(check_K3())

{

P2=0xff;

break; //key3再次按下,开始计时

}

}

test_beep(1);

while(1)

{

if(swt&&swt2)

{

swt=0;

a++;

if(a==100)

{

a=0;

b++;

}

}

prt(b,a);

if(key1_flag==1)//key1再次按下停止计数

{

P2=0xff;

key1_flag=0;

test_beep(1);

swt2=0;

}

if(check_K3())//按下key3再次计数

{

P2=0xff;

key1_flag=0;

test_beep(1);

swt2=1;

}

if(check_K4())//按下key4跳出程序

{

P2=0xff;

Delay(8000);

test_beep(1);

break;

}

if(key2_flag==1)

{

key2_flag=0;

a=0;

b=0;

P2=0xff;

test_beep(1);

}

}

}

else if(key2_flag)//调整当前时间

{

P2=0xff;

key2_flag=0;

test_beep(3);

while(1)

{

prt(h,mi);

if(check_K3()) //调时

{

h++;

P2=0xff;

test_beep(1);

if(h==24)

h=0;

Delay(10000);

}

if(check_K4()) //调分

{

mi++;

P2=0xff;

test_beep(1);

if(mi==60)

{

mi=0;

h++;

}

if(h==24)

h=0;

Delay(10000);

}

if(key2_flag) //再按2 退出调时

{

P2=0xff;

key2_flag=0;

test_beep(3);

Delay(10000);

break;

}

}

}

else if(check_K3())//设置闹钟时间

{

P2=0xff;

test_beep(3);

while(1)

{

prt(hour,min); //显示当前闹铃时间

if(check_K3())

{

P2=0xff;

hour++;

test_beep(1);

if(hour==24)

hour=0;

Delay(10000);

}

else if(check_K4())

{

P2=0xff;

min++;

test_beep(1);

if(min==60)

{

min=0;

hour++;

}

if(hour==24)

hour=0;

Delay(10000);

}

if(key2_flag) //2键退出

{

key2_flag=0;

P2=0xff;

test_beep(5);

Delay(10000);

break;

}

}

}

else if(check_K4())//观看当前秒单位

{

test_beep(1);

k=3000;

while(k--)

{

prt(0,s);

P1=0;

}

P1=0xff;

}

if((h==hour)&&(min==mi))//响铃

{

while(m)

{

singing();

}

}

}

}总结:虽然这个C语言程序比较容易理解,但是运行的速度对比汇编语言比较慢,汇编语言直接和内存打交道,所以比较直接,我们如果想更加深入地去理解其内存中数据变化,还需要深入学习汇编语言的知识,我明白现在只是一个起步,前方的路还很长,我会更加努力好好学习,丰富自己的知识,最后使得自己成长,这样我也就很快乐了,路漫漫其修远兮,吾将上下而求索!还有老师辛苦了,一期一会,祝您幸福!

本文来源:https://www.2haoxitong.net/k/doc/071b76465f0e7cd18425365e.html

《单片机电子时钟实验报告.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式