基于51单片机做的可调时钟,适合新手操作,有详细代码注释

基于51单片机做的可调时钟,适合新手操作,有详细代码注释

1. 最左边两个数码管是显示“时”,中间两个和右边两个分别是“分”“秒”
2. 左边的按钮是调时的,右边的按钮是调分的,每按一下就会加一
3.每次启动单片机就是从00:00:00开始的

现在显示的时间是7:09:15
在这里插入图片描述
细节描述:
1.时钟的计时功能是用了51单片机的定时器模式2:8位自动装载模式,其定时时间为(以定时器0为例):
T=(256-T0初值)X机器周期=(256-T0初值)X振荡周期X12

2. 调时调分功能分别是用了外部中断1和外部中断0

代码块

#include "reg52.h" 
typedef unsigned char uchar;
typedef unsigned int uint;

void delay(uint z);		//延时
void write_address(uchar address);		//选择数码管
void write_data(uint n);	//选择显示的内容
void flicker();			//主要显示函数

uint date[7]={0,0,0,0,0,0,0};	//为了便于编程,忽略掉date[0],只使用date[1]~date[6]
uint n=0;		//计数,计定时器中断的次数
uint second1=0,minute1=0,hour1=0;		//用于flicker函数

uchar TIMECODE[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x00};		//字形码表
uchar WEICODE[7]={~0,~0x01,~0x02,~0x04,~0x08,
~0x10,~0x20};					//选中数码管表
 
void main()
{
	TMOD=0x02;	//把定时器模式设为模式2
	TH0=0x56;	//设置初值
	TL0=0x56;	//设置初值
	TR0=1;		//启动定时器
	EA=1;		//打开总中断开关
	ET0=1;		//打开定时器中断允许位

	EX0=1;		//打开外部中断0
	IT0=1;		//设置外部中断0的模式是下降沿触发

	EX1=1;		//打开外部中断1
	IT1=1;		//设置外部中断1的模式是下降沿触发

	while(1)
	{
		flicker();
	}
}

void delay(uint z)//z等于1,就是延时1ms
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=114;y>0;y--)
		;
}

void write_address(uchar address)//显示数码管
{
	P2=address;

}

void  write_data(uint n)//显示数据
{
	
	P0=TIMECODE[n];
	
}

void flicker()//使数码管动态显示
{	
	write_address(WEICODE[1]);//最左边数码管亮
	write_data(date[1]);	//date[1]的值就是最左边数码管显示的值
	delay(1);//延时	 
	P0=~0xff;//消影			  

	write_address(WEICODE[2]);//同上理
	write_data(date[2]);
	delay(1);
	P0=~0xff;	

	write_address(WEICODE[3]);
	write_data(date[3]);
	
	delay(1);
	P0=~0xff;
	write_address(WEICODE[4]);
	write_data(date[4]);
	
	delay(1);
	P0=~0xff;
	write_address(WEICODE[5]);
	write_data(date[5]);

	delay(1);
	P0=~0xff;	
	write_address(WEICODE[6]);
	write_data(date[6]);
	delay(1);
	P0=~0xff;
}

void serve()interrupt 1//定时器中断响应
{
	 n++;										        
	 if(n==5000)		//当n=5000时,表示过了1s
	 {	 
	     n=0;					                        
	     second1++;
		 if(second1==60)
		 {
		     second1=0;
		     minute1++;
			 if(minute1==60)
			 {
			     minute1=0;
				 hour1++;
				 if(hour1==24)
				 {	    
				    hour1=0;
				 }
			 }
		 }
		 date[6]=second1%10;
		 date[5]=second1/10;
		 date[4]=minute1%10;
		 date[3]=minute1/10;
		 date[2]=hour1%10;
		 date[1]=hour1/10;
	
	 }

}

void tiaofen() interrupt 0//外部中断,按键调分响应
{	
	minute1++;
	if(minute1==60)
		minute1=0;
		
}

void tiaoshi() interrupt 2//外部中断,按键调时响应
{
	hour1++;
	if(hour1==24)
		hour1=0;
}		

新人博客,要是觉得有用给个赞呗嘻嘻

  • 87
    点赞
  • 328
    收藏
    觉得还不错? 一键收藏
  • 44
    评论
以下是一个基于C语言的51单片机数字电子时钟代码,使用了DS1302实时时钟模块: ``` #include<reg52.h> #include<intrins.h> #include<DS1302.h> #define uchar unsigned char #define uint unsigned int uchar code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//共阴数码管0-9的编码 sbit DSPORT=P3^4; //DS1302数据总线 sbit RST=P3^5; //DS1302复位信号 sbit SCLK=P3^6; //DS1302时钟信号 void main() { uchar sec,min,hour; uchar num[8]; uchar i; while(1) { sec=DS1302_Read(0x81); //读取秒 min=DS1302_Read(0x83); //读取分 hour=DS1302_Read(0x85); //读取时 num[0]=hour/10; //十位小时 num[1]=hour%10; //个位小时 num[2]=10; //冒号 num[3]=min/10; //十位分钟 num[4]=min%10; //个位分钟 num[5]=10; //冒号 num[6]=sec/10; //十位秒钟 num[7]=sec%10; //个位秒钟 for(i=0;i<8;i++) { P0=table[num[i]]; //将数码管编码写入P0口 switch(i) //选择对应的数码管 { case 0: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 1: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 2: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 3: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 4: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 5: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 6: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; case 7: DSPORT=1; RST=0; _nop_(); _nop_(); RST=1; break; default: break; } _nop_(); _nop_(); P0=0x00; //清空P0口 } delay(1000); //延时1秒钟 } } ``` 这个代码使用了DS1302实时时钟模块来获取当前时间,然后将时间转换为数码管的编码,并通过P0口输出。在循环中,首先读取当前的小时、分钟和秒钟,然后将这些数字转换为数码管的编码。接着,依次将编码输出到对应的数码管上,并延时1秒钟。注意,这个代码中使用了DS1302库文件,需要提前下载并引用。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值