找回密码
 立即注册

QQ登录

只需一步,快速开始

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

秒表鬼影求指导

[复制链接]
跳转到指定楼层
楼主
ID:63752 发表于 2014-10-24 11:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  下面是我的秒表程序,当按KEY键,秒表走动,当停秒时,LED数码管有很多的鬼影,数码管停秒的亮度比走动时要暗很多,想了很久,还没解决问题,求指导,谢谢。


#include"reg51.h"
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int

sfr AUXR=0x8e;
sfr P4=0xC0;
sfr P4M0=0xB4;
sfr P4M1=0xB3;
sfr P2M0=0x96;
sfr P2M1=0x95;
sfr P0M0=0x94;
sfr P0M1=0x93;

sbit DUANA=P2^6;
sbit DUANB=P2^7;
sbit DUANC=P4^5;
sbit key=P3^5;

unsigned char code LedChar[16] = {
0xDD,0x11,0xD6,0x57,0x1B,0x4F,0xCF,0x15,0xDF,0x5F,0x9F,0xCB,0xCC,0xD3,0xCE,0x8E
};                  //用数组来存储数码管真值表
unsigned char code LedShi[10] = {
0xFD,0x31,0xF6,0x77,0x3B,0x6F,0xEF,0x35,0xFF,0x7F
};

unsigned char LedNumber[3] = {0}; //定义全局变量
unsigned char j = 0;
unsigned int counter = 0;
//unsigned char disp;

void Delay(uint x)
{
    uint a,b;
    for(a=x;a>0;a--)
       for(b=110;b>0;b--);
}   
void main()
{
  unsigned long stopwatch =0;
  P2M1=0x00;
  P2M0=0xFF;
  P0M1=0x00;
  P0M0=0xFF;
  P4M1=0x00;
  P4M0=0xFF;
  AUXR|=0x80;    //定时器0为1T模式//
        //AUXR&=0x7f;    //定时器0为12T模式//
        TMOD=0x00;   //设置定时器0为模式0
    TH0=(65536-60000)/256;
    TL0=(65536-60000)%256;   //定时5MS初值
        EA=1;                //开总中断//
    ET0=1; //开启内部定时器中断0;       
        TR0=0;  //打开定时器0  
  DUANA=1;
  DUANB=1;
  DUANC=1;
  P0=LedChar[0];
    while(1)
        {
                        if(key==0)
                          {
                                 Delay(10);
                                  {
                                          if(key==0)
                                        {
                                          TR0=1;
                                        }
                                        else
                                        TR0=0;
                                  }

                          }
                          if(20 == counter)     //判断定时器0溢出是否达到20次
                {
                  counter = 0;
                  stopwatch++;
                  LedNumber[0] = stopwatch%10;
                  LedNumber[1] = stopwatch/10%10;
                  LedNumber[2] = stopwatch/100%10;
                 }                
        P0 = 0x00;   //消隐
    switch(j)
    {
        case 0: DUANA=0; DUANB=0; DUANC=1; j++; P0=LedChar[LedNumber[0]]; break;
        case 1: DUANA=0; DUANB=1; DUANC=0; j++; P0=LedShi[LedNumber[1]]; break;
        case 2: DUANA=1; DUANB=0; DUANC=0; j=0; P0=LedChar[LedNumber[2]]; break;

        default: break;
    }    //动态刷新
        }
}



void InterruptTimer0() interrupt 1               //中断函数的特殊写法,数字’1’为中断入口号
{
    unsigned long stopwatch =0;
    TH0=(65536-60000)/256;   //溢出后进入中断重新赋值
    TL0=(65536-60000)%256;
    counter++;   //计数值counter加1
       
}   

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

使用道具 举报

沙发
ID:1 发表于 2014-10-24 13:16 | 只看该作者
你的电路图是怎么样的?
回复

使用道具 举报

板凳
ID:63752 发表于 2014-10-24 17:51 | 只看该作者
admin 发表于 2014-10-24 13:16
你的电路图是怎么样的?

  单片机是STC15F2K08S2,三位共阴数码管,位接P2.6.P2.7.P4.5,段接P0,P0直接接段,位经过三极管接到负极,内部晶振12M,KEY键是P3.5,7805稳压管,就这样,没其他了。当秒表停止时,会有很多鬼影出现,很不好,请各位指导,谢谢。
回复

使用道具 举报

地板
ID:19715 发表于 2014-10-24 22:59 | 只看该作者
       P0 = 0x00;   //消隐
    switch(j)
    {
        case 0: DUANA=0; DUANB=0; DUANC=1; j++; P0=LedChar[LedNumber[0]]; break;
        case 1: DUANA=0; DUANB=1; DUANC=0; j++; P0=LedShi[LedNumber[1]]; break;
        case 2: DUANA=1; DUANB=0; DUANC=0; j=0; P0=LedChar[LedNumber[2]]; break;
        default: break;
    }    //动态刷新
    Delay(4);//////////////////////////////加上延时

评分

参与人数 1威望 +50 黑币 +50 收起 理由
admin + 50 + 50

查看全部评分

回复

使用道具 举报

5#
ID:63752 发表于 2014-10-25 14:52 | 只看该作者
明白 发表于 2014-10-24 22:59
P0 = 0x00;   //消隐
    switch(j)
    {

加了这个延时,鬼影是没问题了,但是新的问题就出现了,我的按键,变的很不灵活,有时可以,有时不可以,很不准确,希望有更好的方法,谢谢~~
回复

使用道具 举报

6#
ID:19715 发表于 2014-10-25 19:28 | 只看该作者
Delay(4);//////////加上延时
可以短一些,
按键防抖时间也可以缩小
回复

使用道具 举报

7#
ID:19715 发表于 2014-10-25 19:46 | 只看该作者
XUSHENG 发表于 2014-10-25 14:52
加了这个延时,鬼影是没问题了,但是新的问题就出现了,我的按键,变的很不灵活,有时可以,有时不可以, ...

定时器可以总是打开
void main()
{
  unsigned long stopwatch =0;
  P2M1=0x00;
  P2M0=0xFF;
  P0M1=0x00;
  P0M0=0xFF;
  P4M1=0x00;
  P4M0=0xFF;
  AUXR|=0x80;    //定时器0为1T模式//
        //AUXR&=0x7f;    //定时器0为12T模式//
        TMOD=0x00;   //设置定时器0为模式0
    TH0=(65536-60000)/256;
    TL0=(65536-60000)%256;   //定时5MS初值
    EA=1;                //开总中断//
    ET0=1; //开启内部定时器中断0;        
    TR0=1;  //打开定时器0  
  DUANA=1;
  DUANB=1;
  DUANC=1;
  P0=LedChar[0];
    while(1)
        {
                 if(key)
                  {
                    Delay(2);
                     {
                      if(key)counter=0;                                       
                     }
                  }
                 if(20 == counter)     //判断定时器0溢出是否达到20次
                 {
                  counter = 0;
                  stopwatch++;
                  LedNumber[0] = stopwatch%10;
                  LedNumber[1] = stopwatch/10%10;
                  LedNumber[2] = stopwatch/100%10;
                 }                  
        }
}
void InterruptTimer0() interrupt 1               //中断函数的特殊写法,数字’1’为中断入口号
{
    unsigned long stopwatch =0;
    TH0=(65536-60000)/256;   //溢出后进入中断重新赋值
    TL0=(65536-60000)%256;
    counter++;   //计数值counter加1
    P0 = 0x00;   //消隐
     switch(j)
    {
        case 0: DUANA=0; DUANB=0; DUANC=1; j++; P0=LedChar[LedNumber[0]]; break;
        case 1: DUANA=0; DUANB=1; DUANC=0; j++; P0=LedShi[LedNumber[1]];  break;
        case 2: DUANA=1; DUANB=0; DUANC=0; j=0; P0=LedChar[LedNumber[2]]; break;
       default: j=0; break;
    }    //动态刷新
        
}   

回复

使用道具 举报

8#
ID:44262 发表于 2014-10-27 03:37 来自手机 | 只看该作者
搞定了没有?
回复

使用道具 举报

9#
ID:63752 发表于 2014-10-27 08:58 | 只看该作者
明白 发表于 2014-10-25 19:46
定时器可以总是打开
void main()
{

秒表,我的按键是按一下,秒表停止,再按键,秒表启动。counter=0;是按键一直铵下才等于0,秒表停止,但是我要再按按键,要启动呢?这个counter=0;又要怎样表示呢?还没想通呢~
回复

使用道具 举报

10#
ID:63752 发表于 2014-10-27 08:58 | 只看该作者

还没搞定呢,又好提示吗?
回复

使用道具 举报

11#
ID:19715 发表于 2014-10-27 18:49 | 只看该作者
XUSHENG 发表于 2014-10-27 08:58
秒表,我的按键是按一下,秒表停止,再按键,秒表启动。counter=0;是按键一直铵下才等于0,秒表停止,但 ...

while(1)
        {
                 if(key)
                  {
                    Delay(2);
                     {
                      if(key)F0=!F0;                                       
                     }
                  }
                 if(20 == counter)     //判断定时器0溢出是否达到20次
                 {
                  counter = 0;
                  stopwatch++;
                  LedNumber[0] = stopwatch%10;
                  LedNumber[1] = stopwatch/10%10;
                  LedNumber[2] = stopwatch/100%10;
                 }                  
        }
}
void InterruptTimer0() interrupt 1               //中断函数的特殊写法,数字’1’为中断入口号
{
    unsigned long stopwatch =0;
    TH0=(65536-60000)/256;   //溢出后进入中断重新赋值
    TL0=(65536-60000)%256;
    if(F0)counter++;   //计数值counter加1
    P0 = 0x00;   //消隐
     switch(j)
    {
        case 0: DUANA=0; DUANB=0; DUANC=1; j++; P0=LedChar[LedNumber[0]]; break;
        case 1: DUANA=0; DUANB=1; DUANC=0; j++; P0=LedShi[LedNumber[1]];  break;
        case 2: DUANA=1; DUANB=0; DUANC=0; j=0; P0=LedChar[LedNumber[2]]; break;
       default: j=0; break;
    }    //动态刷新
        
}   

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

12#
ID:63752 发表于 2014-10-27 22:27 来自手机 | 只看该作者
F0=!F0;是取反的意思吧?为什么要这样呢?能解释一下吗?初学者我是
回复

使用道具 举报

13#
ID:63752 发表于 2014-10-28 09:44 | 只看该作者
明白 发表于 2014-10-27 18:49
while(1)
        {
                 if(key)

刚试了这一程序,还是不行啊。一上电,秒表就走动了,而且是慢走的,按了按键才正常走,一松按键,又变回慢走了,还是不行呢,这程序,看上去是可以实行的,但是一烧录了,就和想像的不一样了,头都大了。
回复

使用道具 举报

14#
ID:19715 发表于 2014-10-28 09:56 | 只看该作者
XUSHENG 发表于 2014-10-28 09:44
刚试了这一程序,还是不行啊。一上电,秒表就走动了,而且是慢走的,按了按键才正常走,一松按键,又变回 ...

一上电,秒表是不会走动的,不知道你是怎么整理
回复

使用道具 举报

15#
ID:63752 发表于 2014-10-28 12:03 | 只看该作者
明白 发表于 2014-10-28 09:56
一上电,秒表是不会走动的,不知道你是怎么整理

我按着你的这一提示,重新烧录了的,其他都没有变过,确实是一上电就走动了,是比较慢的走动,按按键,才正常的走动,照程序,一上电应该是不走动的。
回复

使用道具 举报

16#
ID:19715 发表于 2014-10-28 20:40 | 只看该作者
XUSHENG 发表于 2014-10-28 12:03
我按着你的这一提示,重新烧录了的,其他都没有变过,确实是一上电就走动了,是比较慢的走动,按按键,才 ...

把整个c文件晒到这里,让大家看看
回复

使用道具 举报

17#
ID:63752 发表于 2014-10-29 13:08 | 只看该作者
明白 发表于 2014-10-28 20:40
把整个c文件晒到这里,让大家看看

#include"reg51.h"
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int

sfr AUXR=0x8e;
sfr P4=0xC0;
sfr P4M0=0xB4;
sfr P4M1=0xB3;
sfr P2M0=0x96;
sfr P2M1=0x95;
sfr P0M0=0x94;
sfr P0M1=0x93;

sbit DUANA=P2^6;
sbit DUANB=P2^7;
sbit DUANC=P4^5;
sbit key=P3^5;

unsigned char code LedChar[16] = {
0xDD,0x11,0xD6,0x57,0x1B,0x4F,0xCF,0x15,0xDF,0x5F,0x9F,0xCB,0xCC,0xD3,0xCE,0x8E
};                  //用数组来存储数码管真值表
unsigned char code LedShi[10] = {
0xFD,0x31,0xF6,0x77,0x3B,0x6F,0xEF,0x35,0xFF,0x7F
};

unsigned char LedNumber[3] = {0}; //定义全局变量
unsigned char j = 0;
unsigned char F0 = 0;
unsigned int counter = 0;
//unsigned char disp;

void Delay(uint x)
{
    uint a,b;
    for(a=x;a>0;a--)
       for(b=110;b>0;b--);
}   
void main()
{
  unsigned long stopwatch =0;
  P2M1=0x00;
  P2M0=0xFF;
  P0M1=0x00;
  P0M0=0xFF;
  P4M1=0x00;
  P4M0=0xFF;
  AUXR|=0x80;    //定时器0为1T模式//
        //AUXR&=0x7f;    //定时器0为12T模式//
        TMOD=0x00;   //设置定时器0为模式0
    TH0=(65536-60000)/256;
    TL0=(65536-60000)%256;   //定时5MS初值
       
        EA=1;                //开总中断//

    ET0=1; //开启内部定时器中断0;       
        TR0=1;  //打开定时器0
          
  DUANA=1;
  DUANB=1;
  DUANC=1;
  P0=LedChar[0];
    while(1)
        {
                          if(key)
                          {
                                 Delay(10);
                                  {
                                          if(key)F0=!F0
                                       
                                          
                                  }
                                  
                          }
                       
                          if(20 == counter)     //判断定时器0溢出是否达到20次
                {
                  counter = 0;
                  stopwatch++;
                  LedNumber[0] = stopwatch%10;
                  LedNumber[1] = stopwatch/10%10;
                  LedNumber[2] = stopwatch/100%10;
                 }
                        
       
        }
}



void InterruptTimer0() interrupt 1               //中断函数的特殊写法,数字’1’为中断入口号
{
    //unsigned long stopwatch =0;
    TH0=(65536-60000)/256;   //溢出后进入中断重新赋值
    TL0=(65536-60000)%256;
    //counter++;   //计数值counter加1
        if(F0)counter++;  
        P0 = 0x00;   //消隐
    switch(j)
    {
        case 0: DUANA=0; DUANB=0; DUANC=1; j++; P0=LedChar[LedNumber[0]]; break;
        case 1: DUANA=0; DUANB=1; DUANC=0; j++; P0=LedShi[LedNumber[1]]; break;
        case 2: DUANA=1; DUANB=0; DUANC=0; j=0; P0=LedChar[LedNumber[2]]; break;
      
        default: break;
    }    //动态刷新
         
         //Delay(10);


}
回复

使用道具 举报

18#
ID:19715 发表于 2014-10-29 19:47 | 只看该作者
本帖最后由 明白 于 2014-10-29 20:13 编辑

可以这样定义吗:unsigned char F0 = 0;
????????????????????????/
  if(20 == counter)     //判断定时器0溢出是否达到20次
改成:  if(counte>=20)     //判断定时器0溢出是否达到20次

while(1)
        {
                          if(!key)
                          {
                                 Delay(10);
                                  {
                                          if(!key)F0=!F0 ;      // F0不用定义                                                         
                                  }
                            while((!key);      
                          }                       
                         if(counter>=20)     //判断定时器0溢出是否达到20次
                {
                  counter = 0;
                  stopwatch++;
                  LedNumber[0] = stopwatch%10;
                  LedNumber[1] = stopwatch/10%10;
                  LedNumber[2] = stopwatch/100%10;
                 }                       
        }
}



回复

使用道具 举报

19#
ID:19715 发表于 2014-10-29 22:14 | 只看该作者
【 if(20 == counter)  】
这个是变慢的罪魁祸首
回复

使用道具 举报

20#
ID:63752 发表于 2014-10-30 12:43 | 只看该作者
明白 发表于 2014-10-29 22:14
【 if(20 == counter)  】
这个是变慢的罪魁祸首

问题已经解决了,C语言真是博大精深啊。
回复

使用道具 举报

21#
ID:153199 发表于 2016-12-31 11:37 | 只看该作者
软件消隐
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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