单片机 电子时钟 (4*4键盘扫描)按键 源代码。

电子时钟 键盘扫描代码
#include "STC/STC15F2K60S2.H"
sbit SEGLE=P2^7;
sbit DIGLE=P2^6;
sbit LEDLE=P2^5;
unsigned char code Tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
unsigned char code Tab1[10] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
unsigned char count;   //记录中断次数
char second;    //储存秒 
char min;
char hour;
unsigned char num;
unsigned char keyval,index,k,min1,second1,hour1;                               
void delay(void)        //延时约0.6毫秒
{
  unsigned char i;
  for(i=0;i<200;i++) ;
}
//消抖 延迟
void delay30ms(void)
{
   unsigned char i,j;
    for(i = 0;i < 100;i++)
      for(j = 0;j < 100;j++);
}
void Displaysecond(unsigned char k);
void Displaymin(unsigned char k);
void Displayhour(unsigned char k);
unsigned char keyscan();
void leftmove();
void rightmove();
void jian();
void add();
                          
void main(void)      //主函数
   {
        P0 = 0x00;
        DIGLE = 1;
        DIGLE = 0;
        SEGLE = 1;
        SEGLE = 0;
        
        P0 = 0xff;
        LEDLE = 1; 
        LEDLE = 0;

        TMOD=0x01; 
        TH0=(65536-46083)/256; //=50000微秒=50毫秒
        TL0=(65536-46083)%256;
        EA=1;                    
        ET0=1;         
        TR0=1;
        k = 1;
        index = 0;         //允许标志
        count=0;    //中断次数初始化
        second=0;     //秒初始化
        min=0;
        hour=0;    
        while(1)
        {
            switch(keyval)
            {
                case 0:
                    Displayhour(hour);
                    Displaymin(min);
                    Displaysecond(second);
                    keyval = keyscan();
                    break;
                case 1: 
                    index = 1;                //设置允许位置1
                    TR0 = 0;                //关闭时钟0
                    hour1 = hour;            //将修改后的时间变量的值
                    min1 = min;                 //赋值给存储时间初始值变量
                    second1 = second;        //
                    keyval = 0;     
                    break;
                case 3:
                    if(!index)            //是否允许进行设置
                    {
                        keyval = 0;
                        break;    
                    }
                    index = 0;                //设置允许位置0
                    TR0 = 1;                //打开时钟0
                    keyval = 0;             //确认时间设定
                    break;
                case 4: 
                    if(!index)
                    {
                        keyval = 0;
                        break;    
                    }
                    hour = hour1;            //将存储时间初始值变量的值
                    min = min1;        //赋值给修改后的时间变量
                    second = second1;        //
                    keyval = 0;    
                    break;
                case 10:
                    if(!index)
                    {
                        keyval = 0;
                        break;    
                    }
                    leftmove();             //数码管位选左移
                    break;
                case 12: 
                    if(!index)
                    {
                        keyval = 0;
                        break;    
                    }        
                    rightmove();             //数码管位选右移
                    break;
                case 7:
                    if(!index)
                    {
                        keyval = 0;
                        break;    
                    }    
                    add();                 //选定时间值加1
                    break;
                case 15:
                    if(!index)
                    {
                        keyval = 0;
                        break;    
                    }
                    jian();             //选定时间值减1
                    break;
                default:
                    keyval = 0;          //键码赋值0,进行下次扫描
                    break;
            }
        }                 
    
 }
void time0() interrupt 1 using 1  
  {
    TR0 = 0;                 
     count++;     
       if(count==20)
    {
        count=0; 
        second++;   
        if(second == 60)
        {
             second = 0;
            min++;
            
            if(min == 60)
            {
                min = 0;
                hour++;
                if(hour == 24)
                    hour = 0;
             }
        }
    }
         
    
      TH0=(65536-46083)/256;   //重新给计数器T0赋初值
    TL0=(65536-46083)%256;
    TR0=1;     //启动定时器T0
 } 

 //键盘扫描
