STC89C52闹钟练习小项目

本文详细描述了如何使用51单片机实现一个具有动态数码管显示、按键控制、定时闹钟设置和串口通信功能的小闹钟,涉及到了数码管驱动、中断处理和多模块编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用51单边机做一个简易的小闹钟

实现功能:

             1.动态数码管扫描显示年份时间

              2.通过外部中断函数实现按键切换日期和时间功能

              3.利用串口助手设置定时闹钟

              4.利用通信串口将每一时间戳传输到串口助手中

 数码管模块

#ifndef _NIXITE_H_
#define _NIXITE_H_
void Nixite(unsigned char Location,unsigned char Number);
#endif
#include <REGX52.H>
#include"Nixite.h"
#include"Delay.h"

unsigned char code arrNum[]={0X3F,0X06,0X5B,0X4F,0X66,0X7D,0X07,0X7F,0X6F};
void Nixite(unsigned char Location,unsigned char Number)
{
	switch(Location)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=arrNum[Number];
	Delay(1);
	P0=0X00;
	
}

 嗡鸣器模块

#ifndef _BUZZER_H_
#define _BUZZER_H_
sbit Buzzer =P1^5;
void BEEP();
#endif
#include<regx52.h>
#include"buzzer.h"
#include"Delay.h"


void BEEP()
{
	Buzzer=!Buzzer;
	Delay(2);			//500Hz
}

时间转换模块

#ifndef _TIMER_TRANSLATE_H_
#define _TIMER_TRANSLATE_H_

void NowTime ();
void time_1();
#endif
#include <regx52.h>
#include"timetranslate.h"
#include<stdio.h>
#include <string.h>
#include"Nixite.h"

static unsigned char year=23;
unsigned char month=10;
unsigned char date=23;
unsigned char hour=9;
unsigned char min=28;
unsigned char second=23; 
unsigned char week=1; 
unsigned char a=20; 


unsigned char code arrWeek[7][4]={"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
//unsigned char code arrWeek[7]={1,2,3,4,5,6,7};
unsigned char code arrMonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
//char Now[25];
//="2023-10-23 9:28:23 Sun\r\n";

static void count_clock()
{
	second++;
	if (second>=60)
	{
	    min++;
		second=0;
	}
	if (min>=60)
	{
	 hour++;
	 min=0;
	}
	if(hour>=24)
	{
		date++;
		week=(week+1)%7;
		hour=0;
	}
	if (date>arrMonth[month-1])
	{
		month++;
		date=1;
	}
	if(month>12)
	{
		year++;
		month=1;
	}
}
void NowTime ()  //计算当前时间
{
	count_clock();
	
//	printf( "20%02d-%02d-%02d %02d:%02d:%02d %d\r\n", year, month, date, hour, min, second, arrWeek[week]);
	printf("%d-%02d-%02d %02d:%02d:%02d\n",year,month,date,hour,min,second);
	printf("%s\n",arrWeek[week]);
	Nixite(1,22);
	Nixite(2,(unsigned char)year/10);
	Nixite(2,(unsigned char)year%10);
	
	Nixite(3,(unsigned char)hour/10);
	Nixite(4,(unsigned char)hour%10);
	Nixite(5,(unsigned char)min/10);
	Nixite(6,(unsigned char)min%10);
	Nixite(7,(unsigned char)second/10);
	Nixite(8,(unsigned char)second%10);
}

void time_1()
{
	Nixite(5,(unsigned char)month/10);
	Nixite(6,(unsigned char)month%10);
	Nixite(7,(unsigned char)date/10);
	Nixite(8,(unsigned char)date%10);
}

串口中断设置模块

#ifndef _TIMER_H_
#define _TIMER_H_

extern char switch_B;
void InitInterrupt(); 
void InitTimer0();
void InitUART();

#endif
#include"timer.h"
#include<regx52.h>
char switch_B;
void InitInterrupt() 
{
	EA=1; //总开关
	IT0=1; //下降沿触发
	EX0=1; //打开外部中断0中断允许
	IT1 =0; //下降沿触发
	EX1=1; //打开外部中断1中断允许	
	ET0 = 1;   //定时器0允许控制位
	ES = 1;//串口中断允许位
}


void InitTimer0()		//1毫秒@11.0592MHz
{
	TMOD = 0x00;		//设置定时器模式
	TH0 = 0x1C66>>5;		//设置定时初始值
	TL0 = 0x1C66&0X1F;		//设置定时初始值
	TR0 = 1;		//定时器0开始计时
}

void InitUART()
{
	SCON=0x50;
	TMOD=0x20;
	PCON=0x80;
	TL1=0xF4;
	TH1=TL1;
	TR1=1;
	TI=1; //发送中断标志位
}	

void UART_Handle() interrupt 4
{
	static unsigned char s_iBuffer;
	s_iBuffer = SBUF;
	RI =0;
	switch_B = 1; 
}

主函数

#include"timer.h"
#include"timetranslate.h"
#include<regx52.h>
#include"Nixite.h"
#include"Buzzer.h"
#include"Delay.h"

unsigned char Num=0;


void  main()        
{	
	InitInterrupt();  
	InitTimer0();		 //初始化计时器
	InitUART();  	//串口初始化	
	while(1)
	{
		
	}
}

void Time() interrupt 1    //流水灯
{
	static unsigned int count=0;   
	static unsigned int clock = 0;
	count++;  	//秒计数器
	TH0 = 0x1C66>>5;		//设置定时初始值
	TL0 = 0x1C66&0X1F;
	
	
	if (count>=999)
	{
		count=0;
		P2=~(0x01<<Num);
		Num++;
		if (Num==8)
		{
			Num=0; 
		}
		NowTime ();           //每秒当前时间+1,并打印输出
    clock--;
		if (clock==0)
		{
			while(switch_B==1) BEEP();
		}
	}
}

void Key1() interrupt 0 //按键一中断:切换月份
{
	time_1();
	Delay(300);
}

void Key2() interrupt 3 //按键二中断:关闭闹钟
{
	switch_B = 0;
}

评价:该项目主要为了更好的练习多模块化编程以及熟悉各种串口开关,通信流程,出现了一个模块一个函数的情况,比较多的文件冗余。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值