嵌入式 > 技术百科 > 详情

用定时器中断设计秒表 用数码管显示

发布时间:2020-09-22 发布时间:
|
//此秒表有时分秒和毫秒位,最多可以记小时,有暂停和继续计时功能,独立键盘上key1为暂停和继续键,key3为复位和开始计时键

//由于ms中断时间很短,所以如果中断和显示延迟关系处理不好,秒表走时不准,应注意

 

 

#include

#define uchar unsigned char

#define uint unsigned int

uchar code table[]={0x 3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};       // 时分秒的个位显示后带小数点

uchar ms,s,m,h,count,count1;

sbit k1=P3^0;

sbit k3=P3^2;

 

void delay(uint z)

{

     uint x,y;

     for(x=z;x>0;x--)

       for(y=110;y>0;y--);

}

 

 

 

void displays(uchar temp)      //数码管动态显示秒位函数

{

     uchar shi,ge,i;

     i=0;

     shi=temp/10;

     ge=temp;

 

    

        

         P0=0xef;

         P1=table[shi];

         delay(1);              //必须要有延迟,动态扫描,为了不影响整个秒表八位数的扫描速率提高显示效果,延迟又不要太高,ms比较合适       

    

         P0=0xdf;

         P1=table1[ge];

         i=0;

         delay(1);

    

}

 

void displayms(uchar temp)      //数码管动态显示毫秒位函数

{

     uchar shi,ge,i;

     i=0;

     shi=temp/10;

     ge=temp;

 

    

        

         P0=0xbf;

         P1=table[shi];

         delay(1);

    

         P0=0x7f;

         P1=table[ge];

         i=0;

         delay(1);

    

}

 

void displaym(uchar temp)      //数码管动态显示分位函数

{

     uchar shi,ge,i;

     i=0;

     shi=temp/10;

     ge=temp;

 

    

        

         P0=0xfb;

         P1=table[shi];

         delay(1);

    

         P0=0xf7;

         P1=table1[ge];

         i=0;

         delay(1);

    

}

 

void displayh(uchar temp)      //数码管动态显示小时位函数

{

     uchar shi,ge,i;

     i=0;

     shi=temp/10;

     ge=temp;

 

    

        

         P0=0xfe;

         P1=table[shi];

         delay(1);

    

         P0=0xfd;

         P1=table1[ge];

         i=0;

         delay(1);

    

}

 

 

 

void keyscan()           //键盘扫描函数

{

     if(k1==0)

     {

     delay(5);

     if(k1==0)           //检测k1确实被按下防抖动

     {

         count++;

         while(!k1);        //检测松手

         delay(1);           // 检测确实松手

         while(!k1);

 

         if(count==1)

         TR0=0;               //暂停定时器

         if(count==2)

         {

              TR0=1;           //定时器继续计时

              count=0;

         }

     }

     }

     if(k3==0)

     {

     delay(5);

     if(k3==0)

     {

         count1++;

         while(!k3);

         delay(1);

         while(!k3);

         if(count1==1)    // 复位秒表

         {

         TR0=0;              

         ms=0;

         s=0;

         m=0;

         h=0;

         }

         if(count1==2)     //重新开始计时        

         {

              TR0=1;          

              count1=0;

         }

     }

     }

}

 

void main()

{

 

     TMOD=0x01;

     EA=1;

     ET0=1;

     TR0=1;

     TH0=(65536-10000)/256;         //设定定时器初值

     TL0=(65536-10000)%6;         //12M晶振时ms数为

     while(1)

     {

     keyscan();

     displays(s);                //数码管动态扫描秒位显示

     displayms(ms);                 //数码管动态扫描毫秒位显示

     displaym(m);                //数码管动态扫描秒分显示

     displayh(h);                 //数码管动态扫描秒小时显示

     }

}

 

void timer0() interrupt 1           //中断服务程序

{

     TH0=(65536-10000)/256;

     TL0=(65536-10000)%6;

     ms++;

     if(ms==100)                     //定时器中断次为s

     {                             //把这部分放在中断中,能减少程序执行时间对中断时间的影响

         ms=0;

         s++;

         if(s==60)

         {

         s=0;

          m++;

         }

         if(m==60)

         {

              m=0;

              h++;

         }

         if(h==24)

         {

              h=0;

         }

     }   

}

 




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
用于MAX7456随屏显示器SPI