stc89c52单片机定时器实现按键长按识别问题

stc89c52单片机定时器实现按键长按识别问题,第1张

/*AT89S52和STC单片机引脚是通用的,程序可以直接移植

晶振:12MHZ

引脚连接方式见下面定义,该程序经过我仔细调试,只要连接上即可直接运行,*/

#include<reg52.H>

#define seg_data P1 //数码管显示数据输出端口

sbit K1 = P3^0//按键引脚定义

sbit K2 = P3^1

sbit K3 = P3^2

sbit bit1 = P2^0//数码管位选通端口定义

sbit bit2 = P2^1

sbit bit3 = P2^2

/*共阳数码管0-9 */

const unsigned char seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

unsigned char seg_data1=0,seg_data2=0,seg_data3=0,delaytime=0

struct boolean_variable //定义布尔型变量,每个变量只占用一个bit RAM

{

char a :1

char b :1

char c :1

char d :1

char e :1

char f :1

}variable1

/******************************************************************************

定时器初始化

******************************************************************************/

void time0_time1_initialize()

{

TMOD=0X11//T0模式1,T1模式1 相当于00010001B

ET0=1//T0开中断

ET1=1//T1开中断

PT0=1//T0为高优先级

PT1=0//T1为低优先级

EA=1//中断总开关打开

TH1=0XF8////T1装入初值,实现2ms定时

TL1=0X30

TH0=0X3c//T0装入初值,实现50ms定时

TL0=0Xb0

TR1=1//开启T1

}

#define bit1_shanshuo variable1.c

#define bit2_shanshuo variable1.d

#define bit3_shanshuo variable1.e

#define jishu_key variable1.f

/******************************************************************************

动态扫描显示程序

******************************************************************************/

unsigned char judge_segdata=1

void seg_display()

{

if (jishu_key == 1)

{

if (judge_segdata >6)

judge_segdata =1

switch (judge_segdata)

{

case 1: seg_data=seg[seg_data1]bit1 = 1break

case 2: seg_data=seg[seg_data1]bit1 = 0break

case 3: seg_data=seg[seg_data2]bit2 = 1break

case 4: seg_data=seg[seg_data2]bit2 = 0break

case 5: seg_data=seg[seg_data3]bit3 = 1break

case 6: seg_data=seg[seg_data3]bit3 = 0break

}

goto S

}

if (jishu_key == 0)

{

if (judge_segdata >200)

judge_segdata =1

if (bit1_shanshuo == 1)

{

if (judge_segdata == 1)

{

seg_data=seg[seg_data1]bit1 = 1

goto S

}

if (judge_segdata == 100)

{

seg_data=seg[seg_data1]bit1 = 0

goto S

}

if (judge_segdata == 200)

goto S

switch (judge_segdata%10)

{

case 2: seg_data=seg[seg_data2]bit2 = 1bit1 = 0break

case 3: seg_data=seg[seg_data2]bit2 = 0break

case 4: seg_data=seg[seg_data3]bit3 = 1bit1 = 0break

case 5: seg_data=seg[seg_data3]bit3 = 0break

case 6: seg_data=seg[seg_data2]bit2 = 1bit1 = 0break

case 7: seg_data=seg[seg_data2]bit2 = 0break

case 8: seg_data=seg[seg_data3]bit3 = 1bit1 = 0break

case 9: seg_data=seg[seg_data3]bit3 = 0break

}

goto S

}

if (bit2_shanshuo == 1)

{

if (judge_segdata == 1)

{

seg_data=seg[seg_data2]bit2 = 1

goto S

}

if (judge_segdata == 100)

{

seg_data=seg[seg_data2]bit2 = 0

goto S

}

if (judge_segdata == 200)

goto S

switch (judge_segdata%10)

{

case 2: seg_data=seg[seg_data1]bit1 = 1bit2 = 0break

case 3: seg_data=seg[seg_data1]bit1 = 0break

case 4: seg_data=seg[seg_data3]bit3 = 1bit2 = 0break

case 5: seg_data=seg[seg_data3]bit3 = 0break

case 6: seg_data=seg[seg_data1]bit1 = 1bit2 = 0break

case 7: seg_data=seg[seg_data1]bit1 = 0break

case 8: seg_data=seg[seg_data3]bit3 = 1bit2 = 0break

case 9: seg_data=seg[seg_data3]bit3 = 0break

}

goto S

}

if (bit3_shanshuo == 1)

{

if (judge_segdata == 1)

{

seg_data=seg[seg_data3]bit3 = 1

goto S

}

if (judge_segdata == 100)

{

seg_data=seg[seg_data3]bit3 = 0

goto S

}

if (judge_segdata == 200)

goto S

switch (judge_segdata%10)

{

case 2: seg_data=seg[seg_data1]bit1 = 1bit3 = 0break

case 3: seg_data=seg[seg_data1]bit1 = 0break

case 4: seg_data=seg[seg_data2]bit2 = 1bit3 = 0break

case 5: seg_data=seg[seg_data2]bit2 = 0break

case 6: seg_data=seg[seg_data1]bit1 = 1bit3 = 0break

case 7: seg_data=seg[seg_data1]bit1 = 0break

case 8: seg_data=seg[seg_data2]bit2 = 1bit3 = 0break

case 9: seg_data=seg[seg_data2]bit2 = 0break

}

}

}

S: judge_segdata++

}

