- /*-----------------------------------------------
- 名称:DS1302时钟数码管显示可调
- 编写:LI
- 日期:2015.11
- 修改:无
- 内容:DS1302实时时钟数码管显示,时间和日期切换显示 三按键控制
- 时间格式xx-xx-xx
- 日期格式xx-xx-xx
- 周秒格式-x- xx
- ------------------------------------------------*/
- #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #include "ds1302.h"
- #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
- #define uchar unsigned char
- #define uint unsigned int
- sbit BEEP=P1^0;
- sbit led=P0^7;
- sbit SET=P3^5;
- sbit UP=P3^6;
- sbit DOWN=P3^7;
- unsigned char id=0,re_disp=0; //定义用到的变量,id为调整模式用,不为0时表示调整模式,调整哪个量由id值确定
- //时间到取反flag标志位,re_disp记数200次共10s,调整状态下按键无操作10s自动返回正常显示状态
- bit hour,minute,second,flag,year,month,date,day; //定义位变量,hour,minute,second分别为调整时闪烁标志位,flag 500ms取反一次,调整位闪烁及冒号闪烁用
- bit ReadTimeFlag;//定义读时间标志
- unsigned char code dofly_DuanMa[10]={0xf0,0xf8,0xf1,0xf9,0xf2,0xfa,0xf3,0xfb,0xf4,0xfc};// 显示段码值0~9
- unsigned char code dofly_WeiMa[]={0xef,0xdf,0xcf,0xbf,0xaf,0x9f};//分别对应相应的数码管点亮,即位码
- unsigned char TempData[8]; //存储显示值的全局变量
- void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
- void Scan_Key(void);//按键
- void Init_Timer0(void);//定时器0初始化
- void Init_Timer1(void); //定时器1初始化
- void display8(void);//显示方式
- void id_case1_key(void);//键值处理
- void Set_id(unsigned char ,unsigned char); //加减变量函数
- unsigned char displaynum; //显示方式标志
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void main ()
- {
-
- Init_Timer0();
- Init_Timer1();
- if(!UP&!DOWN)Ds1302_Init(); //如果同时按下UP和DOWN键则初始化1302,该语句在while(1)前,只执行一次,需要复位,防止误操作
- Ds1302_Write_Time();
- while (1) //主循环
- {
- id_case1_key();
- Scan_Key();
- }
- }
- ------------------------------------------------*/
- /*------------------------------------------------
- 显示函数,用于动态扫描数码管
- 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
- 如输入0表示从第一个显示。
- Num表示需要显示的位数,如需要显示99两位数值则该值输入2
- ------------------------------------------------*/
- void Display(unsigned char FirstBit,unsigned char Num)
- {
- static unsigned char i=0;
-
- DataPort=0; //清空数据,防止有交替重影
- DataPort=dofly_WeiMa[i+FirstBit]&TempData[i];
-
- i++;
- if(i==Num)
- i=0;
- }
- /*------------------------------------------------
- 定时器0初始化子程序
- ------------------------------------------------*/
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- //TH0=0x00; //给定初值
- //TL0=0x00;
- EA=1; //总中断打开
- ET0=1; //定时器中断打开
- TR0=1; //定时器开关打开
- }
- /*------------------------------------------------
- 定时器1初始化子程序
- ------------------------------------------------*/
- void Init_Timer1(void)
- {
- TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- //TH1=0x00; //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
- // TL1=0x00;
- EA=1; //总中断打开
- ET1=1; //定时器中断打开
- TR1=1; //定时器开关打开
- }
- /*------------------------------------------------
- 定时器0中断子程序
- ------------------------------------------------*/
- void Timer0_isr(void) interrupt 1
- {
- static unsigned int num,a;
- TH0=(65536-2000)/256; //重新赋值 2ms
- TL0=(65536-2000)%256;
-
- Display(0,6); // 调用数码管扫描
- num++;
- if(num==50) //大致100ms
- {
- num=0;
- ReadTimeFlag=1; //读标志位置1
- }
- a++; //秒闪
- if(a<=250)led=1;
- if(a>250)led=0;
- if(a==500)a=0;
- }
- /*------------------------------------------------
- 定时器1中断子程序
- ------------------------------------------------*/
- void Timer1_isr(void) interrupt 3 using 1 //中断处理程序,主要用于取反标志位,返回正常显示状态
- {
- unsigned char timecount;
- TH1=(65535-50000)/256; //50ms定时
- TL1=(65535-50000)%256;
- timecount++;re_disp++;
-
- if(timecount>9)
- {
- timecount=0;
- flag=~flag;
- }
- if(re_disp>150){re_disp=0;if(id)id=0;}
- }
- /*---------------------------------------------------------
- 显示方式
- ---------------------------------------------------------*/
- void display8(void)
- {
- if(ReadTimeFlag==1)
- {
- ReadTimeFlag=0;
- Ds1302_Read_Time();
- }
- if(displaynum==0) //显示时间
- {
- if(flag&hour) //如hour为1表示调整时,flag为1时不显示
- {
- TempData[0]=0; //这句中的0xff是数码管的灭码
- TempData[1]=0;
- }
- else //flag为0时显示,产生闪烁效果,下同
- {
- TempData[0]=dofly_DuanMa[time_buf1[4]/10];//时 //数据的转换,
- TempData[1]=dofly_DuanMa[time_buf1[4]%10];//因我们采用数码管0~9的显示,将数据分开
- }
- if(flag&minute) //分
- {
- TempData[2]=0; //这句中的0xff是数码管的灭码
- TempData[3]=0;
- }
- else
- {
- TempData[2]=dofly_DuanMa[time_buf1[5]/10];//分
- TempData[3]=dofly_DuanMa[time_buf1[5]%10];
- }
- if(flag&second) //秒
- {
- TempData[4]=0; //这句中的0xff是数码管的灭码
- TempData[5]=0;
- }
- else
- {
- TempData[4]=dofly_DuanMa[time_buf1[6]/10];//秒
- TempData[5]=dofly_DuanMa[time_buf1[6]%10];
- }
- }
- if(displaynum==1)//显示日期
- {
- led=0;
- if(flag&year)
- {
- TempData[0]=0; //这句中的0xff是数码管的灭码
- TempData[1]=0;
- }
- else
- {
- TempData[0]=dofly_DuanMa[time_buf1[1]/10];//年
- TempData[1]=dofly_DuanMa[time_buf1[1]%10];
- }
- if(flag&month)
- {
- TempData[2]=0; //这句中的0xff是数码管的灭码
- TempData[3]=0;
- }
- else
- {
- TempData[2]=dofly_DuanMa[time_buf1[2]/10];//月
- TempData[3]=dofly_DuanMa[time_buf1[2]%10];
- }
- if(flag&date)
- {
- TempData[4]=0; //这句中的0xff是数码管的灭码
- TempData[5]=0;
- }
- else
- {
- TempData[4]=dofly_DuanMa[time_buf1[3]/10];//日
- TempData[5]=dofly_DuanMa[time_buf1[3]%10];
- }
- }
- if(displaynum==2)//显示周 秒
- {
- led=1;
- if(flag&day)
- {
- TempData[1]=0xff;
- }
- else
- {
- TempData[0]=0xff;
- TempData[1]=dofly_DuanMa[time_buf1[7]%10];//周
- TempData[2]=0xff;
- TempData[3]=0xff;
- TempData[4]=dofly_DuanMa[time_buf1[6]/10];//秒
- TempData[5]=dofly_DuanMa[time_buf1[6]%10];
- }
- }
-
- }
- /*------------------------------------------------
- 键盘检测函数
- ------------------------------------------------*/
- void Scan_Key(void) //键盘检测函数
- {
- display8(); //程序开头调用显示函数
- if(!SET)
- {
- while(!SET);display8(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
- re_disp=0; //清除记数,重新开始10s定时
- id++;
- if(id>7)id=0; //id加1,后面根据id值对应调整项目
- }
- if(id==0){hour=0;minute=0;second=0;year=0;month=0;date=0;day=0;} //根据id值跳到相应处理函数
- if(id==1){displaynum=0;hour=1;minute=0;second=0;year=0;month=0;date=0;day=0;id_case1_key();} //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同
- if(id==2){displaynum=0;hour=0;minute=1;second=0;year=0;month=0;date=0;day=0;id_case1_key();}
- if(id==3){displaynum=0;hour=0;minute=0;second=1;year=0;month=0;date=0;day=0;id_case1_key();}
- if(id==4){displaynum=1;hour=0;minute=0;second=0;year=1;month=0;date=0;day=0;id_case1_key();}
- if(id==5){displaynum=1;hour=0;minute=0;second=0;year=0;month=1;date=0;day=0;id_case1_key();}
- if(id==6){displaynum=1;hour=0;minute=0;second=0;year=0;month=0;date=1;day=0;id_case1_key();}
- if(id==7){displaynum=2;hour=0;minute=0;second=0;year=0;month=0;date=0;day=1;id_case1_key();}
- }
- /*-----------------------------------------------------
- 键盘处理函数
- -----------------------------------------------------*/
- void id_case1_key(void) //键盘处理函数,只有按下set键时才会进入,
- {
- display8();
- if (!DOWN) //减少
- {
- while(!DOWN)display8(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
- re_disp=0; //清除记数,重新开始10s定时
- Set_id(id,0); //跳到加减判断函数,下同,
- }
-
- if (!UP) //增加
- {
- while(!UP)display8();
- re_disp=0;
- Set_id(id,1);
- }
- }
- /*-------------------------------------------------------
- //根据选择调整相应项目并写入DS1302
- --------------------------------------------------------*/
- void Set_id(unsigned char sel,unsigned char sel_1) //执行调整项目的函数
- {
- if(sel==0) //时间、日期、周显示选择
- {
- if(sel_1==0)
- {
- displaynum++;
- if(displaynum==3)
- displaynum=0;
- }
- else
- {
- displaynum++;
- if(displaynum==3)
- displaynum=0;
- }
- }
- if(sel==1) //调时
- {
- if(sel_1==0)
- {
- time_buf1[4]--;if(time_buf1[4]==24)time_buf1[4]=0;
- }
- else
- {
- time_buf1[4]++;if(time_buf1[4]==24)time_buf1[4]=0;
- }
- Ds1302_Write_Time();
- }
- if(sel==2) //调分
- {
- if(sel_1==0)
- {
- time_buf1[5]--;if(time_buf1[5]==59)time_buf1[5]=0;
- }
- else
- {
- time_buf1[5]++;if(time_buf1[5]==59)time_buf1[5]=0;
- }
- Ds1302_Write_Time();
- }
- if(sel==3) //调秒
- {
- if(sel_1==0)
- {
- time_buf1[6]--;if(time_buf1[6]==0)time_buf1[6]=0;
- }
- else
- {
- time_buf1[6]++;if(time_buf1[6]==0)time_buf1[6]=0;
- }
- Ds1302_Write_Time();
- }
- if(sel==4) //调年
- {
- if(sel_1==0)
- {
- time_buf1[1]--;if(time_buf1[1]==99)time_buf1[1]=15;
- }
- else
- {
- time_buf1[1]++;if(time_buf1[1]==99)time_buf1[1]=15;
- }
- Ds1302_Write_Time();
- }
- if(sel==5) //调月
- {
- if(sel_1==0)
- {
- time_buf1[2]--;if(time_buf1[2]==13)time_buf1[2]=1;
- }
- else
- {
- time_buf1[2]++;if(time_buf1[2]==13)time_buf1[2]=1;
- }
- Ds1302_Write_Time();
- }
- if(sel==6) //调日
- {
- if(sel_1==0)
- {
- time_buf1[3]--;if(time_buf1[3]==32)time_buf1[3]=1;
- }
- else
- {
- time_buf1[3]++;if(time_buf1[3]==32)time_buf1[3]=1;
- }
- Ds1302_Write_Time();
- }
-
-
- if(sel==7) //调周
- {
- if(sel_1==0)
- {
- time_buf1[7]--;if(time_buf1[7]==8)time_buf1[7]=1;
- }
- else
- {
- time_buf1[7]++;if(time_buf1[7]==8)time_buf1[7]=1;
- }
- Ds1302_Write_Time();
- }
- }
复制代码 |