`

51单片机学习笔记:可对时电子钟

阅读更多

本篇是对上一篇的改进,昨天学习了第4章 中的独立键盘的使用

 独立键盘拥有自己独有的IO口,所以比较简单,我上一篇写的电子钟程序只能烧程序对时,

不能手动按键对时,这肯定是最差劲的做法,所以学习了按键之后,就立马动手改进我的电子钟了

 同时改进了数码管小数点的显示,消除了叠影 

 

使用芯片STC89C52RC, 2个锁存器

6个带小数点共阴极数码管显示一个24时制时钟

没有时钟芯片,所以掉电后时间会复位

原理图为TX-1C开发板

 

==============================

最终显示的<时.分.秒>是 16.31.37  形式

 

使用3个按键,  S2  S3   S5

其中S2和S3是加减数值,S5是切换对时状态,

 

#include <reg52.h>
#include "MY51.H"

void show();
int8  shi=22;   //初识时间22:45:00  按S5键进入对时模式
int8  fen=45;
int8  miao=0;
uint8  timeFlag=0;//0计时模式,1校对时钟,2校对分钟,3校对秒钟
void main() 	
{
	startT0(1000);  //开始定时器
	while(1)
	{		
		show();		//送入数码管显示
		if(keyS5==keyDown) //按下S5键
		{
			delayms(5);//消抖处理
			if(keyS5==keyDown)
			{
                while(1)
                {
                    show();
                    if(keyS5==keyUp)//放开按钮
                    {
                        delayms(5); //消抖处理
                        if(keyS5==keyUp)
                        {
                            break;
                        }
                    }
                }
				timeFlag=(++timeFlag)%4; //按S5键进行状态切换   
				while(timeFlag)
				{
					if(timeFlag==1)
					{
                        led=0xff;
                        led7=0;       //进入对时钟模式,且打开7号指示灯                 
					}
					else if(timeFlag==2)
					{
                         led=0xff;
                         led5=0;   	 //进入校对分钟模式,且打开5号指示灯
					}
					else if(timeFlag==3)
					{
                         led=0xff;
                         led3=0;	 //进入校对秒钟模式,且打开3号指示灯
					}
	
					show();			//刷新数码管
					if(keyS2==keyDown)//S2和S3用于调整数值,加减运算
					{
						delayms(5);//消抖处理
						if(keyS2==keyDown)
						{
							if(timeFlag==1)
							{
                                shi--;
                                if(shi<0) 
                                {
                                    shi=23;
                                }                        
							}
							else if(timeFlag==2)
							{
                                fen--;
                                if(fen<0)
                                {
                                    fen=59;
                                }
							}
							else if(timeFlag==3)
							{
                                miao--;
                                if(miao<0)
                                {
                                    miao=59;
                                }
							}
							while(1)
							{
								show(); //就算S2键被按着,也要刷新数码管
								if(keyS2==keyUp)
								{
									delayms(10);
									if(keyS2==keyUp)
									{
										break;
									}
								}
							}

						}	
					}
					
					if(keyS3==keyDown)
					{
						delayms(5);//消抖处理
						if(keyS3==keyDown)
						{
							if(timeFlag==1)
							{
                                shi++;
                                if(shi>23)
                                {
                                    shi=0;
                                }                          
							}
							else if(timeFlag==2)
							{
                                fen++;
                                if(fen>59)
                                {
                                    fen=0;
                                }
							}
							else if(timeFlag==3)
							{
                                miao++;
                                if(miao>59)
                                {
                                    miao=0;
                                }
							}
							while(1)
							{
								show();
								if(keyS3==keyUp)
								{
									delayms(5);
									if(keyS3==keyUp)
									{
										break;
									}
								}
							}

						}	
					}	
					
					if(keyS5==keyDown)
					{
						delayms(5);//消抖处理
						if(keyS5==keyDown)
						{
							timeFlag=(++timeFlag)%4;//按S5键切换状态
							while(1)
							{
								show();
								if(keyS5==keyUp)
								{
									delayms(5);
									if(keyS5==keyUp)
									{
										break;
									}
								}
							}
						}	
					}	
				}
				led=0xff;  //对时结束,指示灯灭
			}	
		}
	}
}


void show()  //显示时钟
{
	uint8 oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela; //oneWela是最左边的数码管
	sixWela =miao%10;
	fiveWela=miao/10;	
	foreWela=fen%10;
	threeWela=fen/10;
	twoWela=shi%10;
	oneWela=shi/10;
	displaySMG(oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela,0xf5); //0xf5是小数点的位置
}

void T0_Work()  //T0定时器调用的工作函数
{  
   miao++;
	if(miao>59)
	{
		miao=0;
		fen++;
	}

	if(fen>59)
	{
		fen=0;
		shi++;
	} 
	
	if(shi>23)
	{
		shi=0;
	}
}

 

 

#ifndef _MY51_H_
#define _MY51_H_
#include <math.h>
#include <intrins.h>

typedef int   				int16  ;
typedef int   				INT16  ;
typedef unsigned int    uint16 ;
typedef unsigned int    UINT16 ;
typedef unsigned short  uint ;
typedef unsigned short  UINT ;
typedef unsigned short  word ;
typedef unsigned short  WORD ;
typedef unsigned long   uint32 ;
typedef unsigned long   UINT32 ;
typedef unsigned long   DWORD ;
typedef unsigned long   dword ;
typedef signed long	   int32	 ;
typedef signed long	   INT32  ;
typedef float		    	    float32	 ;
typedef double		    	double64  ;
typedef signed char		int8 ;
typedef signed char 		INT8 ;
typedef unsigned char	byte ;
typedef unsigned char    BYTE 	 ;		//WINDOWS的windef.h里面是这么定义的
typedef unsigned char	uchar ;
typedef unsigned char	UCHAR ;
typedef unsigned char	UINT8 ;
typedef unsigned char	uint8 ;
typedef unsigned char	BOOL	 ;		//windows中定义BOOL为int
typedef unsigned char	bool	 ;		    //bool是c++的内置类型

#define TRUE     1
#define true     1
#define FALSE    0
#define false    0

#define open     1    //open和close用于 标志打开和关闭状态
#define OPEN     1
#define close    0
#define CLOSE    0
#define lock     0
#define start    1
#define START    1
#define stop     0
#define STOP     0
#define keyDown  0
#define keyUp    1

sbit dula =P2^6;  //段选锁存器控制  控制笔段
sbit wela =P2^7;  //位选锁存器控制  控制位置

#define led P1    //灯总线控制
sbit led0=P1^0;   //8个led灯,阴极送低电平点亮
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;

sbit keyS2=P3^4; 	//4个独立按键
sbit keyS3=P3^5;
sbit keyS4=P3^6;
sbit keyS5=P3^7;

void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot); 
void delayms(uint16 ms);
void T0_Work();

void delayms(uint16 ms)  //软延时函数
{
	uint16 i,j;
	for(i=ms;i>0;i--)
	{
        for(j=113;j>0;j--)
        {}
	}
}
///////////////////////////////////////////////////////////////////////////
#define dark	0x11  //在段中,0x11是第17号元素,为0是低电平,数码管不亮
#define dotDark 0xff //小数点全暗时
uint8 code table[]= { 			//0~F外加小数点和空输出的数码管编码
 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
 0x39 , 0x5e , 0x79 , 0x71 , // C D E F
 0x80 , 0x00                 // . 空     空时是第0x11号也就是第17号元素
 };

/////////////////////////////////////////////////////////////////////////////
uint8   TH0Cout=0 ;	    //初值	
uint8   TL0Cout=0 ;	   
uint16  T0IntCout=0;     //中断计数
uint16  T0IntCountAll=0; //(N-1)/65536+1;  //总中断次数
bool    bT0Delay=false;  //使用延时函数标志,初始未用
bool    bT0Over=false; 	 //中断处理函数执行结果之一

void startT0(uint32 ms)  //开启定时器
{	
	float32   	t=ms/1000.0;		   		 //定时时间
	double64    fox =11.0592*(pow(10,6));   //晶振频率
	uint32    	N=(t*fox)/12 ; 				 //定时器总计数值

	TH0Cout =(65536-N%65536)/256;      	 //装入计时值零头计数初值
	TL0Cout =(65536-N%65536)%256;
	T0IntCountAll=(N-1)/65536+1;			 //总中断次数
	TMOD=TMOD | 0x01; 						 //设置定时器0的工作方式为1
	
	EA =open;   //打开总中断
	ET0=open;   //打开定时器中断

	TH0=TH0Cout;  //定时器装入初值
	TL0=TL0Cout;
	TR0=start;	 //启动定时器
}

void delayT0(uint32 ms)		//硬延时函数,自己乱写的不好用,求指点
{
	startT0(ms);				//启动定时器
	bT0Delay=true;    		//告诉T0定时器,起用延时模式
	while(bT0Over==false);	//时间没到的话继续检测
	bT0Over=false;				//时间到了,让标志复位
}

void T0_times() interrupt 1 //T0定时器中断函数
{
	T0IntCout++;
	if(T0IntCout==T0IntCountAll)  //达到总中断次数值
	{	
		T0IntCout=0; 		 //中断次数清零,重新计时
		bT0Over=true;     //时间真的到了
		if(bT0Delay)		//本次中断是用来延时的吗
		{
			TR0=stop; 		 //如果是由延时函数开启T0的话,关闭T0
			return;
		}

		TH0=TH0Cout;   		//循环定时的话要重装初值,每次定时1秒,重装一次
		TL0=TL0Cout;
		T0_Work();     		//工作函数
	}
}

////////////////////////////////////////////////////////////////////////////////
void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)
{		//控制6位数码管显示函数,不显示的位用参数 dark
		P0=0;
		dula=1;
		dula=0;	 //段选数据清空并锁定
//////////////////////////
		P0=0xff; //送位数据前关闭所有显示
		wela=1;
		P0=0xfe;
		wela=0;

		P0=0;  	//低电平输到数码管阳极,避免数码管吴亮
      dula=1;
		P0=table[oneWela]|((0x01&dot)?0x00:0x80);   //送段数据,小数点可选显示		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xfd;
		wela=0;

		P0=0;
		dula=1;
		P0=table[twoWela]|((0x02&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xfb;
		wela=0;
		P0=0;
		dula=1;
		P0=table[threeWela]|((0x04&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xf7;
		wela=0;

		P0=0;
		dula=1;
		P0=table[fourWela]|((0x08&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xef;
		wela=0;

		P0=0;
		dula=1;
		P0=table[fiveWela]|((0x10&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xdf;
		wela=0;

		P0=0;
		dula=1;
		P0=table[sixWela]|((0x20&dot)?0x00:0x80);
		dula=0;
		delayms(2);
}

#endif

 

0
6
分享到:
评论

相关推荐

    51单片机自学笔记

    ### 51单片机自学笔记知识点概览 #### 第1天:从哪里开始你的单片机学习 - **神秘武器的得来**:这里提到的“神秘武器”指的是51单片机及其相关的开发工具。对于初学者来说,了解如何获取这些工具是非常重要的第一...

    和B站UP江科大自化协学习51单片机.zip

    51单片机在电子工程、自动化控制、物联网等领域有广泛应用,因其结构简单、成本低廉、易于上手而深受初学者和工程师喜爱。 【51单片机硬件结构】 51单片机主要包括以下几个部分: 1. CPU(中央处理器):执行指令...

    51单片机学习使用实践笔记

    《51单片机学习使用实践笔记》是一份详尽且实用的学习资源,专为初次接触单片机的初学者设计。这份资料涵盖了单片机的软硬件各个方面,旨在帮助学习者快速掌握51单片机的基础知识和实际操作技能。 在硬件方面,51...

    单片机学习笔记ourdev_530143.pdf

    ### 单片机学习笔记ourdev_530143.pdf知识点总结 #### 一、开发板配件 - **HJ-1G开发板主机**:作为学习平台的核心部分,该开发板集成了多种功能模块,适用于初学者进行单片机的学习与实践。 - **STC单片机**:已...

    51单片机应用开发快速入门自学笔记_8051_

    这份“51单片机应用开发快速入门自学笔记”主要涵盖了以下几个关键知识点: 1. **单片机基础**:首先,你需要了解单片机的基本结构和工作原理,包括CPU、内存(ROM和RAM)、定时器/计数器、串行通信接口等基本组成...

    基于S51的单片机时钟设计

    在电子工程领域,单片机(Microcontroller)是不可或缺的一部分,尤其在自动化设备和智能系统的设计中。"基于S51的单片机时钟设计"是一个典型的项目,旨在提升开发者对单片机原理和应用的理解,以及使用开发工具的...

    MSP430单片机学习笔记

    ### MSP430单片机学习笔记 #### 学习心得与基础知识 MSP430是一款由德州仪器(TI)生产的16位超低功耗单片机(Microcontroller Unit,MCU),广泛应用于各种低功耗应用场景,如便携式测量设备、汽车电子系统、智能...

    51单片机精简入门笔记

    在学习51单片机时,了解其内部资源是至关重要的。51单片机内部主要由三部分组成:Flash程序空间、RAM空间以及特殊功能寄存器(SFR)。 - **Flash程序空间**:51单片机的Flash程序空间主要用于存储程序代码。例如,在...

    51单片机的OV7670摄像头驱动程序

    在电子工程领域,51单片机是一种广泛应用的微控制器,尤其在教育和小型嵌入式系统中。STC12C5A是51单片机系列的一个具体型号,以其高性价比和丰富的I/O资源受到青睐。在这个项目中,我们将讨论如何在STC12C5A单片机...

    启东单片机51实验板光盘(最新).

    此外,光盘中可能还包括了相关的学习资料,如51单片机原理与应用书籍、教程文档、电路图和设计笔记。这些资料对于深入学习和理解51单片机的工作机制非常有帮助。 总的来说,《启东单片机51实验板光盘(最新)》是一套...

    51单片机DS1302实时时钟模块资料和程序

    在电子工程领域,51单片机是一种广泛应用的微控制器,因其简单易用且功能强大而受到广大开发者的青睐。本资源包主要关注的是51单片机与DS1302实时时钟(RTC)模块的结合使用,旨在帮助开发者理解和实现基于51单片机...

    shizhong.rar_51系列单片机设计实例_单片机 数字时钟_数字时钟

    在提供的压缩包文件中,"新建 文本文档.txt"可能是设计过程中的一些笔记或代码片段,而"www.pudn.com.txt"可能是来源于某个技术论坛或下载站点的链接,提供了更多关于51单片机或数字时钟设计的相关资源。 通过这个...

    记录了我的51单片机学习经历.zip

    这个名为“记录了我的51单片机学习经历.zip”的压缩包,很可能包含了某位开发者在学习51单片机过程中积累的代码资源、笔记或者项目实例。其中,“code_resource_010”可能是其中一个代码资源文件,可能是实验或项目...

    单片机原理及应用笔记

    ### 单片机原理及应用知识点详解 #### 一、单片机定义及其特性 - **定义**: 单片机是一种集成电路技术...通过对AT89S51单片机硬件结构的学习,我们可以更好地理解和掌握单片机的工作原理及其在实际项目中的应用技巧。

    USB下载 51单片机开发板与应用

    ### USB下载51单片机开发板与应用 #### 一、引言 随着计算机技术的不断进步,传统的...此外,搭配STC89C52芯片和丰富的实验板资源,不仅能够提高学习效率,还能帮助学习者深入理解和掌握51单片机的相关知识和技术。

    51单片机代码集.zip

    5. **教程和笔记**:可能是作者或他人整理的51单片机学习笔记,包括了原理讲解、实例分析等内容,有助于快速入门。 学习51单片机,首先要了解它的内部结构和工作原理,包括CPU、存储器、输入输出端口等。然后,掌握...

Global site tag (gtag.js) - Google Analytics