微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 没有延时的小时钟

没有延时的小时钟

时间:10-02 整理:3721RD 点击:

项目:简单的时钟(2015-2-20)

设计要求:带冒号的4位数码管显示时间(MT05643DR)、按键设置时间





分析:本例是简单的时钟,因此采用单片机定时器提供时钟源。时间设置采用按键调节,用两个按键,一个负责小时的增加设置,另一个负责分钟的增加。

单片机STC12C2052AD20脚,晶振采用12M。

引脚分配:P1.0----P1.7  a b c d e f g :

P3.0 按键1 数码管小时加1按键

P3.1 按键2 数码管上分钟加1设置按键

P3.2----P3.5  4位数码管  

程序流程:

#include <reg52.h>

sbit Key1=P3^0;  //定义2个按键用于调整时间

sbit Key2=P3^1;

sbit Wei1=P3^2;      //四位数码管定义端口

sbit Wei2=P3^3;      //

sbit Wei3=P3^4;

sbit Wei4=P3^5;

unsigned char code LEDchar[]={

       0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};    //数码管0-9真值表

unsigned charLedBuff[4]={0xff,0xff,0xff,0xff}; //4位数码管显示数字缓存

unsigned int ms=0;//定义毫秒全局变量

unsigned char miao=0,fen=59,shi=23;//秒,分,时 全局变量

bit keyst1=1;

bit keyst2=1;

bit backup1=1;

bit backup2=1;

void Time0int()//

{

       TMOD=0x01; //定时模式1,16位定时器

       TH0=0xF8;//初值计算公式 65536-(定时时间(2ms=2000us)/1us(晶振12M的计数周期时间))=63536

       TL0=0x30;//63536转换为16进制为 F830H 分配给定时器TH0 TL0 就可以了

       EA=1;//开总中断

       ET0=1;//打开定时器0中断

       TR0=1;//定时器0开始运行

}

void ShowNumber(unsigned int num)  //显示数字函数,参数是1个短整形的数字num

{

       signedchar i;              //定义变量i用于循环数的位数

       unsignedchar buf[4];       //定义一个数组用于保存分离出来各位的数据

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

       {

              buf= num % 10;   

              num= num / 10;

       }                       //上面2个语句就是循环4次,把1个4位数进行按位分离后存放在数组buf中

       for(i=3;i>=1; i--)         //进行首位是零,不显示

       {

              if(buf== 0)     //如果首位是零,则把数码管显示缓存数据为0XFF,由于是共阳极数码管,如果数据是0xff 则数码管不显示

              {

                     LedBuff= 0xFF;

              }

              else               //如果首位不是零,则跳出循环

                     break;

       }

      

       for(;i>=0; i--)           //i继承了上面语句的数值,把该位的数字通过Ledchar[buf]数组,进行转换为该数字的显示数据并赋值给数码管显示缓存

       {

              LedBuff= LEDchar[buf];     

       }

}

unsigned int num(unsigned charhour,unsigned char minute)  //2个8位数据类型变量,合并连接为16位数据来信变量

{

       unsignedint date;

       date=100*hour+minute;

       returndate;

}

void main()

{

       P1=LEDchar[0];

       Time0int();//定时器初始化

       while(1)

       {

              ShowNumber(num(shi,fen));

              if(keyst1!=backup1)

              {

                     if(keyst1==0)

                     {

                            shi++;

                     }

                     backup1=Key1;

              }

             if(keyst2!=backup2)

              {

                     if(keyst2==0)

                     {

                            fen++;

                     }

                     backup2=Key2;

              }

       }   

}

void interruptTimer0() interrupt 1

{

       staticunsigned char i;

       staticunsigned char keybuf1=0xff;

       staticunsigned char keybuf2=0xff;

       TH0=0xf8;     //定时器初值重新赋值

       TL0=0x30;

       ms++;             //利用2毫秒定时器中断来进行时间的累计并把累计次数赋值给时间变量

       if(ms>=500)

       {

              ms=0;

              miao++;

       }

       if(miao>=60)

       {

              miao=0;

              fen++;

       }

       if(fen>=60)

       {

              fen=0;

              shi++;

       }

       if(shi>=24)

       {

              shi=0;

       }

       switch(i)//每次进入中断进行1位数码管的显示刷新,5次耗时10ms

       {

             case0: Wei4=1;Wei3=1;Wei1=0;i++;P1=LedBuff[3];break;

            case1: Wei1=1;Wei2=0;i++;P1=LedBuff[2];break;

           case 2:Wei2=1;Wei3=0;i++;P1=LedBuff[1];break;

              case3: Wei3=1;Wei4=0;i++;P1=LedBuff[0];break;

              case4:

              {

                     Wei3=0;i=0;

                     if(ms<=250)

                            P1=0x7F;  //显示数码管上的冒号

                     else

                         P1=0xff;  //关闭冒号

                     break;

              }

              default:break;

       }

       keybuf1=(keybuf1<<1)|Key1;        //按键扫描利用中断每2ms检测1次按键状态,把状态值放入keybuf变量中

       if(keybuf1==0x00)  //经过8次中断,如果keybuf变量时0x00,则按键为按下状态,

              keyst1=0;

       elseif(keybuf1==0xff)  //经过8次中断,如果keybuf变量时0xff,则按键为弹起状态,

              keyst1=1;

       keybuf2=(keybuf2<<1)|Key2;

       if(keybuf2==0x00)

              keyst2=0;

       elseif(keybuf2==0xff)

              keyst2=1;

}




Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top