一个时钟设计的程序.docx

上传人:b****6 文档编号:16569998 上传时间:2023-07-14 格式:DOCX 页数:29 大小:22.48KB
下载 相关 举报
一个时钟设计的程序.docx_第1页
第1页 / 共29页
一个时钟设计的程序.docx_第2页
第2页 / 共29页
一个时钟设计的程序.docx_第3页
第3页 / 共29页
一个时钟设计的程序.docx_第4页
第4页 / 共29页
一个时钟设计的程序.docx_第5页
第5页 / 共29页
一个时钟设计的程序.docx_第6页
第6页 / 共29页
一个时钟设计的程序.docx_第7页
第7页 / 共29页
一个时钟设计的程序.docx_第8页
第8页 / 共29页
一个时钟设计的程序.docx_第9页
第9页 / 共29页
一个时钟设计的程序.docx_第10页
第10页 / 共29页
一个时钟设计的程序.docx_第11页
第11页 / 共29页
一个时钟设计的程序.docx_第12页
第12页 / 共29页
一个时钟设计的程序.docx_第13页
第13页 / 共29页
一个时钟设计的程序.docx_第14页
第14页 / 共29页
一个时钟设计的程序.docx_第15页
第15页 / 共29页
一个时钟设计的程序.docx_第16页
第16页 / 共29页
一个时钟设计的程序.docx_第17页
第17页 / 共29页
一个时钟设计的程序.docx_第18页
第18页 / 共29页
一个时钟设计的程序.docx_第19页
第19页 / 共29页
一个时钟设计的程序.docx_第20页
第20页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

一个时钟设计的程序.docx

《一个时钟设计的程序.docx》由会员分享,可在线阅读,更多相关《一个时钟设计的程序.docx(29页珍藏版)》请在冰点文库上搜索。

一个时钟设计的程序.docx

一个时钟设计的程序

/*      电子日历,有时间显示、闹铃、日期、秒表及键盘设置功能              */

/*功能键A:

  设置位数字+1     闹钟模式下为闹钟开关 秒表模式下为记时开关 */

/*功能键B:

  设置位数字-1     闹钟模式下为闹钟开关                       */

/*功能键C:

设置模式及设置位选择                      秒表模式下为清零键   */                        

/*功能键D:

在四种工作模式下切换设置闹钟开关                               */      

/*                   曹宇 03电子 0201029                                */

/*                     2006.6.3 更新                                    */

/****************************************************************************/

#include

#include

/***************这里设置程序初始化时显示的时间****************/

#defineSET_HOUR12  /*设置初始化小时*/

#defineSET_MINUTE00  /*设置初始化分钟*/

#defineSET_SECOND00  /*设置初始化秒数*/

/*************************系统地址****************************/

#defineBASE_PORT0x8000 /*选通基地址*/

#defineKEY_LINEBASE_PORT+1 /*键盘行线地址*/

#defineKEY_COLUMNBASE_PORT+2 /*键盘列线地址*/

#defineLED_SEGBASE_PORT+4 /*数码管段选地址*/

#defineLED_BITBASE_PORT+2 /*数码管位选地址*/

#defineLED_ON(x)XBYTE[LED_BIT]=(0x01<

#defineLED_OFFXBYTE[LED_SEG]=0x00  /*LED显示空*/

/**************在设置模式下对秒分时的宏定义*****************/

#defineSECOND0  /*对应数码管右边两位*/

#defineMINUTE1  /*对应数码管中间两位*/

#defineHOUR2    /*对应数码管左边两位*/

/********************定义四种工作模式***********************/

#defineCLOCKclockstr/*时钟模式*/

#defineALARTalartstr/*闹钟模式*/

#defineDATEdatestr  /*日期模式*/

#defineTIMERtimerstr/*秒表模式*/

/****************以下是所有子函数的声明*********************/

voidsys_init(void);                   /*系统的初始化程序*/

voiddisplay(void);   /*动态刷新一次数码管子程序*/

voidclockplus(void);   /*时间加1S的子程序*/

