找回密码
 立即注册

QQ登录

只需一步,快速开始

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

秒表程序……欢迎斧正

[复制链接]
跳转到指定楼层
楼主
ID:3324 发表于 2010-6-21 23:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想做个秒表程序,当键盘按下后,秒表停止,再按下另一个键后,秒表又恢复工作,可是我写的程序,当键盘有键按下时,就停止了,无论再按什么键,都没有反应,求哪位同仁帮我修改一下,谢谢了!想结交单片机爱好者!

#include<reg52.h>
#define uint unsigned int 
#define uchar unsigned char
uchar code disp[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7f,0x39,0x3f,0x79,0x71};
//数码管显示十六进制,从0到f
uchar code select[]={7,6,5,4,3,2,1,0};
//位选数组,自左至右
uint key,temp;
uint tt0=0;
uint num=0;
void display(uint second);
void delay(uint z);

void init()  //初始化子函数
{
 TMOD=0x01; //定时器0工作在方式一
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 EA=1;  //开总中断
 ET0=1;  //开定时器0中断
 TR0=1;  //计时开始
}

void Timer0() interrupt 1 //定时器0中断子函数
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 tt0++;
}

void delay(uint z)   //延时子函数
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--); 
}

void display(uint second)  //显示子函数
{
 uint bai,shi,ge;
 bai=second/100;
 shi=second%100/10;
 ge=second%100%10;
 
 if(bai!=0)    //此处的判断是为了消除重影,不然当没有到100时,百位上总会有一个0在隐隐约约的显示
  { 
  P0=disp[bai];  //显示百位
  P2=select[2];
  delay(1);    //延时0.1s左右
  }
 if(shi!=0)
  {  
  P0=disp[shi];  //显示十位
  P2=select[1];
  delay(1);
  }

 P0=disp[ge];  //显示个位
 P2=select[0];
 delay(1);
} 

void main()
{
 init();
 while(1)
 {
  if(tt0!=2)  //此处为显示秒表
  {
   display(num);
  }
  else 
  {
   tt0=0;
   num++;
  }
  P3=0x7f;  //开始检测按键
  temp=P3;
  while(temp!=0x7f) //检测是否有键按下
  {
   delay(5);  //延时几毫秒后,再次检测,防干扰
   temp=P3;
   while(temp!=0x7f) 
   {
    temp=P3;
    switch(temp)
    {
     case 0x7e:key=1;
       break;
     case 0x7d:key=2;
       break;
     case 0x7b:key=3;
       break;
     case 0x77:key=4;
       break;
    }
    if(key==1)  //若第一个键按下,定时器停止计时
    {
     TR0=0; //定时器0停止计时
     temp=0xff; //跳出while循环
    }
    if(key==2)  //若第二个键按下,定时器又重新开始计时
    {
     temp=0xff;
     TR0=1;
    }
   }
  }
  
 }
}

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

使用道具 举报

沙发
ID:23004 发表于 2010-6-22 11:17 | 只看该作者

看到你的程序结构,哥们就晕了。。。。

给你一个99秒表的参考程序:

#include <REGX51.H>
#include <../stdint.h>
#include <ABSACC.H>
#include <INTRINS.H>
//------------------------------
#define  TH_10MS  (65536-10000)/256
#define  TL_10MS  (65536-10000)%256
//------------------------------------------
#define led12 XBYTE[0xf7ff] //led1与led2数码管
#define led34 XBYTE[0xefff] //led3与led4数码管
#define led_light P3_7
#define keyst  P1_0
#define keyclk  P1_1

volatile struct _clock
{
 uint8_t t_s;//秒
 uint8_t t_ms;//分秒
 uint8_t led_lightf : 1;//中间灯   ==bit  led_lightf;
 uint8_t keyf_st : 1;   //开停键标志
 uint8_t keyf_clk : 1;  //清0键标志
 uint8_t clockf_st : 1; //开始计时标志
#define  STOP 0
#define  START 1
 uint8_t : 0;
}clock;


//-----------------delay-----------------------------
void delay_10ms()
{
 uint8_t i, j;
 for(i=0; i<100; i++)
  for(j=0; j<100; j++);
}

