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