voidupdate_clockstr(void);  /*更新时间显示编码*/

voidupdate_alartstr(void);            /*更新闹钟时间的显示编码*/

voidupdate_datestr(void);  /*更新日期显示编码*/

voidupdate_timerstr(void);            /*更新秒表时间的显示编码*/

voiddeley(int);   /*延时子程序*/

voidupdate_dispbuf(unsignedchar*); /*更新显示缓冲区*/

unsignedchargetkeycode(void);  /*获取键值子程序*/

voidkeyprocess(unsignedchar);  /*键值处理子程序*/

unsignedchargetmonthdays(unsignedint,unsignedchar);/*计算某月的天数子程序*/

/*功能键功能子函数*/

voidAkey(void);   /*当前设置位+1开关闹钟开关秒表*/

voidBkey(void);   /*当前设置位-1开关闹钟*/

voidCkey(void);   /*设置位选择 秒表清零*/

voidDkey(void);   /*切换四种工作模式*/

/**********************全局变量声明部分*********************/

unsignedcharled[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};/*从0~9的LED编码*/

unsignedcharledchar[3]={0x5c,0x54,0x71};/*onf*/

//unsignedcharkey[24]={  /*键值代码数组对应键位:

*/

// 0x70,0x71,0x72,0x73,0x74,0x75, /* 7 8 9 ATRACERESET*/

// 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, /* 4 5 6 BSTEP  MON*/

// 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, /* 1 2 3 CHERE LAST*/

// 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5}; /* 0 F E DEXEC NEXT*/

struct{       /*时间结构体变量*/

 unsignedchars;

 unsignedcharm;

 unsignedcharh;

 }clock={SET_SECOND,SET_MINUTE,SET_HOUR};

struct{                                 /*闹铃时间结构体变量*/

 unsignedcharm;

 unsignedcharh;

 }alart={SET_MINUTE,SET_HOUR};

struct{                                /*日期结构体变量*/

       unsignedintyear;

       unsignedcharmonth;

       unsignedcharday;

       }date={6,1,1};

struct{                                /*秒表时间结构体变量*/

       unsignedcharms;

       unsignedchars;

       unsignedcharm;

       }timer={0,0,0};

unsignedchardispbuf[6]; /*显示缓冲区数组*/

unsignedcharclockstr[6]; /*时间显示的数码管编码数组*/

unsignedcharalartstr[6]; /*闹钟显示的数码管编码数组*/

unsignedchardatestr[6]; /*日期显示的数码管编码数组*/

unsignedchartimerstr[6];     /*秒表显示的数码管编码数组*/

unsignedintitime=0,idot; /*定时器0中断计数*/

unsignedcharitime1=0; /*定时器1中断计数*/

sbitP3_1=P3^1;   /*外接蜂鸣器的管脚*/

bdatabitIsSet=0;  /*设置模式标志位 0:

正常走时1:

设置模式*/

bdatabitAlart_EN=0;  /*闹铃功能允许位 0:

禁止闹铃1:

允许闹铃*/

bdatabitIsBeep=0;            /*响铃标志位     0:

未响铃  1:

正在响铃*/

unsignedcharSetSelect=0; /*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/

unsignedchar*CurrentMode;/*标志当前正设置的功能,如CurrentMode=CLOCK或CurrentMode=ALART等*/

voidtimerplus(void);

/**************************函数部分*************************/

voidmain(void)

{

       sys_init();

   while

(1)

 {

  XBYTE[KEY_COLUMN,0x00];   /*给键盘列线赋全零扫描码,判断是否有键按下  */

  while((XBYTE[KEY_LINE]&0x0f)==0x0f) /*检测是否有键按下,无则一直进行LED的刷新显示*/

               {

                if(Alart_EN&&(clock.h==alart.h)&&(clock.m==alart.m)){IsBeep=1;}

                else

                {IsBeep=0;

                 P3_1=0;}

                display();

               }

  keyprocess(getkeycode());  /*有键按下时得到键值,并送入键值处理程序*/

               display();    /*可要可不要*/

 }

}

voidsys_init(void)