unsigned char  keyscan()   
    { 
        unsigned char scode;               //定义行扫描变量
        unsigned char rcode ;               //定义返回编码变量
        unsigned char m;                //定义行首编码变量
        unsigned char k;                //定义列检测码
        unsigned char i,j;                //定义循环控制变量
        P1 = 0x0f;               //发全列为0扫描码,行线输入
        if((P1 & 0x0f) != 0x0f)            //若有键按下
        {
            delay30ms();                     //延时消抖
            if((P1 & 0x0f) != 0x0f)        //若有键按下
            {
                m = 1;                 //行首编码变量赋初值
                scode = 0xfe;            //行扫描变量赋初值
                for(i = 0;i < 4;i++)
                {
                    P1 = scode;         //输出列线吗
                    k = 0x10;             //列检测码赋初值
                    for(j = 0;j < 4;j++)
                    {    
                        if((P1 & k) == 0)    //本列有键按下
                        {           
                            rcode = m + j;        //求键码
                            while((P1 & 0xf0) != 0xf0);    //等待按键释放
                            return (rcode);        //返回键码
                        }                        
                        else
                            k = k <<1 ;           //列检测码左移一位        
                    }
                    m = m + 4;                    //下一行行首编码        
                    scode = scode << 1;            //行扫描变量左移一位
                }                                    
            }
        }
        return 0;            //若没键按下,返回0
    }

 void Displaysecond(unsigned char k)
{ 
   P0=0xef;
   SEGLE=1;
   SEGLE=0;    
   P0=Tab[k/10];
   DIGLE=1;          
   DIGLE=0;
   delay();
   P0=0xdf;
   SEGLE=1;
   SEGLE=0;     
   P0=Tab[k%10];
   DIGLE=1;         
   DIGLE=0;
   delay();
}
void Displaymin(unsigned char k)
{
   P0=0xfb;
   SEGLE=1;
   SEGLE=0;
   P0=Tab[k/10];
   DIGLE=1;
   DIGLE=0;
   delay();
   P0=0xf7;
   SEGLE=1;
   SEGLE=0;
   P0=Tab1[k%10];
   DIGLE=1;
   DIGLE=0;
   delay();
}
void Displayhour(unsigned char k)
{
   P0=0xfe;
   SEGLE=1;
   SEGLE=0;
   P0=Tab[k/10];
   DIGLE=1;
   DIGLE=0;
   delay();
   P0=0xfd;
   SEGLE=1;
   SEGLE=0;
   P0=Tab1[k%10];
   DIGLE=1;
   DIGLE=0;
   delay();
}
void leftmove()
{        
         k--;
         if(k < 1)
             k=3;    
            
        while(keyval == 10||keyval == 0 )       //没有键按下,显示选中数码管位
        {
            if(k ==3)     
                Displaysecond(second);
            if(k ==2)
                Displaymin(min);
            if(k == 1)
                Displayhour(hour);    
            keyval = keyscan();                  //键盘扫描
            if(keyval == 10)                  //若本函数的识别键再次被按下,则退出循环
                break;
        }

}
void rightmove()
{      
        k++;
         if(k > 3)
             k=1;                
        while(keyval == 12 || keyval == 0)       //没有键按下,显示选中数码管位
        {
            if(k ==3)     
                Displaysecond(second);        
            if(k ==2)
                Displaymin(min);
            if(k == 1)
                Displayhour(hour);    
            keyval = keyscan();                  //键盘扫描
            if(keyval == 12)                  //若本函数的识别键再次被按下,则退出循环
                break;
        }
}

void add()
{
    
        if(k == 3)                    //数码管位选为秒位
        {
            second++;
            if(second == 60)
                second = 0;
        }

        if(k == 2)                       //数码管位选为分位
        {
            min++;
            if(min == 60)
                min = 0;
        }

        if(k == 1)                    //数码管位选为时位
        {
            hour++;
            if(hour == 24)
                hour = 0;
        }
      while(keyval == 7 || keyval == 0)       //没有键按下,显示选中数码管位
        {     
                Displaysecond(second);    
                Displaymin(min);
                Displayhour(hour);    
            keyval = keyscan();                  //键盘扫描
            if(keyval == 7)                  //若本函数的识别键再次被按下,则退出循环
                break;
        }
    }
void jian()
{
        if(k == 3)
        {
            second--;
            if(second < 0)
                second = 59;
        }
        if(k == 2)
        {
            min--;
            if(min < 0)
                min = 59;
        }
        if(k == 1)
        {
            hour--;
            if(hour< 0)
                hour = 23;
        }

        while(keyval == 15 || keyval == 0)
            {
                Displayhour(hour);
                Displaymin(min);
                Displaysecond(second);
            keyval = keyscan();
            if(keyval == 15)
                break;
        }
    }

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值