找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6025|回复: 21
收起左侧

基于51单片机定时器的时钟,关于程序按键不受控制问题?

  [复制链接]
ID:102056 发表于 2016-11-2 11:15 | 显示全部楼层 |阅读模式
本帖最后由 king@ 于 2016-11-2 11:15 编辑

#include <reg52.h>
sbit WEI = P1^6;
sbit DU = P1^7;
sbit BEEP = P1^4;
sbit KEY1 = P3^4;
sbit KEY2 = P3^5;
sbit KEY3 = P3^6;
sbit KEY4 = P3^7;


void xiaoying();
void di();
void keyscan();
/* ***************************************************** */
// 宏定义
/* ***************************************************** */
#define uInt32 unsigned  long  int
#define uInt16 unsigned int
uInt16 s=0;m=0;h=0;
uInt32        num=0;
void DelayMS(uInt16 ValMS)
{
                uInt16 uiVal,ujVal;
                for(uiVal = 0; uiVal < ValMS; uiVal++)
                        for(ujVal = 0; ujVal < 113; ujVal++);
}
unsigned char Bit_Tab[] =
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};                //位选数组
unsigned char  DISP_smg[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/* ***************************************************** */
// 函数名称:Timer0Init()
// 函数功能:定时器0初始化设置
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void Timer0Init(void)
{
        TMOD = 0x01;        // 设置定时器1工作在模式1下
        TH0 = 0xDC;
        TL0 = 0x00;                // 赋初始值
        EA = 1;                        // 开总中断
        ET0 = 1;                // 开定时器1中断
        TR0 = 1;                // 开定时器0
}
/* ***************************************************** */
// 函数名称:main()
// 函数功能:定时器初始化后进入死循环,等定时器中断
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void main(void)
{
        Timer0Init();
   while(1)
   {
           void keyscan();


            h= num /3600;                  
            m=(num%3600)/60;                 
            s=(num%3600)%60;
                   if(s>59)
           {
                di();
                   s=0;
                m=m+1;
           }
           if(m>59)
           {
                di();
                   m=0;
                h=h+1;           
           }
           if(h>23)
           h=0;


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[5];
          WEI = 0;
          DU = 1;
          P0 = 0x40;
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[2];
          WEI = 0;
          DU = 1;
          P0 = 0x40;
          DelayMS(2);




          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[7];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[s%10];
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[6];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[s/10];
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[4];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[m%10];
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[3];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[m/10];
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[1];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[h%10];
          DelayMS(2);


          xiaoying();
          WEI = 1;
          P0 = Bit_Tab[0];
          WEI = 0;
          DU = 1;
          P0 = DISP_smg[h/10];
          DelayMS(2);


        }                        
}
/* ***************************************************** */
// 函数名称:Timer0_ISR()
// 函数功能:定时器中断服务,控制LED闪烁
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void Timer0_ISR(void) interrupt 1
{
        static uInt16 uiCounter = 0;         //只做一次定义
        TH0 = 0xDC;
        TL0 = 0x00;                                                //定时器赋初值
        uiCounter++;                                        //记录中断次数
        if(100 == uiCounter)
        {
                uiCounter = 0;
               
                num=num+1;
                                 
        }        
}




void xiaoying()
{
  DU=1;
  P0=0x00;
  DU=0;
}
void di()
{
  BEEP=0;
  DelayMS(100);
  BEEP=1;        
}
void keyscan()
{
   unsigned char flag;
   if(KEY1==0)
   {
         DelayMS(5);
         if(KEY1==0)
         {                    
              di();
                  TR0=~TR0;
                  flag=~flag;
                     while(!KEY1);
         }        
   }
   if(flag)
   {
         if(KEY2==0)
     {
         DelayMS(5);
         if(KEY2==0)
            {
                  di();
                 s=s+1;
                 if(s==60)
                 s=0;
                  while(!KEY1);


            }
     }


         if(KEY3==0)
     {
         DelayMS(5);
         if(KEY3==0)
            {
                  di();
                 m=m+1;
                 if(m==60)
                 m=0;
                  while(!KEY3);
            }
     }
         if(KEY4==0)
     {
         DelayMS(5);
         if(KEY4==0)
            {
                  di();
                 h=h+1;
                 if(h==24)
                 s=0;
                  while(!KEY4);


            }
     }






   }


}


不知道为什按键不受控,达不到效果,想要按键KEY1第一次按数码暂停,KEY2控制秒加,KEY3控制分加,KEY4控制时加,第二次按KEY1数码管继续计时,按键这部分程序写到这里不知道为什么数码管不受按键控制?求大神指导一下。





CPU.png
按键.png
蜂鸣器.png
数码管.png
回复

使用道具 举报

ID:111634 发表于 2016-11-2 11:57 | 显示全部楼层
这个问题以前好像拿出来过,有许多人解答了,怎么又拿出来?
回复

使用道具 举报

ID:102056 发表于 2016-11-2 13:34 | 显示全部楼层
zl2168 发表于 2016-11-2 11:57
这个问题以前好像拿出来过,有许多人解答了,怎么又拿出来?

我以前又不会按键,应该不会发过用按键控制数码管类似的问题
回复

使用道具 举报

ID:102056 发表于 2016-11-2 14:31 | 显示全部楼层
king@ 发表于 2016-11-2 13:34
我以前又不会按键,应该不会发过用按键控制数码管类似的问题

之前是没用中断,现在这个新写的程序应该是不一样的。
回复

使用道具 举报

ID:145717 发表于 2016-11-2 16:09 | 显示全部楼层
好文章
回复

使用道具 举报

ID:145717 发表于 2016-11-2 16:10 | 显示全部楼层
好文章!
回复

使用道具 举报

ID:145719 发表于 2016-11-2 16:12 | 显示全部楼层
if(100 == uiCounter)   这个是什么鬼。明显错误啊。
回复

使用道具 举报

ID:102056 发表于 2016-11-2 17:48 | 显示全部楼层
1281280722 发表于 2016-11-2 16:12
if(100 == uiCounter)   这个是什么鬼。明显错误啊。

T0定时器中断的时间0.01S,累计100次也就是1S数码管计数一次.
回复

使用道具 举报

ID:144789 发表于 2016-11-3 14:15 | 显示全部楼层
程序中间可能有问题
回复

使用道具 举报

ID:144789 发表于 2016-11-3 14:16 | 显示全部楼层
程序中间可能有问题
回复

使用道具 举报

ID:102056 发表于 2016-11-3 16:50 来自手机 | 显示全部楼层
xiaokaixin 发表于 2016-11-3 14:15
程序中间可能有问题

能不能再具体一点?
回复

使用道具 举报

ID:111634 发表于 2016-11-3 17:17 | 显示全部楼层
1281280722 发表于 2016-11-2 16:12
if(100 == uiCounter)   这个是什么鬼。明显错误啊。

错到没错,但易被人疑成“鬼”。有人说如果写成if( uiCounter ==100) ,有可能会误写成if( uiCounter =100)。
回复

使用道具 举报

ID:111634 发表于 2016-11-3 17:21 | 显示全部楼层
多认真研读正确的程序,有利于打好基础,少写出问题程序。
回复

使用道具 举报

ID:111634 发表于 2016-11-3 17:26 | 显示全部楼层
正确的程序很多,看看中断、键盘、显示,正确的的链接方法和思路,可避免出错,少走弯路。不要老是纠结于错误的程序,忙于让“大神”诊断,浪费时间。
回复

使用道具 举报

ID:111634 发表于 2016-11-3 18:04 | 显示全部楼层
学习的过程是研读、理解、模仿、创新。前3个阶段,未扎实基础,就想步入创新阶段,反而欲速而不达。
回复

使用道具 举报

ID:111634 发表于 2016-11-3 18:07 | 显示全部楼层
本帖最后由 zl2168 于 2016-11-3 18:29 编辑

给你介绍2本能达到上述要求的书,张志良编著的:
80C51单片机实用教程——基于Keil CProteus》高等教育出版社ISBN 978-7-04-044532-9, 用于学习51单片机原理,便于阅读理解,便于自学。
80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行
51单片机仿真设计实例教程仿真文件.rar (4.88 MB, 下载次数: 13)
回复

使用道具 举报

ID:111634 发表于 2016-11-3 18:20 | 显示全部楼层
真诚地希望广大单片机初学者改变学习方法,少走弯路,增强效果。
回复

使用道具 举报

ID:140489 发表于 2016-12-15 14:19 | 显示全部楼层
这是我做时钟的按键程序,你可以参考一下。主要是选择按键的次数要用一个变量来表示,比如knum=0,knum=2。
void keyscan()                                                                   //按键扫描函数
{                                                                                  
        if(s3==0)                                                                   //选择按键按下
        {
                delay(10);
                if(s3==0)
                {
                        while(!s3)
                                display(shi,fen,miao);        //加上这句,按键按下就不会闪
                        knum++;
                        if(knum==1)                                                  //分闪烁
                        {
                                 write_1302(0x8e,0x00);                //保护取消
                                 write_1302(write_miao,0x80);
                        }
                        if(knum==3)                                                   //时钟启动
                        {
                                knum=0;
                                write_1302(write_miao,0x00);
                                write_1302(0x8e,0x80);                //保护启动
                        }
                }
        }
        if(knum==1)                                                                //分钟调节
        {
                if(s1==0)                                                        //加
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen++;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==0x60)
                                        fen=0x00;
                                write_1302(write_fen,fen);        //写入1302
                                read_sf();                                        //读出时间,然后显示
                        }
                }
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                fen--;
                                fen=fen/10*16+fen%10;                //转为16进制
                                if(fen==-1)
                                        fen=0x59;
                                write_1302(write_fen,fen);
                                read_sf();
                        }
                }
        }
        if(knum==2)
        {
                if(s1==0)
                {
                        delay(10);
                        if(s1==0)
                        {       
                                while(!s1)
                                        display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi++;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==0x24)
                                        shi=0x00;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {       
                                while(!s2)
                                          display(shi,fen,miao);        //加上这句,按键按下就不会闪
                                shi--;
                                shi=shi/10*16+shi%10;                //转为16进制
                                if(shi==-1)
                                        shi=0x23;
                                write_1302(write_shi,shi);
                                read_sf();
                        }
                }
        }
}
回复

使用道具 举报

ID:155060 发表于 2016-12-15 17:13 | 显示全部楼层
好文章
回复

使用道具 举报

ID:135369 发表于 2016-12-15 21:38 来自手机 | 显示全部楼层
我感觉问题在于flag变量,
uchar flag初值确定就是0?
你试试bit flag=0;
回复

使用道具 举报

ID:155134 发表于 2016-12-15 21:59 来自手机 | 显示全部楼层
同求学习
回复

使用道具 举报

ID:260250 发表于 2018-1-23 10:52 | 显示全部楼层
学习时钟、中断,也遇到此问题。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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