首页 > 编程知识 正文

51单片机可调时钟程序(51单片机数字钟设计程序)

时间:2023-05-06 17:47:51 阅读:83463 作者:4183

在前一节中,单片机的定时器/计数器共享实现数字管道动态更新的程序代码,在本节中,利用定时器/计数器以及外部中断实现简单的电子表功能。 相应的视频课程实现了单片机应用实践篇的计时器/计数器可以按钮的电子表。 视频链接: https://www.I xigua.com/6840071457402257928。 在此重新整理视频课程的程序代码,按照模块化进行简单的处理,然后选择main.c、display.c、display.h、time.c、time.h、exit.c、exit . 这个按键可调的电子表功能比较简单,主要是为了向初次学习单片机的学生介绍综合应用实例,同时也要考虑状态机的编程思路和程序的框架处理。 当然,程序有很多需要改进和优化的地方。 在这里,我们使用4位的数字管道进行程序的功能演示,但是如果你要制作实物的话,请考虑使用时钟专用的数字管道。 另外,为了显示程序的效果,现在的界面没有显示,时间为分:秒。 大家可以根据自己的需要,设计和修改合适的接口。 只要在该代码上适当添加小算法代码,就可以实现年历的功能,如果有网友想实现年历的功能代码,可以留言,也可以稍后共享以前调试的代码。 不用说,代码会汹涌而来。

//主. c

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

程序功能:可按键调整电子表的设计

4位数字管显示部分:秒(可根据需要调整显示界面) ) )。

KEY1外部中断0状态切换

KEY2外部中断1参数调整

产生时间基准计时器0

数码管动态刷新计时器1

* * * *

# #包括re g51.h

# #包括'显示. h '

# #包括时间h '

# #包括'退出. h ' '