//-------------------10进制显示-----------------------
void display_val(uint8_t data_l, uint8_t data_r)
{
 uint8_t led_tmp12, led_tmp34;
 //取右边分秒
 led_tmp12 = (data_r/10)%10;
 led_tmp12 <<=4;
 led_tmp12 |= (uint8_t)(data_r%10);
 //取左边秒
 led_tmp34 = (data_l/10)%10;
 led_tmp34 <<=4;
 led_tmp34 |= data_l%10;

 led12 = led_tmp12;//送显示
 led34 = led_tmp34;
}

//------------------------初始化--------------
void clr_data()
{
 clock.t_s = 0;
 clock.t_ms = 0;
 clock.led_lightf = 0;
 clock.keyf_st = 0;
 clock.keyf_clk = 0;
 clock.clockf_st = STOP;
 TR0 = 0;   //关定时器
 display_val(0,0);
 led_light = 0;  
}
void init_sys()
{
 clr_data();
 //定时器0设置
 TMOD = 0x01; //定时器0设为MAOD1
 TCON = 0x00; //清标志位
 TH0 = TH_10MS;
 TL0 = TL_10MS;
 //TR0 = 1;   //开定时器
 //IE = 0x8a; //开定时中断0,1与总开关
 EA = 1;
 ET0 = 1;
}

//--------------------键盘扫描-----------------
void key_scan()
{
 bit keyf;
 keyf = keyst & keyclk;
 if(keyf)
  goto error;
 delay_10ms();
 keyf = keyst & keyclk;
 if(keyf)
  goto error;
  clock.keyf_st = !keyst;
  clock.keyf_clk = !keyclk;
  do
  {
   keyf = keyst & keyclk;
  }
  while(!keyf);
error:
 return ;  
}

//--------------------键盘处理-------------------
void key_deal()
{
 if(clock.keyf_st)
 {
  if(clock.clockf_st == STOP)
   TR0 = 1;
  else
   TR0 = 0;
  clock.clockf_st = ~clock.clockf_st;
  clock.keyf_st = 0;
 }
 if(clock.keyf_clk)
   {
  clr_data();
  clock.keyf_clk = 0;
   }
}

// -------------------main------------------------
void main()
{
 init_sys();
 while(1)
 {
  key_scan();//键盘扫描
  key_deal();//键盘处理
 }
}
//----------------------定时中断0-----------------
void  t0_interrupt() interrupt 1
{
 
 TR0 = 0;

 clock.t_ms++;
 if(clock.t_ms == 100)
 {
  clock.t_ms = 0;
  clock.t_s++;
  if(clock.t_s == 100)
   clock.t_s = 0;
  clock.led_lightf = ~clock.led_lightf;
 }
 display_val(clock.t_s, clock.t_ms);
 led_light = clock.led_lightf;
 TH0 = TH_10MS;
 TL0 = TL_10MS;
 TR0 = 1;
}

回复

使用道具 举报

板凳
ID:17294 发表于 2010-6-29 22:49 | 只看该作者
C语言有注释比较好读
回复

使用道具 举报

地板
ID:25278 发表于 2010-8-3 18:25 | 只看该作者
楼主遍的看着舒服
回复

使用道具 举报

5#
ID:25782 发表于 2010-8-28 22:14 | 只看该作者

void main()
{
init();
while(1)
{
  if(tt0!=2)  //此处为显示秒表///////其实这里是很冒险的也是很容易出问题的,初学者很容易将可以“片”判断条件不用,而用“点”判断条件,如这里,如果tt0>=2呢?这也不是不可能,如tt0刚刚加到2,而这时按键1动作(按键除抖延时还是很长的,在这段时间tt0会在T0中断里不断增加),这样,显示一直在运行,而tt0迟迟回不到“0”,就会陷入死循环了 ,将这里改成if(tt0<2)看看

 {
   display(num);
  }
  else
  {
   tt0=0;
   num++;
  }


 

 


 

[此贴子已经被作者于2010-9-11 19:58:54编辑过]
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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