|
倒计时,计数器,数码管显示当前定时时间,求助按下按键key2时如何实现按一下修改定时分(两位)按两下修改定时秒,并且修改的当前位闪烁显示,按键key3,key4分别为加减按键,只有闪烁的位才可以修改值。贴上我的源程序。按键功能函数为:void KeyDriver()
#define MAIN_Fosc 11059200L //定义主时钟,注意和下载频率选择一致
#include "15W4KxxS4.H"
#define uint16 unsigned int
#define uint8 unsigned char
void KeyDriver();
void KeyScan();
void zoushi();
void sheizhi();
void Timer0Init(void);
/********************************************
引脚别名定义
*********************************************/
sbit KEY1=P4^1; //设置
sbit KEY2=P4^2; //启动
sbit KEY3=P4^3; //加
sbit KEY4=P4^4; //减
sbit vo1=P3^3; //电机
sbit vo2=P3^4; //电机
/********************************************
变量定义
*********************************************/
unsigned int cnt = 0; //时标
unsigned int cnt1 =0; //时标
unsigned int cnt2 =0; //时标
uint16 sec = 60;//秒初始值
uint16 min =99;//分初始值
uint8 i=0;//段码时标
uint8 a=0;//按键记次
uint8 b=0;//段码时标
bit keybuff1=0;//启动停止标志位,0停止,1启动
bit fm=0;//改分秒值,0分,1 秒
bit fen=0;//分标志位
bit miao=0;//秒标志位
/********************************************
数码管段码0-F
*********************************************/
uint8 code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/********************************************
数码管初始值 99.59
*********************************************/
uint8 LedBuff[4]={
0x3f, 0x7d, 0x6f, 0x6f
};
/********************************************
按键初始值1111
*********************************************/
unsigned char KeySta[4] = { //按键当前状态
1, 1, 1, 1
};
/***********************
功能描述:主函数
入口参数:无
返回值:无
************************/
int main()
{
P0M1 = 0; P0M0 = 0XFF;//P0为推挽模式
P2M1 = 0; P2M0 = 0;//P2为标准模式
P3M1 = 0; P3M0 = 0;//P3为标准模式
/********************************************
I/O口工作模式
*********************************************/
Timer0Init(); //定时器0初始化,定时2ms
while (1)
{
KeyDriver();
if(fen==1)
{
fen=0;
if(cnt2==500)
{
cnt2=0;
//b=1;
P2=~0X80;
P2=~0X40;
}
}
if(keybuff1==1)
{
zoushi();
}
}
}
/***********************
功能描述:定时器0初始化
入口参数:无
返回值:无
************************/
void Timer0Init(void)
{
AUXR |= 0x80; //定时器0为1T模式
TMOD &= 0xF8; //定时器0设置为定时方式,工作模式为16位自动重装模式
TMOD &= 0xF7; //定时器0门控位GATE设置为0
TL0 = 0x9A; //设置定时初值
TH0 = 0xA9; //设置定时初值
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0的溢出中断允许位
EA = 1; //使能总中断
}
/**************************************
功能描述:按键功能程序
入口参数:无
返回值:无
***************************************/
void KeyDriver()
{
unsigned char i;
static unsigned char backup[4] = {1,1,1,1};
for (i=0; i<4; i++) //循环检测4个按键
{
if (backup[i] != KeySta[i]) //检测按键动作
{
if (backup[i] != 0) //按键按下时执行动作
{
if (i == 0) //启动停止计数器
{
keybuff1=~keybuff1;//按键状态取反
}
else if (i == 1) //设置计数器,按一下分,两下秒,三下退出
{
a++;
if(a==1)
{
fen=1;
}
if(a==2)
{
miao=1;
a=0;
}
}
else if (i == 2) //计数器加
{
}
else if (i == 3) //计数器减
{
}
}
backup[i] = KeySta[i]; //刷新前一次的备份值
}
}
}
/**************************************
功能描述:按键检测程序
入口参数:无
返回值:无
***************************************/
void KeyScan()
{
unsigned char i;
static unsigned char keybuf[4] = { //按键扫描缓冲区
0xFF, 0xFF, 0xFF, 0xFF
};
//按键值移入缓冲区
keybuf[0] = (keybuf[0] << 1) | KEY1;
keybuf[1] = (keybuf[1] << 1) | KEY2;
keybuf[2] = (keybuf[2] << 1) | KEY3;
keybuf[3] = (keybuf[3] << 1) | KEY4;
//消抖后更新按键状态
for (i=0; i<4; i++)
{
if (keybuf[i] == 0x00)
{ //连续8次扫描值为0,即16ms内都是按下状态时,可认为按键已稳定的按下
KeySta[i] = 0;
}
else if (keybuf[i] == 0xFF)
{ //连续8次扫描值为1,即16ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[i] = 1;
}
}
}
/**************************************
功能描述:走时程序
入口参数:无
返回值:无
***************************************/
void zoushi()
{
/********************************************
秒走时
*********************************************/
if(cnt1 == 500) //500次中断被响应后,正好1000ms
{
cnt1 = 0;
sec--;
if(sec<=0)
{
sec=60;
cnt=1;
LedBuff[0] = table[sec%10];
LedBuff[1] = table[sec/10%10];
}
else
{
LedBuff[0] = table[sec%10];
LedBuff[1] = table[sec/10%10];
}
}
/********************************************
分走时
*********************************************/
if(cnt==1)
{
cnt=0;
min--;
if(min<=0)
{
min=99;
LedBuff[2] = table[min%10];
LedBuff[3] = table[min/10%10];
}
else{
LedBuff[2] = table[min%10];
LedBuff[3] = table[min/10%10];
}
}
}
void sheizhi()
{
keybuff1=0;
}
/**************************************
功能描述:定时器0中断服务程序
入口参数:无
返回值:无
***************************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
if(keybuff1==1)
{
cnt1++;//计时
cnt2++;
}
/************************ 2ms刷新 ****************************/
switch(i)
{
case 0: P2=0X80; i++; P0=LedBuff[0];break;
case 1: P2=0X40; i++; P0=LedBuff[1];break;
case 2: P2=0X20; i++; P0=LedBuff[2];break;
case 3: P2=0X10; i=0; P0=LedBuff[3];break;
default:break;
} //无任务,说明LED亮灭来自于中断
KeyScan(); //按键扫描
}
|
|