按住一个独立按键不松手的连续步进触发
#include "REG52.H"
#define const_voice_short 40
#define const_key_time1 20
#define const_key_time2 20
/*
如何知道1秒钟需要多少个定时中断?
其实前面程序已经说过了,在这再啰嗦一下。
这里需要先编写一小段程序进行测试,得到测试的结果后再按比例修正。
比例:
第一步:在程序代码上先写入1秒钟大概需要200个中断。
第二步:基于以上1秒钟的基准,编写一个60秒的简单测试程序(如果编
写超过60秒的时间,这个精度还会更高)。比如,编写一个用蜂鸣器的
声音来识别计时的起始和终止的测试程序。
第三步:把程序烧录到单片机后,上电开始测试,手上同步打开手机里的
秒表。假设单片机仅仅跑了27秒。
第四步:最终得到1秒钟需要的定时中断次数是:const_time_1s=(200*60)/27=444
*/
#define const_time_0_25s 111 //0.25秒的时间需要的定时中断次数
#define const_time_1s 444 //1秒钟的时间需要的定时中断次数
#define const_voice_short 40
#define const_key_time1 20
#define const_key_time2 20
/*
如何知道1秒钟需要多少个定时中断?
其实前面程序已经说过了,在这再啰嗦一下。
这里需要先编写一小段程序进行测试,得到测试的结果后再按比例修正。
比例:
第一步:在程序代码上先写入1秒钟大概需要200个中断。
第二步:基于以上1秒钟的基准,编写一个60秒的简单测试程序(如果编
写超过60秒的时间,这个精度还会更高)。比如,编写一个用蜂鸣器的
声音来识别计时的起始和终止的测试程序。
第三步:把程序烧录到单片机后,上电开始测试,手上同步打开手机里的
秒表。假设单片机仅仅跑了27秒。
第四步:最终得到1秒钟需要的定时中断次数是:const_time_1s=(200*60)/27=444
*/
#define const_time_0_25s 111 //0.25秒的时间需要的定时中断次数
#define const_time_1s 444 //1秒钟的时间需要的定时中断次数
void initial_myself();
void initial_peripheral();
void delay_long(unsigned int uiDelayLong);
void T0_time();
void key_service();
void key_scan();
void led_run();
void initial_peripheral();
void delay_long(unsigned int uiDelayLong);
void T0_time();
void key_service();
void key_scan();
void led_run();
sbit key_sr1=P0^0;
sbit key_sr2=P0^1;
sbit key_gnd_dr=P0^4;
sbit beep_dr=P1^5;
sbit led_dr=P3^5;
sbit key_sr2=P0^1;
sbit key_gnd_dr=P0^4;
sbit beep_dr=P1^5;
sbit led_dr=P3^5;
unsigned char ucKeySec=0;
unsigned int uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned int uiKeyCtntyCnt1=0; //按键连续触发的时间间隔延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned int uiKeyTimeCnt2=0;
unsigned int uiKeyCtntyCnt2=0;
unsigned char ucKeyLock2=0;
unsigned int uiVoiceCnt=0;
unsigned int uiSetNumber=0; //设置的数据
unsigned int uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned int uiKeyCtntyCnt1=0; //按键连续触发的时间间隔延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned int uiKeyTimeCnt2=0;
unsigned int uiKeyCtntyCnt2=0;
unsigned char ucKeyLock2=0;
unsigned int uiVoiceCnt=0;
unsigned int uiSetNumber=0; //设置的数据
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
key_service();
led_run();
}
}
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
key_service();
led_run();
}
}
void led_run()
{
if(uiSetNumber<10)
led_dr=1; //灭
else
led_dr=0; //亮
}
{
if(uiSetNumber<10)
led_dr=1; //灭
else
led_dr=0; //亮
}
void key_scan()
{
if(key_sr1==1) //IO高电平,按键没有被按下,及时清零一些标志位
{
uiKeyTimeCnt1=0; //按键去抖动延时清零
ucKeyLock1=0; //按键自锁标志清零
uiKeyCtntyCnt1=0; //连续累加的时间间隔时间清零
}
else if(ucKeyLock1==0) //有按键按下,且被第一次按下
{
uiKeyTimeCnt1++; //累加定时中断次数
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //自锁按键置位,避免一直触发
ucKeySec=1; //触发1号键
}
}
else if(uiKeyTimeCnt1<const_time_1s) //按住,没有累加到1秒
{
uiKeyTimeCnt1++;
}
else //按住累加到1秒
{
uiKeyCtntyCnt1++; //连续触发延时计数器累加
if(uiKeyCtntyCnt1>const_time_0_25s) //按住没松手,每0.25秒触发一次
{
uiKeyCtntyCnt1=0;
ucKeySec=1; //触发1号键
}
}
if(key_sr2==1)
{
ucKeyLock2=0;
uiKeyTimeCnt2=0;
uiKeyCtntyCnt2=0;
}
else if(ucKeyLock2==0)
{
uiKeyTimeCnt2++;
if(uiKeyTimeCnt2>const_key_time2)
{
uiKeyTimeCnt2=0;
ucKeyLock2=1;
ucKeySec=2;
}
}
else if(uiKeyTimeCnt2<const_time_1s)
{
uiKeyTimeCnt2++;
}
else
{
uiKeyCtntyCnt2++;
if(uiKeyCtntyCnt2>const_time_0_25s)
{
uiKeyCtntyCnt2=0;
ucKeySec=2;
}
}
}
{
if(key_sr1==1) //IO高电平,按键没有被按下,及时清零一些标志位
{
uiKeyTimeCnt1=0; //按键去抖动延时清零
ucKeyLock1=0; //按键自锁标志清零
uiKeyCtntyCnt1=0; //连续累加的时间间隔时间清零
}
else if(ucKeyLock1==0) //有按键按下,且被第一次按下
{
uiKeyTimeCnt1++; //累加定时中断次数
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //自锁按键置位,避免一直触发
ucKeySec=1; //触发1号键
}
}
else if(uiKeyTimeCnt1<const_time_1s) //按住,没有累加到1秒
{
uiKeyTimeCnt1++;
}
else //按住累加到1秒
{
uiKeyCtntyCnt1++; //连续触发延时计数器累加
if(uiKeyCtntyCnt1>const_time_0_25s) //按住没松手,每0.25秒触发一次
{
uiKeyCtntyCnt1=0;
ucKeySec=1; //触发1号键
}
}
if(key_sr2==1)
{
ucKeyLock2=0;
uiKeyTimeCnt2=0;
uiKeyCtntyCnt2=0;
}
else if(ucKeyLock2==0)
{
uiKeyTimeCnt2++;
if(uiKeyTimeCnt2>const_key_time2)
{
uiKeyTimeCnt2=0;
ucKeyLock2=1;
ucKeySec=2;
}
}
else if(uiKeyTimeCnt2<const_time_1s)
{
uiKeyTimeCnt2++;
}
else
{
uiKeyCtntyCnt2++;
if(uiKeyCtntyCnt2>const_time_0_25s)
{
uiKeyCtntyCnt2=0;
ucKeySec=2;
}
}
}
void key_service()
{
switch(ucKeySec)
{
case 1: //1号键,连续加键
uiSetNumber++; //参数连续往上加
if(uiSetNumber>20) //最大是20
uiSetNumber=20;
uiVoiceCnt=const_voice_short; //按键声音触发,嘀一声就停
ucKeySec=0; //响应按键服务程序后,按键编号清零,避免一直触发
break;
case 2: //2号键,连续减键
uiSetNumber--;
if(uiSetNumber>20) //最小是0.为什么这里用20?因为0减去1就是溢出变成了65535(0xffff)
uiSetNumber=0;
uiVoiceCnt=const_voice_short;
ucKeySec=0;
break;
}
}
{
switch(ucKeySec)
{
case 1: //1号键,连续加键
uiSetNumber++; //参数连续往上加
if(uiSetNumber>20) //最大是20
uiSetNumber=20;
uiVoiceCnt=const_voice_short; //按键声音触发,嘀一声就停
ucKeySec=0; //响应按键服务程序后,按键编号清零,避免一直触发
break;
case 2: //2号键,连续减键
uiSetNumber--;
if(uiSetNumber>20) //最小是0.为什么这里用20?因为0减去1就是溢出变成了65535(0xffff)
uiSetNumber=0;
uiVoiceCnt=const_voice_short;
ucKeySec=0;
break;
}
}
void T0_time() interrupt 1
{
TF0=0;
TR0=0;
key_scan();
if(uiVoiceCnt!=0)
{
uiVoiceCnt--;
beep_dr=0;
}
else
{
;
beep_dr=1;
}
TH0=0xf8;
TL0=0x2f;
TR0=1;
}
{
TF0=0;
TR0=0;
key_scan();
if(uiVoiceCnt!=0)
{
uiVoiceCnt--;
beep_dr=0;
}
else
{
;
beep_dr=1;
}
TH0=0xf8;
TL0=0x2f;
TR0=1;
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
for(j=0;j<500;j++)
;
}
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
for(j=0;j<500;j++)
;
}
void initial_myself()
{
key_gnd_dr=0;
beep_dr=1;
led_dr=1; //灭
TMOD=0x01;
TH0=0xf8;
TL0=0x2f;
}
{
key_gnd_dr=0;
beep_dr=1;
led_dr=1; //灭
TMOD=0x01;
TH0=0xf8;
TL0=0x2f;
}
void initial_peripheral()
{
EA=1; //开启总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}
{
EA=1; //开启总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}