{

 TMOD=0x22; /*定时器0和1都设置为工作方式2,基准定时250×2=500us=0.5ms*/

 TH0=6;         /*定时器0中断服务用来产生1秒时钟定时及闹钟蜂鸣器蜂鸣脉冲*/

 TL0=6;         /*定时器1中断服务留给秒表使用,产生1/100秒定时*/

       TH1=6;

       TL1=6;

       ET0=1;

       ET1=1;

       EA=1;

 TR0=1;

       update_clockstr(); /*初始化时钟显示编码数组*/

       update_alartstr();      /*初始化闹钟显示编码数组*/

       update_datestr();       /*初始化日期显示编码数组*/

       update_timerstr();      /*初始化秒表显示编码数组*/

       update_dispbuf(clockstr);/*初始化显示缓冲数组*/

       CurrentMode=CLOCK;      /*默认的显示摸式为时钟*/

       P3_1=0;                 /*蜂鸣器接线引脚复位*/

}

voidtimer0(void)interrupt1using1 /*定时器0中断服务器,用来产生1秒定时*/

{

 itime++;

 if(itime==1000)

 {

               if(IsSet) /*在设置模式下,对正在设置的位闪烁显示*/

  {

                       dispbuf[SetSelect*2]=0; /*对正在设置的位所对应的显示缓冲区元素赋0,使LED灭*/

         dispbuf[SetSelect*2+1]=0;

               }

               if(IsBeep)P3_1=!

P3_1; /*闹钟模式时,产生峰鸣器响脉冲*/

               if(CurrentMode==CLOCK)

               {

                       dispbuf[2]=dispbuf[2]&0x7f;

                       dispbuf[4]=dispbuf[4]&0x7f;

               }

 }

 if(itime==2000)   /*两千次计数为1S 2000×0.5ms=1s*/

 {

  itime=0;   /*定时1s时间到,软计数清零*/

  clockplus();   /*时间结构体变量秒数加1*/

  update_clockstr();  /*更新时间显示编码数组*/

         if(CurrentMode!

=TIMER)update_dispbuf(CurrentMode); /*用时间编码数组更新显示缓冲区*/

 }

}

voidtimer1(void)interrupt3using2   /*定时器1中断服务器,用来产生1/100秒定时*/

{

 idot++;

 if(++itime1==20)      /*20*0.5ms=10ms*/

 {

       itime1=0;

       timerplus();

       update_timerstr();

       if(CurrentMode==TIMER)

       {

        update_dispbuf(timerstr);

        dispbuf[2]=dispbuf[2]&0x7f;   /*关闭小数点的显示*/

        dispbuf[4]=dispbuf[4]&0x7f;

        if(idot<1000)                 /*闪烁显示小数点*/

        {

               dispbuf[2]=dispbuf[2]|0x80;

               dispbuf[4]=dispbuf[4]|0x80;

        }else{

               dispbuf[2]=dispbuf[2]&0x7f;

               dispbuf[4]=dispbuf[4]&0x7f;

              }

       }

       

 }

 if(idot==2000)idot=0;

}

/*功能模块子函数*/

voidclockplus(void)  /*时间加1s判断分,时子函数*/

{

 if(++clock.s==60)  /*秒位判断*/

 {

  clock.s=0;

 if(++clock.m==60) /*分位判断*/

 {

 clock.m=0;

 if(++clock.h==24) /*时位判断*/

 {

         clock.h=0;

         if(++date.day==(getmonthdays(date.year,date.month)+1))

         {

          date.day=1;

          if(++date.month==13)date.month=1;

         }

        }

 }

 }

}

voidtimerplus()       /*秒表1/100秒位加1,判断秒、分子程序*/

{

 if(++timer.ms==100)

 {

       timer.ms=0;

       if(++timer.s==60)

       {

        timer.s=0;

        if(++timer.m==60)

        {

         timer.m=0;

        }      

       }

 }        

}

voidupdate_clockstr(void) /*更新时钟显示代码数组clockstr*/

