国信长天单片机竞赛训练之配合定时器实现立即计数和随按下按键的时间计数(二)

21 篇文章 0 订阅

本次训练实现当按下S18时且时间<1s 只计算一次,当按下s18且按下按键时间大于1s则在不松开的情况每过1s计数加一,而按下s19则是减一,与上同理。难点在于通过按键扫描记录按下未松手的key值,配合定时器中断实现每过1s计数加减,并把数值通过数码管显示。

//mian.c

#include "sys.h"
#include "math.h"
u8 key_value=0;
static	u32 example=0;
static u32 count=0;
static u32 time=0;
static u32 flag=0;
u8 temp1=0;
u8 temp2=0;
void main(){
	sys_init();
	ET0=1;
	EA=1;
  Timer0Init();
	while(1){
		key_value=keyscan();
		 
		temp1=key_value;//读取按键状态 0/被按下的状态
 	 if(key_value>0){//有按键按下,temp2保留按键按下的状态
		temp2=key_value;
		 flag=getsec();
	 }
	    smgshow(3,flag/10);
			smgshow(4,flag%10);//显示case2的值
	 
		 if(temp2<10){
			 smgshow(7,temp2%10);
		 }
		 if(temp2>10&&temp2<100){
			 smgshow(6,temp2/10);
			 smgshow(7,temp2%10);
		 }
		 
		 
		if(example>=0&&example<10){
			
			smgshow(0,example%10);
		}
		 if(example>=10&&example<100){
			
			smgshow(0,example/10);
			smgshow(1,example%10);
			
		}
			
		
		if(temp2==temp1&&temp2==19){//s11 减
			
			example--;
		}
		 if(temp2==temp1&&temp2==18){//s10 增
			example++;
		}
		if(example<0){
			smgshow(0,12);
			smgshow(1,abs(example));
			
		}
		if(time==1000&&flag==18){
			 example++;
			 time=0;
		 }
		 else if(time==1000&&flag==19){
			 
			 example--;
			 time=0;
		 }
		
	}
}
			
void timer0() interrupt 1{
		
		 
	if(flag>0&&flag==getsec()){
		
		time++;
	}
	else if(flag!=getsec()){
		
		
		time=0;
	
	
	}
 
	
}
	
//sys.c
#include "sys.h"
 
static u8 key_state=0;
u8 key_press;
u8 code smg_index[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x7f,0xbf}; 
sbit buzzer=P0^6;
sbit relay=P0^4;
static u8 sec=0;
void sys_init(){
	 
	P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;
	
	P2=(P2&0x1f)|0xa0;buzzer=0;relay=0;P2&=0x1f;

	P2=(P2&0x1f)|0xc0;P0=0xff;P2&=0x1f;

	P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f;
	
}
 	
u8 keyscan(){
	
   u8 row=0;
	 
	switch(key_state){
		case 0:
			P3=0X0F;
			P42=0;
			P44=0;
			key_press=P3&0x0F;
			if(key_press!=0x0F){
				key_state=1;
				  }
			break;
		case 1:
							P3=0X0F;
							P42=0;
							P44=0;
							key_press=P3&0x0f;
					if(key_press!=0x0f){
						if(key_press==0x0e) row=7;			 
						else if(key_press==0x0d) row=6;
						else if(key_press==0x0b)  row=5;					 
						else if(key_press==0x07) row=4;
						 
					
					P3=0xf0;
					P42=1;P44=1;
					key_press=P3&0xf0;
					if(key_press!=0xf0){
						if(P44==0) row+=0;
				
						else if(key_press==0xd0) row+=8;
							 
						else if(key_press==0xe0)  row+=12;
						
						else if(P42==0) row+=4;
							 
					}
					sec=row;
					key_state=2;
				}
				else key_state=0;
				break;
			case 2:
				P3=0x0f;
				key_press=P3&0x0f;
				if(key_press==0x0f){
					key_state=0;
				}
				 
				break;
			default :
				break;
		}
	 
	  return row;
}
u8 getsec(){

	if(key_state==2) return sec;
	else return 0;
}
void smgshow(u8 weis,u8 dus){
	P2=P2&0x1f;
	P0=0xff;
	P2=(P2&0x1f) | 0xe0;   //消除干扰
	
	P2=P2&0x1f;
	P0=1<<weis;             //位选
	P2=(P2&0x1f)|0xc0;
	P2=P2&0x1f;
	
	P0=smg_index[dus];    //某位数码管显示的数字
	P2=(P2&0x1f)|0xe0;
	P2=P2&0x1f;
	
}

void Timer0Init(void)		//1000??@11.0592MHz
{
	AUXR |= 0x80;		 
	TMOD &= 0xF0;		 
	TL0 = 0xCD;		 
	TH0 = 0xD4;		 
	TF0 = 0;		 
	TR0 = 1;		 
}	
	

//sys.h
#ifndef __SYS_H__
#define __SYS_H__
#include "stc15f2k60s2.h"
typedef unsigned char u8;
typedef int u32;
void sys_init();
u8  keyscan();
u8 getsec();
void smgshow(u8 weis,u8 dus);
void Timer0Init();
#endif     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值