基于51单片机的秒表时钟设计

(仿真+程序+设计报告)

功能介绍

具体功能:

1.由51单片机主控,LCD1602显示时、分、秒;

2.运行后三个按键可以修改时间;

​演示视频:

基于51单片机的秒表时钟设计—LCD1602显示时分秒、可调 

添加图片注释,不超过 140 字(可选)

程序

//****************************************
#include  <REG51.H>          
#include  <math.h>    //Keil library  
#include  <stdlib.h>  //Keil library  
#include  <stdio.h>   //Keil library        
#include  <INTRINS.H> //Keil library  
#include "DS1302.h"    //时钟模块头文件 
/***微信公众号:木子单片机****
/* define constants */
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode


#define   uchar unsigned char
#define   uint unsigned int        

#define   DataPort P0    //LCD1602数据端口

#define LCD_COMMAND			0      // Command
#define LCD_DATA			1      // Data
#define LCD_CLEAR_SCREEN	0x01      // 清屏
#define LCD_HOMING  		0x02      // 光标返回原点

#define LCD_SHOW			0x04    //显示开
#define LCD_HIDE			0x00    //显示关	  

#define LCD_CURSOR			0x02 	//显示光标
#define LCD_NO_CURSOR		0x00    //无光标		     

#define LCD_FLASH			0x01    //光标闪动
#define LCD_NO_FLASH		0x00    //光标不闪动

#define LCD_AC_UP			0x02
#define LCD_AC_DOWN			0x00      // default

#define LCD_MOVE			0x01      // 画面可平移
#define LCD_NO_MOVE			0x00      //default

//Port Definitions**********************************************************
sbit LcdRs		= P2^5;
sbit LcdRw		= P2^6;
sbit LcdEn  	= P2^7;
sfr  DBPort 	= 0x80;		//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

sbit key1 = P3^7;   //加按键
sbit key2 = P3^6;   //减按键
sbit key3 = P3^5;   //设置按键
sbit BEEP = P1^2;	//报警
                   
uchar key1Flag=0,key2Flag=0,key3Flag=0;
uchar FirstBuff[16];

uchar Set_flicker=0;     //设置闪烁标志
uint  SetTime_MS;  //定时器毫秒定时
uchar SetPosition=0;     //设置位置

//*********************************************************
/**************************************************
函数:delay_ms()
描述:延迟x毫秒
/**************************************************/
void delay_ms(uchar x)
{
    uchar i, j;
    i = 0;
    for(i=0; i<x; i++)
    {
       j = 250;
       while(--j);
	   j = 250;
       while(--j);
    }
}
//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{
	LcdRs=0;
	LcdRw=1;	_nop_();
	LcdEn=1;	_nop_();
						 
	LcdEn=0;
	return DBPort;		
}
//向LCD写入命令或数据************************************************************
void LCD_Write(bit style, unsigned char input)
{
	LcdEn=0;
	LcdRs=style;
	LcdRw=0;		_nop_();
	DBPort=input;	_nop_();//注意顺序
	LcdEn=1;		_nop_();//注意顺序
	LcdEn=0;		_nop_();
	LCD_Wait();	
}

//设置显示模式************************************************************
void LCD_SetDisplay(unsigned char DisplayMode)
{
	LCD_Write(LCD_COMMAND, 0x08|DisplayMode);	
}
//设置输入模式************************************************************
void LCD_SetInput(unsigned char InputMode)
{
	LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化LCD************************************************************
void LCD_Initial()
{
	LcdEn=0;
	LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵
	LCD_Write(LCD_COMMAND,0x38);
	LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
	LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
	LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
}
//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
	if(y==0)
		LCD_Write(LCD_COMMAND,0x80|x);
	if(y==1)
		LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
//将字符输出到液晶显示
void Print(unsigned char *str)
{
	while(*str!='\0')
	{
		LCD_Write(LCD_DATA,*str);
		str++;
	}
}
//按键控制函数
void Button_Control(void)
{
	    int Readtime=0;
///////////////////////////////////加/////////////////////////////////////	
        if ((key1 == 0)&&(key1Flag == 0))
		{
			BEEP = 0;
			delay_ms(70);//消抖
			BEEP = 1;
			key1Flag = 1;
			if (key1 == 0)
			{
			    if (SetPosition == 1)//小时
				{
					Readtime = Read1302(DS1302_HOUR);
					Readtime++;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+16;
					}
					if(Readtime > 0x23)
					{
						Readtime=0x00;
					}
					DS1302_SetTime(DS1302_HOUR,Readtime);
				}
				else if (SetPosition == 2)//分钟
				{
					Readtime = Read1302(DS1302_MINUTE);
					Readtime++;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+16;
					}
					if(Readtime > 0x59)
					{
						Readtime=0x00;
					}
					DS1302_SetTime(DS1302_MINUTE,Readtime);
				}
				else if (SetPosition == 3)//秒钟
				{
					Readtime = Read1302(DS1302_SECOND);
					Readtime++;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+16;
					}
					if(Readtime > 0x59)
					{
						Readtime=0x00;
					}
					DS1302_SetTime(DS1302_SECOND,Readtime);
				}
		  }
		}
		else if (key1 == 1)
		{
		  key1Flag = 0;
		}
///////////////////////////////////减/////////////////////////////////////
		if ((key2 == 0)&&(key2Flag == 0))
		{
			BEEP = 0;
			delay_ms(70);//消抖
			BEEP = 1;
			key2Flag = 1;
			if (key2 == 0)
			{
				if (SetPosition == 1)//小时
				{
					Readtime = Read1302(DS1302_HOUR);
					Readtime--;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+9;
					}
					if(Readtime < 0x00)
					{
						Readtime=0x23;
					}
					DS1302_SetTime(DS1302_HOUR,Readtime);
				}
				else if (SetPosition == 2)//分钟
				{
					Readtime = Read1302(DS1302_MINUTE);
					Readtime--;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+9;
					}
					if(Readtime < 0x00)
					{
						Readtime=0x59;
					}
					DS1302_SetTime(DS1302_MINUTE,Readtime);
				}
				else if (SetPosition == 3)//秒钟
				{
					Readtime = Read1302(DS1302_SECOND);
				    Readtime--;
					if (Readtime%16 > 9)
					{
						Readtime=(Readtime&0xf0)+9;
					}
					if(Readtime < 0x00)
					{
						Readtime=0x59;
					}
					DS1302_SetTime(DS1302_SECOND,Readtime);
				}
		  }
		}
		else if (key2 == 1)
		{
		  key2Flag = 0;
		}
////////////////////////////////////设置////////////////////////////////////
		if ((key3 == 0)&&(key3Flag == 0))
		{
		    BEEP = 0;
			delay_ms(70);//消抖
			BEEP = 1;
			key3Flag = 1;
			if (key3 == 0)
		    {
              SetPosition++;
			  if (SetPosition >= 4)
			  {
				SetPosition = 0;
			  }
			  LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
			}
		}
		else if (key3 == 1)
		{
		  key3Flag = 0;
		}
}
//*********************************************************
//******主程序********
//*********************************************************
void main()
{  
  SYSTEMTIME CurrentTime;  
 
  TMOD = 0x01;                    //set timer0 as mode1 (16-bit)
  TL0 = T1MS;                     //initial timer0 low byte
  TH0 = T1MS >> 8;                //initial timer0 high byte
  TR0 = 1;                        //timer0 start running
  ET0 = 1;                        //enable timer0 interrupt
  EA = 1;                         //open global interrupt switch         
  LCD_Initial();                   //液晶初始化
  while(1)                         //循环
  { 
    
    Button_Control();//按键控制函数
	DS1302_GetTime(&CurrentTime);//DS1302获取时间函数
	TimeToStr(&CurrentTime);

    GotoXY(0,0);
    Print(FirstBuff);	 //显示1602第一行数组
  }
}**//完整资料
***/***微信公众号:木子单片机****
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
    TL0 = T1MS;                     //reload timer0 low byte
    TH0 = T1MS >> 8;                //reload timer0 high byte

	if (SetPosition != 0)
	{
	  SetTime_MS++;
	  if (SetTime_MS >= 100)              //1ms * 500 -> 0.3s
      {
        SetTime_MS = 0;                    //reset counter
		Set_flicker = !Set_flicker;
	  }
	} 
}




 

硬件设计

使用元器件:

单片机:AT89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

设计资料

01仿真图

本设计使用proteus8.9版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

02程序

本设计使用Keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

03设计报告

六千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

04设计资料

        资料获取请看前面演示视频,全部资料包括仿真源文件 、程序(含注释)、设计报告等。具体内容如下,全网最全! !

操作演示请观看前面演示视频!

点赞分享一起学习成长。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