{

 clockstr[0]=led[clock.s%10];  /*给元素0赋相应数码管显示编码,编码序号是秒数的个位*/

 clockstr[1]=led[(int)(clock.s/10)]; /*给元素1赋相应数码管显示编码,编码序号是秒数的十位*/

 clockstr[2]=led[clock.m%10];  /*以下类推*/

 clockstr[3]=led[(int)(clock.m/10)];

 clockstr[4]=led[clock.h%10];

 clockstr[5]=led[(int)(clock.h/10)];

}

voidupdate_alartstr(void)     /*更新闹钟显示代码数组alartstr*/

{                              /*右边两位显示on:

闹钟开启 of:

闹钟关闭*/

       if(Alart_EN)alartstr[0]=ledchar[1];/*显示字母n*/

       elsealartstr[0]=ledchar[2];       /*显示字母f*/

       alartstr[1]=ledchar[0];            /*显示字母o*/

       alartstr[2]=led[alart.m%10];

       alartstr[3]=led[(int)(alart.m/10)];

       alartstr[4]=led[alart.h%10];

       alartstr[5]=led[(int)(alart.h/10)];

}

voidupdate_datestr(void)      /*更新日期显示代码数组datestr*/

{

       datestr[0]=led[date.day%10];

       datestr[1]=led[(int)(date.day/10)];

       datestr[2]=led[date.month%10];

       datestr[3]=led[(int)(date.month/10)];

       datestr[4]=led[date.year%10];

       datestr[5]=led[(int)(date.year/10)];

}

voidupdate_timerstr(void)     /*更新秒表显示代码数组timerstr*/

{

       timerstr[0]=led[timer.ms%10];

       timerstr[1]=led[(int)(timer.ms/10)];

       timerstr[2]=led[timer.s%10];

       timerstr[3]=led[(int)(timer.s/10)];

       timerstr[4]=led[timer.m%10];

       timerstr[5]=led[(int)(timer.m/10)];

}

voiddisplay(void)       /*刷新显示六位LED一次*/

{

 unsignedchari;

 for(i=0;i<6;i++)

 {

  LED_ON(i);   /*选通相应位*/

  XBYTE[LED_SEG]=dispbuf[i]; /*写显示段码*/

               deley(50);   /*延时显示*/

  LED_OFF;   /*写LED全灭段码*/

 }

}

voidupdate_dispbuf(unsignedchar*str)   /*更新显示缓冲区子函数,参数为要用来更新缓冲区的源字符数组的首地址*/

{

       dispbuf[0]=str[0]; /*将要更新的源字符数组内容COPY至dispbuf数组,用作显示缓冲区*/

       dispbuf[1]=str[1];

       dispbuf[2]=str[2]|0x80;/*默认把时位和分位后面的小数点显示出来,根据需要再取舍*/

       dispbuf[3]=str[3];

       dispbuf[4]=str[4]|0x80;

       dispbuf[5]=str[5];

}

voiddeley(inti) /*延时子函数*/

{

  while(i--);

}

unsignedchargetkeycode(void) /*键盘扫描子程序,返回获得的键码*/

{

 unsignedcharkeycode;  /*键码变量,一开始存行码*/

 unsignedcharscancode=0x20; /*列扫描码*/

 unsignedcharicolumn=0; /*键的列号*/

       display();                     /*用刷新数码管显示的时间去抖*/

       XBYTE[KEY_COLUMN]=0x00;

 keycode=XBYTE[KEY_LINE]&0x0f; /*从行端口读入四位行码*/

 while((scancode&0x3f)!

=0) /*取scancode的低六位,只要没变为全0,则执行循环*/

 {

  XBYTE[KEY_COLUMN]=(~scancode)&0x3f; /*给列赋扫描码,第一次为011111*/

  if((XBYTE[KEY_LINE]&0x0f)==keycode)break; /*检测按键所在的列跳出循环*/

               scancode=scancode>>1; /*列扫描码右移一位*/

  icolumn++;  /*列号加1*/

       }

 keycode=keycode<<4;  /*把行码移到高四位*/

 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 教学研究 > 教学计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2