⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led时钟.c

📁 一个用C语言写的基于98C51单片机的电子钟程序
💻 C
字号:
#include <REGX51.H>
#include "ds1302.h"			//包含DS1302头文件
#define leddata P0			//定义LED数据口
#define sec 0x80			//1302秒寄存器地址
#define min 0x82			//1302分寄存器地址
#define hou 0x84			//1302时寄存器地址
#define read 0x01			//读操作,因为读的时候地址要加1,使最低位为1
sbit MODE=P3^4;				//按键定义,下同
sbit SET=P3^5;
sbit UP=P3^6;
sbit DOWN=P3^7;
sbit led0=P2^0;				//LED位选,因为布线不是按顺序布的,程序定义一下就可以了,下同
sbit led1=P2^3;
sbit led2=P2^7;
sbit led3=P2^4;
sbit led4=P2^6;
sbit led5=P2^5;
//**************函数声明*****************
void delays(unsigned char);
void display(void);
void Scan_Key(void);
void id_case1_key();
void Set_id(unsigned char ,unsigned char);
//*************变量定义******************
unsigned char id=0,timecount,re_disp=0;		//定义用到的变量,id为调整模式用,不为0时表示调整模式,调整哪个量由id值确定
											//timecount用于500ms定时记数,时间到取反flag标志位,re_disp记数200次共10s,调整状态下按键无操作10s自动返回正常显示状态
bit hour,minute,second,flag;				//定义位变量,hour,minute,second分别为调整时闪烁标志位,flag 500ms取反一次,调整位闪烁及冒号闪烁用
unsigned char code tab[]={0x48,0xEE,0x54,0xC4,0xE2,0xC1,0x41,0xEC,0x40,0xC0,0x60};	//LED码表,根据硬件修改
unsigned char inittime[7]={0x00,0x00,0x12,0x16,0x11,0x06,0x04};						//初始化1302时用到的初始化数据
//                          秒  分钟 小时  日   月   年  星期
void t0(void) interrupt 1 using 0			//中断处理程序,主要用于取反标志位,返回正常显示状态
{
  	TH0=(65535-50000)/256; //50ms定时
  	TL0=(65535-50000)%256;  
  	timecount++;re_disp++;
  	if(timecount>9)
   		{
			timecount=0;
    		flag=~flag;
   		}
	if(re_disp>200){re_disp=0;if(id)id=0;}
}
void delays(unsigned char k)				//延时函数
{
	unsigned char i,j;
	for(i=0;i<k;i++)
		for(j=0;j<50;j++);
}
void display(void)							//显示函数
{
	if(flag&hour)							//如hour为1表示调整时,flag为1时不显示
		{
			led0=0;leddata=0xff;delays(10);led0=1;
			led1=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led1=1;	//&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
		}
	else									//flag为0时显示,产生闪烁效果,下同
		{
			leddata=tab[Read1302(hou|read)/16];led0=0;delays(10);led0=1;
			leddata=tab[Read1302(hou|read)%16]&~((unsigned char)~flag<<6);led1=0;delays(10);led1=1;
		}
	if(flag&minute)
		{
			led2=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led2=1;
			led3=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led3=1;
		}
	else
		{
			leddata=tab[Read1302(min|read)/16]&~((unsigned char)~flag<<6);led2=0;delays(10);led2=1;
			leddata=tab[Read1302(min|read)%16]&~((unsigned char)~flag<<6);led3=0;delays(10);led3=1;
		}
	if(flag&second)
		{
			led4=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led4=1;
			led5=0;leddata=0xff;delays(10);led5=1;
		}
	else
		{
			leddata=tab[Read1302(sec|read)/16]&~((unsigned char)~flag<<6);led4=0;delays(10);led4=1;
			leddata=tab[Read1302(sec|read)%16];led5=0;delays(10);led5=1;
		}
}
void Scan_Key(void)				//键盘检测函数
{
	display();					//程序开头调用显示函数
	if(!SET)					
		{
			while(!SET)display();	//等待按键释放,如一直按下一直调用显示函数,防止显示中断
			re_disp=0;				//清除记数,重新开始10s定时
			id++;if(id>3)id=0;		//id加1,后面根据id值对应调整项目
		}
	if(id==0){hour=0;minute=0;second=0;}	//根据id值跳到相应处理函数
	if(id==1){hour=1;id_case1_key();}		//id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同
	if(id==2){hour=0;minute=1;id_case1_key();}
	if(id==3){minute=0;second=1;id_case1_key();}
}
void id_case1_key(void)						//键盘处理函数,只有按下set键时才会进入,
{
	display();								
  	if (!DOWN) //减少
      	{
       		while(!DOWN)display();			//等待按键释放,如一直按下一直调用显示函数,防止显示中断
			re_disp=0;						//清除记数,重新开始10s定时
	   		Set_id(id,0);					//跳到加减判断函数,下同,
      	}
   	if (!UP)  //增加
      	{
       		while(!UP)display();
			re_disp=0;
	   		Set_id(id,1);    
      	}
}

//根据选择调整相应项目并写入DS1302
void Set_id(unsigned char sel,unsigned char sel_1)		//执行调整项目的函数
{
  	signed char max,mini,address,item;					
	if(sel==1)  {address=hou; max=23;mini=0;}    //小时	//根据id值确定要调整的项,并确定调整上下限,下同
	if(sel==2)  {address=min; max=59;mini=0;}    //分钟
  	if(sel==3)  {address=sec; max=0;mini=0;}     //秒
  	item=Read1302(address|read)/16*10+Read1302(address|read)%16;	//从相应的地址读取当前数据并转换为十进制
  	if (sel_1==0) item--;  else item++;								//确定是对项目加还是减,并对越限处理
 	if(item>max) item=mini;   
  	if(item<mini) item=max;
	Write1302(0x8e,0x00);//允许写操作	
  	Write1302(address,item/10*16+item%10);							//将调整结果转换成压缩BCD码重新写入1302
  	Write1302(0x8e,0x80);//写保护,禁止写操作  
}
void main()							//主函数
	{  
		TMOD=0x01;					//初始化定时器
  		TH0=(65535-50000)/256;
  		TL0=(65535-50000)%256;
  		EA=1;
  		ET0=1;
		TR0=1; 
		Write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭 
 		Write1302(0x8e,0x80);//写保护,禁止写操作 
		if(!UP&!DOWN)Set1302(inittime);			//如果同时按下UP和DOWN键则初始化1302,该语句在while(1)前,只执行一次,需要复位,防止误操作
		while(1)
			{  
				Scan_Key();						//主程序一直调用键盘检测函数即可
			}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -