利用单片机定时器制作数字时钟

供稿:hz-xin.com     日期:2025-01-14
利用单片机的定时器和数码管,设计一个电子时钟

给你个电路和程序,//前几天帮一个网友写,单片机定时时钟在调节功能,可以参考一下我程序

/***************************************************
* 6位数码管显示电子钟
*
* 功能: 按键加,按键减, 按键,启动和停止。
*
*
***************************************************/
#include "REG52.H"

sbit SHUG_01 = P2^0; //数码管1
sbit SHUG_02 = P2^1; //数码管2
sbit SHUG_03 = P2^2; //数码管3
sbit SHUG_04 = P2^3; //数码管4
sbit SHUG_05 = P2^4; //数码管5
sbit SHUG_06 = P2^5; //数码管6
sbit KEY0_01 = P0^0; //按键 启动或停止sbit KEY0_02 = P0^1; //按键 加
sbit KEY0_03 = P0^2; //按键减
sbit KEY0_04 = P0^3; //按键菜单
#define LED_DATA P1 //P1数据端口
unsigned char value_temp = 0;unsigned char value_Outk = 0;
unsigned char value_shio = 8;
unsigned char value_feno = 40;
unsigned char value_miao = 0;
unsigned char code value_tab0[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //共阳极unsigned char code value_tab1[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //共阳极带点

/*
* 延时1ms延时子函数
**/
void Delay_1ms(unsigned int Time)
{
unsigned int x, y;
for(x = Time; x > 0; x--)
for(y = 120; y > 0; y--);
}
/* * 程序运行【启动和停止】子函数
**/
void Disp_layledketCmd(void)
{
/***小时***/
SHUG_01 = 1;
LED_DATA = value_tab0[value_shio / 10]; /*******小时的十位数显示***************/
Delay_1ms(5);
SHUG_01 = 0;
SHUG_02 = 1;
LED_DATA = value_tab1[value_shio % 10]; /*******小时的个位数显示***************/
Delay_1ms(5);
SHUG_02 = 0;
/***分钟***/ SHUG_03 = 1;
LED_DATA = value_tab0[value_feno / 10]; /*******分钟的十位数显示***************/
Delay_1ms(5);
SHUG_03 = 0;
SHUG_04 = 1;
LED_DATA = value_tab1[value_feno % 10]; /*******分钟的个位数显示***************/
Delay_1ms(5);
SHUG_04 = 0;
/***秒钟***/ SHUG_05 = 1;
LED_DATA = value_tab0[value_miao / 10]; /*******秒钟的十位数显示***************/
Delay_1ms(5);
SHUG_05 = 0;
SHUG_06 = 1;
LED_DATA = value_tab0[value_miao % 10]; /*******秒钟的个位数显示***************/
Delay_1ms(5);
SHUG_06 = 0;
}
/* * 定时器初始化定时50ms
**/
void Tero_Init(void)
{
TMOD = 0x01;
TH0 = 0x4C;
TL0 = 0x00;
ET0 = 1;
TR0 = 1;
EA = 1;
}
/* * 按键开关【启动和停止】子函数
**/
void Scan_keyoutCmd(void)
{
if(KEY0_01 == 0)
{
Delay_1ms(10);
if(KEY0_01 == 0)
{
TR0 = ~ TR0;
}
while(KEY0_01 == 0);
}
if(KEY0_02 == 0) {
Delay_1ms(10);
if(KEY0_02 == 0)
{
value_miao--;
if(value_miao == -1)
{
value_feno--;
value_miao = 59;
if(value_feno == -1)
{
value_shio--;
value_feno = 59;
if(value_shio == -1)
{
value_shio = 23;
}
}
}
while(KEY0_02 == 0);
}
}
if(KEY0_03 == 0) {
Delay_1ms(10);
if(KEY0_03 == 0)
{
value_miao++;
if(value_miao == 60)
{
value_miao = 0;
value_feno++;
if(value_feno == 60)
{
value_feno = 0;
value_shio++;
if(value_shio == 24)
{
value_shio = 0;
}
}
}
while(KEY0_03 == 0); //检测松手
}
}
}
/* * 函数主体
**/
int main(void)
{
P1 = P2 = P3 = 0x00;
Tero_Init();

while(1)
{
Scan_keyoutCmd();
Disp_layledketCmd(); //执行应运程序
}
}
/* * 定时器中断服务程序
**/
void Tmero()interrupt 1
{
TH0 = 0x4C;
TL0 = 0x00;
value_temp++;
if(value_temp == 20)
{
value_temp = 0;
value_miao++;
if(value_miao == 60)
{
value_feno++;
value_miao = 0;
if(value_feno == 60)
{
value_shio++;
value_feno = 0;
if(value_shio == 24)
{
value_shio = 0;
}
}
} }
}

相关资料: 多功能数字钟设计 一 简介 时钟, 自从它发明的那天起,就成为人类的朋友,但随着时间的推移,人们对它的功能又提出了新的要求,怎样让时钟更好的为人民服务,怎样让我们的老朋友焕发青春呢?这就要求人们不断设计出新型时钟。本方案设计的多功能电子钟除了传统的显示时间功能之外还可以测试温度、电网频率、电压、并提供了过压报警、非接触止闹等功能。其中温度采用AD590温度传感器电路测得,非接触止闹则采用红外控制技术实现。 二 方案论证 时钟模块方案 方案一 基本门电路搭建 用基本门电路来实现数字钟,电路结构复杂,故障系数大,不易调试。 方案二 单片机编程 用单片机设计电路,由于使用软硬件结合的方式,所以电路结构简单、调试也相对方便。与第一种方案比较优点是非常明显的。我们选择了第二种方案 测温模块方案 方案一 热电阻测温 热电阻测量温度,精度和灵敏度都可以,但是它的电阻值与温度的线性关系不好.不便用数字的方法处理。 方案二 热电偶测温 热电偶是温度测量中应用最广泛的一种传感器 .在一般的测量和控制中,常用于中高温的温度检测.在 测量中需要温度的冷端补偿,在数字电子中实现不方便 方案三 AD590加运算放大器 二端式半导体温度传感器 AD590的工作电压要求不高,测温的范围比较宽最重要的是它的输出电流是紧随温度变化的电流源,所以它的线性非常好.我们选择了这种方案。 测电压模块方案 方案一 取样测试。用高速的取样电压取样,可得电压的峰值与主频率,并根据其电压大小进行相应的报警操作。此方案功能实现复杂,造价相对较高,不适合一般的家用。 方案二 测得电压有效值 测电压的有效值的方法比较简单,可以把一段时间内的电压的整体情况反映出来 ,但不能测出电压的瞬时变化的情况,对电网的突然冲击不能测出. 方案三 测得峰值推得有效值。交流电经过整流滤波后得到直流电压大小就是交流电的峰值,分压测出此电压大小,后根据交流电有效值和峰值的关系可推得有效值。这种方案采用的电路简单,实现方便,易于调试,精度较高, 为我们的设计采用。 非接触止闹模块方案 方案一 声音止闹 声音代替肢体给人带来了很大便利,但是要采用声控装置不得不考虑外界噪声对正常声音信号带来的干扰,而这一点又很难控制,因此虽然声控方便,但在这里不太适用所以割舍。 方案二 红外止闹 红外控制技术现在已被广泛地应用到各个领域,此技术有其独特的特点,首先操作方便抗干扰性好、探测灵敏度高、工作湿度范围宽设计电路有不太复杂,造价也不高,由于这些特点我们选用了红外遥控来止闹。 显示模块方案 方案一 段码显示。段码显示需要专门的驱动,增大了硬件电路,调试不易。而且用段码表示不够直观,因此不采用这种方案 方案二 单片机控制液晶显示。控制部分集成在单片机内软件调试,硬件集成度大,为本方案所采用。 综上所述得到以下方块图: 三 各模块功能 单片机控制显示部分:液晶显示片上显示时间、电压、温度,键盘控制,键盘如下图所示: 调节 ↑ 闹铃 ↓ 闹铃键用来设置闹铃,闹铃响时按下闹铃键可用来止闹,平时闹铃键可用来设置闹铃的开关,闹铃关时按下此键闹铃功能将被打开,反之闹铃功能将被关闭。需要调节时间时,按动调节按钮,显示片上需要设置的时间值以闪烁的方式出现,以示区别,表示当前调节内容,再次按动,跳至下个需要设置的时间值,我们可以通过切换选择我们需要调整的时间部分,然后按“上”“下”按钮进行设定。其中时钟部分以二十四或十二小时(AM/PM)制显示。 此外单片机还控制温度和电压的测量,通过测温端和测电压端输出的电压,由相应的函数关系求得被测端的被测参数,然后显示在液晶显示屏上. 测温部分 原理方块图: 温度检测电路的设计,电路图如下: 测温元件使用温度传感器AD590。A/D590在0℃时输出的电流I=273 uA,温度T每增加1℃,I增加1u A。输出的电压变化为: Δv=1uA×R2 系统要求电压变化范围在0—5伏,可解得R2<62.5K,设计中R2采用了52K的电阻。 当温度为-10摄氏度时,要
求采纳为满意回答。

下面是时间程序,直接下来用就行了.
/*******************************************************************************

********************************************************************************
* 描述: *
* 简易电子时钟,LED数码管显示 *
* K1---时调整 *
* K2---分调整 *
* *
* 上电时初始化显示: 12-00-00 *
* *
* * **** **** **** **** **** *
* * * * * * * * * * * *
* * * * * * * * * * * *
* * **** ****** * * * * ****** * * * * *
* * * * * * * * * * * *
* * * * * * * * * * * *
* * **** **** **** **** **** *
* *
* *

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

#include <reg51.h>
#include <intrins.h>

unsigned char data dis_digit;
unsigned char key_s, key_v;

unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
unsigned char data dis_buf[8];
unsigned char data dis_index;
unsigned char hour,min,sec;
unsigned char sec100;

sbit K1 = P3^2;
sbit K2 = P3^3;

bit scan_key();
void proc_key();
void inc_sec();
void inc_min();
void inc_hour();
void display();
void delayms(unsigned char ms);

void main(void)
{
P0 = 0xff;
P2 = 0xff;
TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式
TH1 = 0xdc;
TL1 = 0;

TH0 = 0xFC;
TL0 = 0x17;

hour = 12;
min = 00;
sec = 00;

sec100 = 0;

dis_buf[0] = dis_code[hour / 10]; // 时十位
dis_buf[1] = dis_code[hour % 10]; // 时个位
dis_buf[3] = dis_code[min / 10]; // 分十位
dis_buf[4] = dis_code[min % 10]; // 分个位
dis_buf[6] = dis_code[sec / 10]; // 秒十位
dis_buf[7] = dis_code[sec % 10]; // 秒个位
dis_buf[2] = 0xbf; // 显示"-"
dis_buf[5] = 0xbf; // 显示"-"

dis_digit = 0xfe;
dis_index = 0;

TCON = 0x01;
IE = 0x8a; // 使能timer0,1 中断

TR0 = 1;
TR1 = 1;

key_v = 0x03;

while(1)
{
if(scan_key())
{
delayms(10);
if(scan_key())
{
key_v = key_s;
proc_key();
}
}

}
}

bit scan_key()
{
key_s = 0x00;
key_s |= K2;
key_s <<= 1;
key_s |= K1;
return(key_s ^ key_v);
}

void proc_key()
{
EA = 0;
if((key_v & 0x01) == 0) // K1
{
inc_hour();
}
else if((key_v & 0x02) == 0) // K2
{
min++;
if(min > 59)
{
min = 0;
}
dis_buf[3] = dis_code[min / 10]; // 分十位
dis_buf[4] = dis_code[min % 10]; // 分个位
}

EA = 1;
}

void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
// 选通P2.0口数码
// dis_buf --- 显于缓冲区基地址
{
TH0 = 0xFC;
TL0 = 0x17;

P2 = 0xff; // 先关闭所有数码管
P0 = dis_buf[dis_index]; // 显示代码传送到P0口
P2 = dis_digit; //

dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管
dis_index++; //

dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}

void timer1() interrupt 3
{
TH1 = 0xdc;

sec100++;

if(sec100 >= 100)
{
sec100 = 0;
inc_sec();
}
}

void inc_sec()
{
sec++;
if(sec > 59)
{
sec = 0;
inc_min();
}
dis_buf[6] = dis_code[sec / 10]; // 秒十位
dis_buf[7] = dis_code[sec % 10]; // 秒个位
}

void inc_min()
{
min++;
if(min > 59)
{
min = 0;
inc_hour();
}
dis_buf[3] = dis_code[min / 10]; // 分十位
dis_buf[4] = dis_code[min % 10]; // 分个位
}

void inc_hour()
{
hour++;
if(hour > 23)
{
hour = 0;
}
if(hour > 9)
dis_buf[0] = dis_code[hour / 10]; // 时十位
else
dis_buf[0] = 0xff; // 当小时的十位为0时不显示
dis_buf[1] = dis_code[hour % 10]; // 时个位

}

void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}

定时器其实就是单片机的一个内部自身时钟的计数器,每一个周期计数器加1,所以使用定时器功能时候先要给定时器付初值,就是先写th0tl0的值(如下),写完初值后就等着定时器功能的那个计数器记满了数后也就是到了65536后就溢出了,所以一次定时的过程就是65536-初值
之间的数
所代表的时钟周期,计数满了溢出要产生中断就要写一个中断服务子程序,子程序如下void
timer0()
interrrupt
x
中断服务子程序中还要给定时器计数器的th
tl付初值
进行下一次的计数,明白了吧。。楼上的那个没写interrupt
选择定时器工作方式。哎呀,妈呀
累死我了
void
main()
{
th0=(65536-50000)/256;
tl0=(65536-50000)%256;//定时器0初值,定时50ms
定时多少ms就多少*1000
ea=1;//开启总中断
et0=1;//定时器0中断允许
tr0=1;//开启定时器0
while(1)
{
}
}
void
timer0()
interrrupt
1
{
th0=(65536-50000)/256;
tl0=(65536-50000)%256;
}

不知道你用的那款单片机啊。
我本科毕业设计用的是飞思卡尔的08系列芯片,做的电子万年历。
如果用c语言的话比较简单,我当时加了一块时钟芯片,用的IIC与GP32通信的,比较方便,直接读时间就可以了,也比较精确,电路啥的电脑好像还有。

你用什么单片机的
我这有AVR的和430的
都是成功的程序
如果你需要就说声
gao_deqiang@163.com

找我,我有。。。

利用单片机定时器制作数字时钟
下面是时间程序,直接下来用就行了.\/ 描述:简易电子时钟,LED数码管显示 K1---时调整 K2---分调整 上电时初始化显示: 12-00-00 \/ include <reg51.h> include <intrins.h> unsigned char data dis_digit;unsigned char key_s, key_v;unsigned char code dis_code[11]={0xc0,0xf9,0xa4...

利用单片机的定时器和数码管,设计一个电子时钟
给你个电路和程序,\/\/前几天帮一个网友写,单片机定时时钟在调节功能,可以参考一下我程序 \/ 6位数码管显示电子钟 功能: 按键加,按键减, 按键,启动和停止。\/ include "REG52.H"sbit SHUG_01 = P2^0; \/\/数码管1 sbit SHUG_02 = P2^1; \/\/数码管2 sbit SHUG_03 = P2^2; ...

1、设计一个简易时钟(时间由定时器中断控制)在数码管上显示,显示_百度...
1、设计一个简易时钟(时间由定时器中断控制)在数码管上显示,显示初始状态为00-00-00,分别为小时,分钟,秒。并实现以下功能:1自主设置时间:单片机上电后,进入自主设置初始化时间模块,此时由矩阵键盘设置具体数值;按下独立键盘K1后设置成功,时钟开始工作。2闹钟:5秒后,蜂鸣器响(此时,时钟可暂停工作),按下独立键盘K2...

设计电子时钟 要用AT89S51单片机的定时器实现,用4位数码管显示,用点的...
unsigned int timer1_times;unsigned int timer0_times_AA; \/\/按纽AA用 unsigned int timer0_times_BB; \/\/按纽BB用 unsigned int timer0_times_CC; \/\/ 半秒计时用 unsigned int timer0_times_DD; \/\/四分之一秒用 unsigned int timer0_times_EE; \/\/ 闹钟用 typedef struct{ unsign...

51单片机做数字电子钟
数字电子钟是以1s为最小定时单位的,51单片机自身具有两个16位定时\/计数器,当晶振频率为6MHz时,最大定时时间为0.13s。而具有时、分和秒的数字电子钟只能以1s定时,所以要实现实现1s定时,必须采用软件计数和定时器定时相结合的方法。每1s定时到,修改显示值,送6位LED显示。本课题需用6个LED数码管显示时间值,并且...

51单片机多功能LED点阵显示数字时钟
这款数字时钟程序在PROTUES上运行良好,你可以自行在PROTUES上进行电路设计。程序使用了51单片机,通过P2.5,P2.6两个端口控制数码管显示,P1.0至P1.7端口分别用于控制按钮1至按钮8的状态检测。程序通过定时器0实现秒级计时功能,每0.256秒更新一次显示数据,确保时间显示的准确性。在主函数中,首先...

采用定时器,设计制作一个时钟,用六位数码管显示时间,用三个按键可以调整...
用51单片机的定时器,设计一个时钟,用8位一体共阴数码管显示时间时分秒,用三个按键可以调整时间。可用proteus仿真实现,仿真图如下。

基于51单片机简易时钟闹钟八位数码管显示Proteus仿真
本设计旨在实现一个基于51单片机的多功能数字时钟闹钟,其主要功能包括显示时、分、秒,并能设置时间和闹钟。该设计采用单片机内部定时器实现计时功能,通过八位数码管显示当前时间。用户可以对时、分、秒进行独立设置,设置时数码管将闪烁。此外,闹钟功能可让用户设置特定时间,当时间到达,蜂鸣器将每秒鸣响...

用单片机设计一个时钟,可显示时和分,可以调时间,也要有闹钟功能,要有设...
unsigned char z,s=00,m=00,h=00;给时钟初始值 while(1){ for(z=0;z<100;z++){ tmp=0x01;P2=tab[h\/10];小时显示 disp();P2=tab[h%10];disp();P2=tab[m\/10];分钟显示 disp();P2=tab[m%10];disp();P2=tab[s\/10];秒显示 disp();P2=tab[s%10];disp();} s++;while...

基于AT89C51 单片机数字时钟如何设计?
通过 Protues 8.7 软件,我们实现了精细的仿真设计,让设计过程可视化。同时,使用KEIL5编写并优化的程序保证了时钟功能的准确无误,主函数代码如下:void main() { TMOD = 0x01; \/\/ 定时器工作模式1 TH0 = (65536 - 50000) \/ 256; TL0 = (65536 - 50000) % 256; \/\/ 定时50...