想做个秒表程序,当键盘按下后,秒表停止,再按下另一个键后,秒表又恢复工作,可是我写的程序,当键盘有键按下时,就停止了,无论再按什么键,都没有反应,求哪位同仁帮我修改一下,谢谢了!想结交单片机爱好者!
#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.51hei.com/bbs/) | Powered by Discuz! X3.1 |