基于单片机的简易电子时钟设计c语言,一种基于单片机的电子时钟的设计的制作方法...

本发明专利涉及单片机技术领域,具体涉及一种基于单片机的电子时钟的设计。

背景技术:

单片机是指一个集成在一块芯片上的完整计算机系统。尽管他的大部分功能集成在一个小芯片上,但是它具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分单片机还会具有外存。同时集成诸如通讯接口、定时器,实时时钟等外围设备。而现在最强大的单片机系统甚至可以将声音、图像、网络、复杂的输入输出系统集成在一块芯片上。单片机也被称为微控制器(Microcontroller),是因为它最早被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来,最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小、更容易集成于复杂的而对体积要求严格的控制设备当中。INTEL的Z80是最早按照这种思想设计出的处理器,从此以后,单片机和专用处理器的发展便分道扬镳。

发明专利内容

本发明专利涉及一种基于单片机的电子时钟的设计,本发明设计的电子时钟是基于51单片机,同时使用c语言为程序设计语言,从而克服传统电子时钟的弊端;本发明拟实现的基本功能为单片机计时显示功能,本发明能够体现单片机电子时钟的可扩展优越性,加入时间调整程序,使用按钮,调整年月日及时间;加入阴历显示功能。

附图说明

图1:主程序流程图。

具体实施方式

为了使本发明专利的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明专利进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明专利,并不用于限定本发明专利。

本发明专利涉及一种基于单片机的电子时钟的设计,本发明设计的电子时钟是基于51单片机,同时使用c语言为程序设计语言,从而克服传统电子时钟的弊端;本发明拟实现的基本功能为单片机计时显示功能,本发明能够体现单片机电子时钟的可扩展优越性,加入时间调整程序,使用按钮,调整年月日及时间;加入阴历显示功能。

进一步的,本发明可实现的功能:

(1)采用六位数码管显示小时、分钟、秒,并且可以任意设定时间;

(2)可以查看并且设定日期,日期采用年、月、日的显示方式;

(3)可以查看并设定闹钟,闹钟的显示方式采用与时间相同的显示方式;

(4)可以查看并设定星期,数码管的最后一位显示星期,用数字8表示星期日。

进一步的 系统设定详细说明:系统的初始状态为显示时钟状态,此时显示小时、分钟、秒。初始状态下,按K0键进入时间调整程序,按K1键查看闹钟,按K2键查看日期,按K3键查看星期。进入时间调整状态后,首先调整分钟,此时分钟闪烁显示,按K1键加一,按K2键减一。按K0键开始调整小时,此时小时闪烁显示,按K1键加一,按K2键减一,再按K0键后系统返回到显示时间状态。在调整时间状态下按下K3键进入调整闹钟状态,此时显示原先的闹钟时间,并且闹钟分钟闪烁显示,此时按K1键加一,按K2键减一;调整后按K0键转换到闹钟小时调整单元,此时按K1键加一,按K2键减一。闹钟调整完毕后按K0键回到调整时间状态,按K3键转到调整日期状态。在调整日期状态下,日单元闪烁显示,此时按K1键加一,按K2键减一;按下K0键进入调整月,此时按K1键加一,按K2键减一;按下K0键进入调整年,此时按K1键加一,按K2键减一。此时按下K0键返回到调整时间状态,按下K3键进入调整星期状态。在调整星期状态下,星期闪烁显示,此时按K1键加一,按K2键减一。按下K0键返回到调整时间状态。此时分钟闪烁显示,按K0键开始调整小时,此时小时闪烁显示,再按K0键后系统返回到显示时间状态。

