找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2271|回复: 5
打印 上一主题 下一主题
收起左侧

单片机数码时钟调节时分秒的时候怎么让调节位闪烁?求大佬指点

[复制链接]
跳转到指定楼层
楼主
1黑币
#include<reg51.h>
sbit key_1=P1^0        ;  //秒、分、时间的切换键
sbit key_2=P1^1        ;  //加1
sbit key_3=P1^2        ;  //减1
sbit key_4=P1^3        ;  //ok
sbit speaker_= P3^1;
unsigned char code table1[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //笔段码
unsigned char code table2[ ]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};                  //位选码
unsigned char count1=0 ;
/****************************************************/
        
unsigned char hour = 12, min = 0,sec = 0;         //时钟赋初值

/******************T0__50mS中断程序*******************/

void  T0_1s(void) interrupt 1                  // 50mS中断程序
{
    static unsigned char count = 0;
    TR0 = 0;
    TH0 = (65536 - 50000 ) / 256;         //设置T0初始值为:15536
         TL0 = (65536 - 50000 ) % 256;         //记数为50000次//50000*1us=50ms*20=1s
    TR0 = 1;
        count++;
        
        if(count == 20)                   //中断服务程序
                {                                        //定时1s时间到(需要中断20次)
                          count = 0;
                        sec++;
                          if(sec==60)          //1分钟时间到
                              {
                            sec=0;
                                   min++;
                                   if(min==60)                 //1小时时间到
                                   {
                                     min=0;
                                    hour++;   
                                    if(hour==24)        //24小时时间到
                                      {
                                       sec =0;
                                        min =0;
                                        hour=0;
                                     }
                                   }
                            }
                }
}

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

void delay_5ms()   //动态扫描显示--软件延时
{
        unsigned char i,j;
        for(i=0;i<20;i++)
                 for(j=0;j<50;j++)             //50
                ;

}
  void delay_500ms()   //500ms延时
{
  unsigned char a,b;
  for(a=500;a>0;a--)
     for(b=110;b>0;b--)            //500
           ;
  }
/*****************************************************************/
void disp_led()
{
/****************显示时钟 ******************************/
                           P0=table1[hour/10];                //显示小时十位数
                        P2=table2[0];                          
                        delay_5ms();        
                        P0=0xff;     //共阳空字形
                        

                        P0=table1[hour%10];                   //显示小时个位数
                         P2=table2[1];                           
                        delay_5ms();         
                        P0=0xff;
                        
                         P0=0xbf;                                  //显示分隔符'-'   
                         P2=table2[2];                           
                        delay_5ms();         
                        P0=0xff;
                 

                           P0=table1[min/10];                  //显示分钟十位数  
                        P2=table2[3];                           
                        delay_5ms();         
                        P0=0xff;
                          
                        P0=table1[min%10];                  //显示分钟个位数      
                         P2=table2[4];                           
                        delay_5ms();         
                        P0=0xff;
                                                                          
                          P0=0xbf;                               //显示分隔符'-'
                         P2=table2[5];                           
                        delay_5ms();         
                        P0=0xff;
                        

                        P0=table1[sec/10];                   //显示秒十位数   
                        P2=table2[6];                        
                        delay_5ms();            
                        P0=0xff;
                          
                        P0=table1[sec%10];                  //显示秒个位数      
                        P2=table2[7];                        
                        delay_5ms();         
                        P0=0xff;
}
/*******************闹钟程序****************************/
void clock()
{        unsigned int i;
        if(hour==12 && min==0 && sec==30)           
        {        speaker_=0;
                for(i=0;i<500;i++)                        //15秒蜂鸣器
                        {
                                disp_led();
                        }
                speaker_=1;
        }
}
/*********************蜂鸣器按键声*****************************/
void speak()
{        unsigned char m;
        speaker_=0;
        for(m=0;m<3;m++)               
                {
                        disp_led();
                }
        speaker_=1;
}
/********************按键扫描程序***************************/
void delay_10ms()                   //键盘去抖动--软件延时                       
{
        unsigned char i,j;
        for(i=0;i<20;i++)
                 for(j=0;j<40;j++)  
                ;
}  
/*******************调时钟按键扫描*******************************/
void key_scan()                                           //键盘扫描子程序
{
if(key_1==0)                                //检测是否有键按下
        {           
                 delay_10ms();               //去抖动延时
                 if(key_1==0)                //再次确认否有键按下
                 {        {        speak();
                                 count1++;                //切换次数
                                TR0=0;                        //关计时
                        //        ET0=0;
                        }
                        if(count1==4)
                        {        count1=0;                 //到4次后重新记
                                TR0=1;                         //开计时
                                ET0=1;
                        }
                 }        
                while(key_1==0)                 disp_led(); //等待按键释放,并且调用显示程序                                
        }  
        if(count1==1)
        {        if(key_2==0)                //调整秒钟加//检测是否有键按下
                  {  
                                  delay_10ms();        //去抖动延时
                                   if(key_2==0)                     //再次确认否有键按下
                                {        speak();                  //按键声
                                        sec++;
                                        if(sec==60)        sec=0;
                                }
                                while(key_2==0) disp_led();  //等待按键释放,并且调用显示程序                                
                   }
                   if(key_3==0)                        //调整秒钟减//检测是否有键按下
                  {            
                                   delay_10ms();               //去抖动延时
                                    if(key_3==0)                    //再次确认否有键按下
                                 {        speak();
                                         sec--;
                                        if(sec==-1) sec=59;
                                       
                                 }        
                                 while(key_3==0) disp_led(); //等待按键释放,并且调用显示程序
                   }
                   if(key_4==0)// ok键//
                                {
                                         delay_10ms();
                                  if(key_4==0)
                                     {count1= 0;TR0=1;}
                                }
                          

        }
        if(count1==2)
        {
                if(key_2==0)                         //调整分钟加//检测是否有键按下
                  {           
                                  delay_10ms();            //去抖动延时
                                   if(key_2==0)                        //再次确认否有键按下
                                {        speak();
                                        min++;
                                        if(min==60)         min=0;
                                       
                                }        
                                while(key_2==0) disp_led();  //等待按键释放,并且调用显示程序                                
                   }
                   if(key_3==0)                         //调整分钟减//检测是否有键按下
                  {           
                                  delay_10ms();            //去抖动延时
                                   if(key_3==0)                        //再次确认否有键按下
                                {        speak();
                                        min--;
                                        if(min==-1)        min=59;
                                       
                                }        
                                while(key_3==0) disp_led();  //等待按键释放,并且调用显示程序                                
                  }
                 if(key_4==0)//调时结束键//
                                {
                                        delay_10ms();
                                  if(key_4==0)
                                   {
                                     count1 = 0; TR0=1; }
                                }
                          

        }
        if(count1==3)
        {         if(key_2==0)                         //调整小时加//检测是否有键按下
                  {            
                                  delay_10ms();            //去抖动延时
                                   if(key_2==0)                        //再次确认否有键按下
                                {        speak();
                                        hour++;
                                        if(hour==24)
                                                {        hour=0;
                                                        min=0;
                                                        sec=0;
                                                }
                                }        
                                while(key_2==0) disp_led();  //等待按键释放,并且调用显示程序                                
                   }
                   if(key_3==0)                         //调整小时减//检测是否有键按下
                   {           
                                  delay_10ms();            //去抖动延时
                                   if(key_3==0)                        //再次确认否有键按下
                                {        speak();
                                        hour--;
                                        if(hour==-1)        hour=23;
                                
                                }        
                                while(key_3==0) disp_led();  //等待按键释放,并且调用显示程序                                
                    }
                 if(key_4==0)//调时结束键//
                                {
                                        delay_10ms();
                                  if(key_4==0)
                                   {
                                     count1 = 0; TR0=1; }
                                }
                          
        }
}
/*********************主函数***********************/
void main()
{
        TMOD = 0x01;
    TH0 = (65536 - 50000 ) / 256;         //设置T0初始值
         TL0 = (65536 - 50000 ) % 256;

        ET0 = 1;           //开中断
        EA  = 1;            //开CPU
        TR0 = 1;           //开定时

        while(1)
        {
                disp_led();                 //时钟显示
                key_scan();                 //时钟扫描
        //        clock();             //闹钟
        }
}