/******************************************************************************

定时计数器1的中断服务子程序, 用于定时扫描数码管

******************************************************************************/

unsigned char dc1=1

void time1_interrupt() interrupt 3 using 2

{

TH1=0XF8//T1重新装入初值

TL1=0X30

dc1++

if (dc1 == 100) //200ms到了?数码管计数加1

{

dc1 = 0

if (jishu_key == 1)

{

seg_data1++

if (seg_data1 == 10)

{

seg_data1 = 0

seg_data2++

}

if (seg_data2 == 10)

{

seg_data2 = 0

seg_data3++

}

if (seg_data3 == 10)

seg_data3 = 0

}

}

seg_display()

}

#define second variable1.a

static unsigned char dc2=0

/******************************************************************************

定时计数器0的中断服务子程序, 用于定时扫描数码管

******************************************************************************/

void time0_interrupt() interrupt 1 using 3

{

TH0=0X3c//T0装入初值,继续50ms定时

TL0=0Xb0

dc2++//50ms计数变量加1

if (dc2 == delaytime) //2s到了?

{

second = 1//布尔型变量second置位

dc2=0

}

}

/******************************************************************************

延时程序

******************************************************************************/

void delay(int time0)

{

unsigned char i

for(time0 >= 0time0--)

{

for(i=0i<120i++)

}

}

/******************************************************************************

按键执行程序

******************************************************************************/

#define timedelay1 50

void key_function()

{

unsigned char j=0

bit1_shanshuo = 1//数码管第一位闪烁

delay(500)//延时500ms

delaytime = 100 //定时器0 定时100*50ms = 5000ms=5s

TH0=0X3c

TL0=0Xb0

TR0 = 1//开启T0,定时5s

while(!second) //如果5秒内没有按键,则按键设置程序返回

{

if (K1 == 0)

{

dc2 = 0//清零T0十秒计数变量

j++

}

if (j >3)

j=1

switch (j)

{

case 1:bit1_shanshuo = 1bit2_shanshuo = 0bit3_shanshuo = 0break

case 2:bit1_shanshuo = 0bit2_shanshuo = 1bit3_shanshuo = 0break

case 3:bit1_shanshuo = 0bit2_shanshuo = 0bit3_shanshuo = 1break

default: break

}

if (K2 == 0)

{

dc2 = 0//清零T0十秒计数变量

switch (j)

{

case 1: seg_data1++if (seg_data1>9) seg_data1=0break

case 2: seg_data2++if (seg_data2>9) seg_data2=0break

case 3: seg_data3++if (seg_data3>9) seg_data3=0break

}

}

if (K3 == 0)

{

dc2 = 0//清零T0十秒计数变量

switch (j)

{

case 1: seg_data1--if (seg_data1>9) seg_data1=0break

case 2: seg_data2--if (seg_data2>9) seg_data2=0break

case 3: seg_data3--if (seg_data3>9) seg_data3=0break

}

}

delay(400)//延时400ms

}

jishu_key = 1//数码管继续计数

TR0 = 0

}

/******************************************************************************

K1键扫描程序

******************************************************************************/

void key_press()

{

if (K1 == 0) //key1按下?

{

jishu_key = 0//数码管停止计数

delaytime = 40//定时器1定时40*50ms = 2s

TH0=0X3c

TL0=0Xb0

TR0 = 1//T0开始定时

delay(10)//消除键盘抖动

while (!K1) //等待

{

if (second == 1)//两秒计数变量为1?

{

TR0 = 0//关闭T0

second = 0

key_function()

return

}

}

TR0 = 0

jishu_key=1

}

}

void main()

{

K1 = 1

K2 = 1

K3 = 1

second = 0

jishu_key = 1

bit1_shanshuo =0

bit2_shanshuo =0

bit3_shanshuo =0

time0_time1_initialize()

while(1) //不断执行

key_press()

}

花了我一整个上午的时间,再给我70分

很简单的。

循环(1){

检测按键,等待按下;

发现按下后,延时消抖,等待释放,然后执行下面的循环;

循环(1){ //循环检测1秒钟

 发现按下后,灯亮,等待释放,然后就跳出循环;

 延时10ms

 次数加一

 次数不到100,继续循环

 到了100(即1s了),关灯,然后就跳出循环;

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12021517.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存