进一步的, 秒计数器的计数时钟信号为1Hz的标准信号,可以由CPLD板上提供的20MHZ的信号通过分频得到。秒计数器的进位输出信号作为分钟计数器的计数信号,分钟计数器的进位输出信号又作为小时计数器的计数信号。设计一个同时显示时、分、秒6个数字的数字钟,则需要6个七段显示器。若同时点亮这6个七段显示器,则电路中会产生一个比较大的电流,很容易造成电路烧坏,我们通过扫描电路来解决这一问题,通过产生一个扫描信号LT(0)一LT(5)来控制6个七段显示器,依次点亮6个七段显示器,也就是每次只点亮一个七段显示器。只要扫描信号的频率超过人的眼睛视觉暂留频率24Hz以上,就可以达到尽管每次点亮单个七段显示器,却能具有6个同时显示的视觉效果,而目显示也不致闪烁抖动。其中6位扫描信号一方面控制七段显示器依次点亮,一方面控制6选1选择器输出相应显示数字。控制电路用来将控制时钟的一些功能加入到整个正常计数的显示电路中,通过最终的显示来验证控制电路的正确性。图1为整体系统设计标图。

进一步的,C语言是计算机提供给用户的最快最有效的语言,也是能够利用计算机的所有硬件特性并能够直接控制硬件的唯一语言。对于对电子时钟的设计这样的程序来说,用c语言是最快最有效的语言,下面是用c语言进行编写的基于单片机的电子时钟的设计的部分主要流程程序:

#include "main.h"

#include "ds1302.h"

code uint8 Ledcode[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0x86};

uint8 Time[7]={55,59,11,22,2,2,11};//秒分时日月周年10-08-15 11:59:55

uint8 Led_buf[6];

uint8 Num, Led_n=0, T_n=0;

void delay(uint16 n)

{

while (n--);

}

/*

* 初始化系统定时器*/

void systimer_init(void)

{

TMOD = 0x01;

TH0 = 0xF8;

TL0 = 0xCC;

TR0 = 0;

ET0 = 1;

TMOD &= 0x0F;

TMOD |= 0x10;

TH1 = 0xDC; // 定时10ms

TL1 = 0x00;

TR1 = 0;

ET1 = 0;

EA = 1;

}

/*

* 判断键值*/

uint8 scan_key(void)

{

uint8 val=0;

KeyOut1 = 0;

KeyOut2 = 1;

KeyOut3 = 1;

KeyOut4 = 1;

if (KeyIn4 == 0)

{

delay(KEY_DELAY);

if (KeyIn4 == 0)

val = K_ADD;

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;

KeyOut2 = 0;

KeyOut3 = 1;

KeyOut4 = 1;

if (KeyIn4 == 0)

{

delay(KEY_DELAY);

if (KeyIn4 == 0)

val = K_LEFT;

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;

KeyOut2 = 1;

KeyOut3 = 0;

KeyOut4 = 1;

if (KeyIn4 == 0)

{

delay(KEY_DELAY);

if (KeyIn4 == 0)

val = K_SUB;

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;

KeyOut2 = 1;

KeyOut3 = 1;

KeyOut4 = 0;

if (KeyIn2 == 0)

{

delay(KEY_DELAY);

if (KeyIn2 == 0)

val = K_SET;

}

if (KeyIn3 == 0)

{

delay(KEY_DELAY);

if (KeyIn3 == 0)

val = K_ENTER;

}

if (KeyIn4 == 0)

{

delay(KEY_DELAY);

if (KeyIn4 == 0)

val = K_RIGHT;

}

while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

return val;

}

/* * 制作数码管数据*/

void make_led_number(void)

{

ET0 = 0;

Led_buf[0] = 0x7F & Ledcode[Time[0]%10];

Led_buf[1] = Ledcode[Time[0]/10];

Led_buf[2] = 0x7F & Ledcode[Time[1]%10];

Led_buf[3] = Ledcode[Time[1]/10];

Led_buf[4] = 0x7F & Ledcode[Time[2]%10];

Led_buf[5] = Ledcode[Time[2]/10];

ET0 = 1;

}

/* * 启动clock数字闪烁*/

void start_flash(void)

{

T_n = 0;

Led_buf[2*Num] = 0x7F & Ledcode[Time[Num]%10];

Led_buf[2*Num+1] = Ledcode[Time[Num]/10];

TH1 = 0xDC; // 定时10ms

TL1 = 0x00;

TR1 = 1;

ET1 = 1;

}

/* * 停止clock数字闪烁*/

void stop_flash(void)

{

ET1 = 0;

TR1 = 0;

Led_buf[2*Num] = 0x7F & Ledcode[Time[Num]%10];

Led_buf[2*Num+1] = Ledcode[Time[Num]/10];

}

/* * 时钟设置*/

void set_clock(void)

{

uint8 k_val, flag=0;

Num = 0;

while (1)

{

k_val = scan_key();

if (k_val == 0)

{

if (flag == 0)

{

start_flash();

flag = 1;

}

continue;

}

flag = 0;

stop_flash();

if (k_val == K_ENTER)

{

set_time(Time);

break;

}

switch (k_val)

{

case K_ADD:

if (Num == 2)

{

if (Time[Num] >= 23)

Time[Num] = 0;

else

Time[Num]++;

}

else

{

if (Time[Num] >= 59)

Time[Num] = 0;

else

Time[Num]++;

}

break;

case K_SUB:

if (Num == 2)

{

if (Time[Num] == 0)

Time[Num] = 23;

else

Time[Num]--;

}

else

{

if (Time[Num] == 0)

Time[Num] = 59;

else

Time[Num]--;

}

break;

case K_LEFT:

if (Num >= 2)

Num = 0;

else

Num++;

break;

case K_RIGHT:

if (Num == 0)

Num = 2;

else

Num--;

break;

default: break;

}

make_led_number();

}

}

/* * 数码管显示*/

void show_num(uint8 *buf)

{

ENLED = 1;

switch (Led_n)

{

case 0:

ADDR0 = 0;

ADDR1 = 0;

ADDR2 = 0;

P0 = buf[0];

break;

case 1:

ADDR0 = 1;

ADDR1 = 0;

ADDR2 = 0;

P0 = buf[1];

break;

case 2:

ADDR0 = 0;

ADDR1 = 1;

ADDR2 = 0;

P0 = buf[2];

break;

case 3:

ADDR0 = 1;

ADDR1 = 1;

ADDR2 = 0;

P0 = buf[3];

break;

case 4:

ADDR0 = 0;

ADDR1 = 0;

ADDR2 = 1;

P0 = buf[4];

break;

case 5:

ADDR0 = 1;

ADDR1 = 0;

ADDR2 = 1;

P0 = buf[5];

break;

}

ENLED = 0;

if (Led_n >= 5)

Led_n = 0;

else

Led_n++;

}

main()

{

uint8 k_val;

ADDR3 = 1;

ENLED = 0;

systimer_init();

set_time(Time); //初始时间设定

TR0 = 1;

while (1)

{

read_time(Time);

make_led_number();

k_val = scan_key();

if (k_val == K_SET)

set_clock();

}

}

void time0_isr() interrupt 1

{

ET0 = 0;

TH0 = 0xF8;

TL0 = 0xCC;

show_num(Led_buf);

ET0 = 1;

}

void time1_isr() interrupt 3

{

ET1 = 0;

TH1 = 0xDC; // 定时10ms

TL1 = 0x00;

T_n++;

if (T_n == 50) // 0.5s

{

Led_buf[2*Num] = 0x7F & Ledcode[10];

Led_buf[2*Num+1] = Ledcode[10];

}

else if (T_n >= 100) // 1s

{

T_n = 0;

Led_buf[2*Num] = 0x7F & Ledcode[Time[Num]%10];

Led_buf[2*Num+1] = Ledcode[Time[Num]/10];

}

ET1 = 1;

}

以上所述仅为本发明专利的较佳实施例而已,并不用以限制本发明专利,凡在本发明专利的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明专利的保护范围之内。

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值