1.png (93.04 KB, 下载次数: 26)

1.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:491577 发表于 2019-7-6 00:50 | 只看该作者
你的程序直接用学习板的程序是不行的,单片机学习板的程序只是为了说明单片机原理,真正的程序要多用中断,少用延时,这种语句 while(key_2==0)基本不用。实际按键程序不需要按键消抖,不需要等,实际按键程序需要放在约10-20ms中断中执行,数码管显示程序也是放在中断中执行的。你这个程序只要一按按键数码管显示就混乱。因为你的按键程序有待按键释放,按键后就不运行数码管显示程序了。
回复

使用道具 举报

板凳
ID:105364 发表于 2019-7-6 14:25 | 只看该作者
hhh402 发表于 2019-7-6 00:50
你的程序直接用学习板的程序是不行的,单片机学习板的程序只是为了说明单片机原理,真正的程序要多用中断, ...

“你这个程序只要一按按键数码管显示就混乱。因为你的按键程序有待按键释放,按键后就不运行数码管显示程序了。”


while(key_1==0)                 disp_led(); //等待按键释放,并且调用显示程序
没问题
回复

使用道具 举报

地板
ID:105364 发表于 2019-7-6 22:07 | 只看该作者
一、设个闪烁的标志,开定时中断T1,0.5秒求反一次。
void  T1_500ms(void) interrupt 3               
{
    static unsigned char count2 = 0;
    TR1 = 0;
    TH1 = (65536 - 50000 ) / 256;         //设置T1初始值为:15536
    TL1 = (65536 - 50000 ) % 256;         //记数为50000次//50000*1us=50ms
    TR1 = 1;
    count2++;
    if(count2 == 10)                 
    {
                count2 = 0;
                flag_flash=!flag_flash;// 调整时的闪烁标志
        }
}

二、显示函数里根据调秒和闪烁标志,控制显示和熄灭(这里仅以秒的闪烁为例)
P0=table1[sec/10];                   //显示秒十位数
if( count1==1&&flag_flash==1)
P2=0x00;
else
                           
                        P2=table2[6];                        
                        delay_5ms();            
                        P0=0xff;

                                                P0=table1[sec%10];                  //显示秒个位数      
                        if( count1==1&&flag_flash==1)
                                                        P2=0x00;
                                                else  
                        
                        P2=table2[7];                        
                        delay_5ms();         
                        P0=0xff;
回复

使用道具 举报

5#
ID:105364 发表于 2019-7-6 22:08 | 只看该作者
P0=table1[sec/10];                   //显示秒十位数
                                                if( count1==1&&flag_flash==1)
                                                        P2=0x00;
                                                else

                           
                        P2=table2[6];                        
                        delay_5ms();            
                        P0=0xff;

                                                P0=table1[sec%10];                  //显示秒个位数      
                        if( count1==1&&flag_flash==1)
                                                        P2=0x00;
                                                else  
                        

                        P2=table2[7];                        
                        delay_5ms();         
                        P0=0xff;
回复

使用道具 举报

6#
ID:105364 发表于 2019-7-7 12:04 | 只看该作者

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表