想做個秒表程序,當鍵盤按下后,秒表停止,再按下另一個鍵后,秒表又恢復工作,可是我寫的程序,當鍵盤有鍵按下時,就停止了,無論再按什么鍵,都沒有反應,求哪位同仁幫我修改一下,謝謝了!想結交單片機愛好者!
#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;
}
}
}
}
}
看到你的程序結構,哥們就暈了。。。。
給你一個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;
}
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++;
}
| 歡迎光臨 (http://www.denmoz.com/bbs/) | Powered by Discuz! X3.1 |