单片机实现时钟闹钟

之前做了一个单片机课设,用51单片机实现时钟闹钟,程序比较简单,思路也有很多种,放上我的代码供大家参考。
按键功能说明:
矩阵键盘:
第1到第10个按键分别对应数字0-9;
独立按键:
Key1短按切换模式,长按时钟暂停;
Key2按下则进行时钟和闹钟的设置;
Key3短按确认输入时间,长按清零。
(开发板上Key4故障,大家也可以把长按或短按功能设为Key4)

#include<reg52.h> 
#include<intrins.h> 
#define uchar unsigned char 
#define uint unsigned int 
sbit key1=P3^0;//按键
sbit key2=P3^1; 
sbit key3=P3^2; 
sbit key4=P3^3;
sbit buffer=P2^3;//蜂鸣器
sbit DU =P2^6;//段选
sbit WE =P2^7;//位选
uchar bitdata[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数码管1-8
uchar segdata[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//段选0-9,-
uchar dis_arr[]={10,10,10,10,10,10};//时钟显示数组
uchar time[]={0,0,0};//时钟 时分秒
uchar time_In[]={0,0,0,0,0,0};
uchar time_clk[]={0,0,0};//闹钟 时分秒
uchar num=0;
uchar mode=0;
uchar keydown=0;
uchar clk_state=0;
uchar keyIn,keyvalue,i,temp;//矩阵键盘读入
void key();
void init();
uchar keyscan();//矩阵键盘扫描函数
void delayms(uint x);//延时函数
void display(uchar duan1,uchar duan2,uchar duan3,uchar duan4,uchar duan5,uchar duan6);
void display_1(uchar wei,uchar duan);
void input();
void soundTime();
void main()
{	
	input();
	init();
	while(1)
	{	
		key();
		
		if(mode==0)//时钟
		    display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);
		else if(mode==1)//闹钟
			display(time_clk[0]/10,time_clk[0]%10,time_clk[1]/10,time_clk[1]%10,time_clk[2]/10,time_clk[2]%10);		
	}
}
void init()//初始化函数
{	
	P3=0xff;//给高电平
	TMOD=0x01;//定时器工作方式选择1
	TH0=(65536-45872)/256;
	TL0=(65536-45872)%256;
	EA=1; //开总中断
	ET0=1;//允许定时器0中断
	TR0=1;//开始计数
	//P1=1;
}
void delayms(uint x)//延时函数
{
    uint i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}
void key()
{
	while(key2==0)
	{
		input();
		break;
	}
	if(key1==0)
	{	
		delayms(200);
		if(key1==0)
		//{while(!key1){TR0=0;display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}TR0=1;}
		{TR0=!TR0;while(!key1)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}
		//else if(TR0==0)TR0=1;}
		else if(key1==1)
		{mode++;if(mode==2)mode=0;}
	}
	if(key3==0)
	{
		delayms(200);
		if(key3==0)
		{if(mode==0){time[0]=0;time[1]=0;time[2]=0;num=0;
		while(!key3)display(time[0]/10,time[0]%10,time[1]/10,time[1]%10,time[2]/10,time[2]%10);}
		else if(mode==1){time_clk[0]=0;time_clk[1]=0;time_clk[2]=0;
		while(!key3)display(time_clk[0]/10,time_clk[0]%10,time_clk[1]/10,time_clk[1]%10,time_clk[2]/10,time_clk[2]%10);}}
		else if(key3==1)
			{buffer=1;/*P1=1;*/}	
	} 
}		
uchar keyscan()//矩阵键盘扫描函数
{
	keyvalue=99;
	P3=0xfe;
	temp=P3;					  
	temp=temp&0xf0;//判断是否还等于0xf0
	while(temp!=0xf0)
	{
		delayms(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
			switch(temp)
			{
				case 0xee:{keyvalue=0;keydown=1;break;}
				case 0xde:{keyvalue=1;keydown=1;break;}
				case 0xbe:{keyvalue=2;keydown=1;break;}
				case 0x7e:{keyvalue=3;keydown=1;break;}
			}
			while(temp!=0xf0)
			{
				temp=P3;
				temp=temp&0xf0;
			}
		}
	}
	P3=0xfd;
	temp=P3;					  
	temp=temp&0xf0;//判断是否还等于0xf0
	while(temp!=0xf0)
	{
		delayms(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
			switch(temp)
			{
				case 0xed:{keyvalue=4;keydown=1;break;}
				case 0xdd:{keyvalue=5;keydown=1;break;}
				case 0xbd:{keyvalue=6;keydown=1;break;}
				case 0x7d:{keyvalue=7;keydown=1;break;}					
			}
			while(temp!=0xf0)
			{
				temp=P3;
				temp=temp&0xf0;
			}			
		}
	}
    P3=0xfb;
	temp=P3;					  
	temp=temp&0xf0;//判断是否还等于0xf0
	while(temp!=0xf0)
	{
		delayms(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
			switch(temp)
			{
				case 0xeb:{keyvalue=8;keydown=1;break;}
				case 0xdb:{keyvalue=9;keydown=1;break;}
				case 0xbb:{keyvalue=10;keydown=1;break;}
				case 0x7b:{keyvalue=11;keydown=1;break;}					
			}
			while(temp!=0xf0)
			{
				temp=P3;
				temp=temp&0xf0;
			}
		}
	}
	P3=0xf7;
	temp=P3;					  
	temp=temp&0xf0;//判断是否还等于0xf0
	while(temp!=0xf0)
	{
		delayms(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
			switch(temp)
			{
				case 0xe7:{keyvalue=12;keydown=1;break;}
				case 0xd7:{keyvalue=13;keydown=1;break;}
				case 0xb7:{keyvalue=14;keydown=1;break;}
				case 0x77:{keyvalue=15;keydown=1;break;}
			}
			while(temp!=0xf0)
			{
				temp=P3;
				temp=temp&0xf0;
			}
		}
	}
	return keyvalue;
}
void display(uchar duan1,uchar duan2,uchar duan3,uchar duan4,uchar duan5,uchar duan6)
{
	display_1(0,duan1);
	delayms(1);
	display_1(1,duan2);
	delayms(1);
	display_1(2,10);
	delayms(1);
	display_1(3,duan3);
	delayms(1);
	display_1(4,duan4);
	delayms(1);
	display_1(5,10);
	delayms(1);
	display_1(6,duan5);
	delayms(1);
	display_1(7,duan6);
	delayms(1);
}
void display_1(uchar wei,uchar duan)
{
	DU=1;
	P0=segdata[duan];
	DU=0;
	P0=0xff;
    WE=1;
    P0=bitdata[wei];
    WE=0;
	P0=0x00;
}
void input()//输入
{
	EA=0;
	for(i=0;i<8;i++)//重置为-便于下次使用
		dis_arr[i]=10;
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[0]=keyIn;
			time_In[0]=keyIn;
			if(time_In[0]>=0&&time_In[0]<=2)
				break;	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[1]=keyIn;
			time_In[1]=keyIn;
			if((time_In[1]>=0&&time_In[1]<=9)&&(time_In[0]*10+time_In[1])<24)
				break;	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[2]=keyIn;
			time_In[2]=keyIn;
			if(time_In[2]>=0&&time_In[2]<=5)
				break;	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[3]=keyIn;
			time_In[3]=keyIn;
			if((time_In[3]>=0&&time_In[3]<=9)&&(time_In[2]*10+time_In[3])<60)
				break;	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[4]=keyIn;
			time_In[4]=keyIn;
			if(time_In[4]>=0&&time_In[4]<=5)
				break;	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		keyIn=keyscan();
		if(keydown==1)
		{
			keydown=0;
			dis_arr[5]=keyIn;
			time_In[5]=keyIn;
			if((time_In[5]>=0&&time_In[5]<=9)&&(time_In[4]*10+time_In[5])<60)
			{
				if(mode==0)
				{time[0]=time_In[0]*10+time_In[1];
				time[1]=time_In[2]*10+time_In[3];
				time[2]=time_In[4]*10+time_In[5];}
				else if(mode==1)
				{time_clk[0]=time_In[0]*10+time_In[1];
				time_clk[1]=time_In[2]*10+time_In[3];
				time_clk[2]=time_In[4]*10+time_In[5];}
				break;
			}	
		}
	}
	while(1)
	{
		display(dis_arr[0],dis_arr[1],dis_arr[2],dis_arr[3],dis_arr[4],dis_arr[5]);
		if(key3==0)
		{
			delayms(10);
			if(key3==0)
				{
					EA=1;
				break;}
		}
	}
}
void T0_time() interrupt 1//中断函数
{
    TH0=(65536-45872)/256;
    TL0=(65536-45872)%256;
    num++;
	if(num==20)//循环20次为一秒
    {
        num=0;
        time[2]++;//秒加一
        if(time[2]==60)//秒到60进位
		{
            time[2]=0;//秒清零分钟加一
            time[1]++;
            if(time[1]==60)//分钟到60进位
			{ 
                time[1]=0;//分钟清零小时加一
                time[0]++;  
                soundTime();//整点报时
                if(time[0]==24)//小时满24清零
                    time[0]=0;
            }
        }
		if((time[0]==time_clk[0])&&(time[1]==time_clk[1])&&(time[2]==time_clk[2]))
			{buffer=0;/*P1=0;*/}
	}
}				
void soundTime()
{
	buffer=0;
	delayms(10);
	buffer=1;
}

  • 13
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Verilog 数字时钟闹钟的设计可以分为两个模块:时钟模块和闹钟模块。时钟模块主要用于显示当前时间,包括小时、分钟和秒钟;而闹钟模块则主要用于设置和响铃闹钟。 下面是一个简单的 Verilog 数字时钟闹钟的设计示例: ```verilog module clock( input clk, // 时钟输入 output reg [3:0] hour, minute, second, // 当前时间 input set_alarm, // 闹钟设置输入 input alarm_on // 闹钟开关输入 ); reg [3:0] alarm_hour, alarm_minute; // 闹钟时间 reg alarm_ringing; // 闹钟响铃标志 // 时钟模块 always @(posedge clk) begin if (second == 60) begin second <= 0; if (minute == 60) begin minute <= 0; if (hour == 24) begin hour <= 0; end else begin hour <= hour + 1; end end else begin minute <= minute + 1; end end else begin second <= second + 1; end end // 闹钟模块 always @(*) begin if (set_alarm) begin alarm_hour <= hour; alarm_minute <= minute; end if (alarm_on && (hour == alarm_hour) && (minute == alarm_minute)) begin alarm_ringing <= 1; end else begin alarm_ringing <= 0; end end endmodule ``` 在这个示例中,时钟模块使用了一个 always 块,通过对秒、分和时进行递增操作来实现时间的显示。闹钟模块则使用了一个组合逻辑块,通过对闹钟时间的设置和当前时间的比较来实现闹钟功能。同时,还定义了一个闹钟响铃标志,用于指示当前是否正在响铃。 需要注意的是,这个示例只是一个简单的 Verilog 数字时钟闹钟设计,实际应用中还需要考虑更多的因素,如显示器、按键输入等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值