void showNormal (;

void showSec (;

void showMin (;

void showHour (;

//状态变量

无符号状态=0;

void主() )

{

EX0_Init (;

EX1_Init (;

Timer1Init (;

Timer0Init (;

EA=1;

while(1) )。

{

是开关(state )

{

case 0:TR0=1; showNormal (; 布莱克; //通常的时钟状态

case 1:showSec (; 布莱克; //秒一致

case 2:showMin (; 布莱克; //对准重点

case 3:显示之家(; 布莱克; //调时

默认:中断;

}

}

}

//普通时钟显示界面

void showNormal (

{

led buf=最小/10;

led buf=最小;

led buf [2]=秒/10;

led buf=秒;

}

//秒调节显示接口

void showSec (

{

LEDBuf[0]=23; //关闭

LEDBuf[1]=23; //关闭

led buf [2]=秒/10;

led buf=秒;

}

//调分显示画面

声音显示() )

{

led buf=最小/10;

led buf=最小;

LEDBuf[2]=23; //关闭

LEDBuf[3]=23; //关闭

}

//调整时显示画面

void showHour ()

{

led buf=hour/10;

led buf=hour;

LEDBuf[2]=23; //关闭

LEDBuf[3]=23; //关闭

}

//时间. c

# #包括时间h '

# #包括'显示. h '

//全局变量的定义

无符号字符计时器CNT;

无符号字符序列;

无符号字符民;

无符号字符孔;

语音时间r0初始化(语音)/50毫秒@12.000MHz

{

TMOD=0xF0; //设定计时器模式

TMOD |=0x01; //设定计时器模式

TL0=0xB0; //设定计时器初始值

TH0=0x3C; //设定计时器初始值

TF0=0; 清除//TF0标志

ET0=1;

}

语音时间R1初始化(语音)/1毫秒@12.000MHz

{

TMOD=0x0F; //设定计时器模式

TMOD |=0x10; //设定计时器模式

TL1=0x18; //设定计时器初始值

TH1=0xFC; //设定计时器初始值

TF1=0; 清除//TF1标志

ET1=1;

TR1=1; //计时器1开始计数

}

/* * * *

******************* 1、中断服务函数一定是一个没有返回值的函数 2、中断服务函数一定是没有参数的函数 3、中断服务函数函数名后跟关键字 interrupt 4、interrupt n 0 - 4 5个中断源 8*n + 0003H 0003H INT0 000BH T0 0013H INT1 001BH T1 0023H ES 5、中断服务函数不能被主程序或其他程序所调用 6、 n 后面 跟 using m (0 - 3 )工作寄存器组 ***************************************/ void timer0_ISR(void) interrupt 1 { timerCnt++; if(timerCnt >= 20)//20次50ms中断,即1S时间到 { timerCnt = 0; sec++; if(sec >= 60) { sec = 0; min++; if(min >= 60) { min = 0; hour++; if(hour >= 24) { hour = 0; } } } } TL0 = 0xB0; //设置定时初值 TH0 = 0x3C; //设置定时初值 } void timer1_ISR(void) interrupt 3 { TR1 = 0; Display(); TL1 = 0x18; //设置定时初值 TH1 = 0xFC; //设置定时初值 TR1 = 1; } //time.h #ifndef __TIME_H__ #define __TIME_H__ #include <reg51.h> extern unsigned char sec; extern unsigned char min; extern unsigned char hour; void Timer0Init(void); void Timer1Init(void); #endif//exti.c #include "exit.h" #include "time.h" //外部变量声明 extern unsigned char state; void EX0_Init() { IT0 = 1; EX0 = 1; } void EX1_Init() { IT1 = 1; EX1 = 1; } void EX0_ISR() interrupt 0 { TR0 = 0; state++; if(state >3 ) state = 0; } void EX1_ISR() interrupt 2 { switch(state) { case 0:break; case 1:sec++;if(sec >= 60) sec = 0;break; case 2:min++;if(min >= 60) min = 0;break; case 3:hour++;if(hour >= 24) hour = 0;break; default:break; } }//exti.h #ifndef __EXIT_H__ #define __EXIT_H__ #include <reg51.h> void EX0_Init(); void EX1_Init(); #endif//display.c #include "display.h" unsigned char code leddata[]={ //数码管的段码表 0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F, //"9" 0x77, //"A" 0x7C, //"B" 0x39, //"C" 0x5E, //"D" 0x79, //"E" 0x71, //"F" 0x76, //"H" 0x38, //"L" 0x37, //"n" 0x3E, //"u" 0x73, //"P" 0x5C, //"o" 0x40, //"-" 0x00, //熄灭 }; unsigned char LEDBuf[] = {22,22,22,22};//数据显示缓冲区 unsigned char code PLACE_CODE[] = {0xfe,0xfd,0xfb,0xf7};//位选信号 void Display() { static unsigned char i = 0; //1、送段码 //2、送位选 //3、延时 //4、消隐 switch(i) { case 0: GPIO_DIG = 0x00; GPIO_DIG = leddata[LEDBuf[0]]; GPIO_PLACE = PLACE_CODE[0]; i++; break; case 1: GPIO_DIG = 0x00; GPIO_DIG = leddata[LEDBuf[1]]; GPIO_PLACE = PLACE_CODE[1]; i++; break; case 2: GPIO_DIG = 0x00; GPIO_DIG = leddata[LEDBuf[2]]; GPIO_PLACE = PLACE_CODE[2]; i++; break; case 3: GPIO_DIG = 0x00; GPIO_DIG = leddata[LEDBuf[3]]; GPIO_PLACE = PLACE_CODE[3]; i = 0; break; default:break; } }//display.h #ifndef __DISPLAY_H__ #define __DISPLAY_H__ #include <reg51.h> //IO的声明 #define GPIO_DIG P0 //段码 IO #define GPIO_PLACE P2 //位选 IO #define N 4 //数码管个数 unsigned char code leddata[]; extern unsigned char LEDBuf[]; void Display(); #endif

执行代码后,通过Proteus仿真的显示界面如下:

正常时钟显示界面(分钟:秒)

调秒显示界面

调分显示界面

调时显示界面

程序代码仅供初学的同学参考学习,代码可以根据自己的风格进行相应的优化处理,仅供参考。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。