怎么用C语言C51程序实现单片机按键长按开机与长按关机

怎么用C语言C51程序实现单片机按键长按开机与长按关机,第1张

首先需要硬件支持,也就是单片机某个引脚可以控制断电和维持上电

按键的的作用也可以给单片机供电,并且还要有个专门的引脚检测按键状态。

软件:首先是长按判断。这个最好用按键扫描。就是检测按键按下时候,定时器计时,如果松开就立即清零。在设置一个功能函数检测定时值,大于两秒后,就表示长按。

按键按下单片机供电开始计时,如果达到长按标准,就输出引脚控制持续供电,这时候按键松了也不会断电。

运行期间,按键再次按下并符合长按,那木引脚输出停止供电,这时候如果按键松开,那就彻底没电关机。

不能给你程序,只能给你思路。\x0d\ \x0d\设置定时器(建设100ms),在设置一个变量x,(100ms自加1)\x0d\在主循环中判断按键是否按下,并判断x的值大小;\x0d\ \x0d\假设 x每隔100ms加1 \x0d\y是按键状态(为1表示按下,为0 表示未按)\x0d\z记录按键状态的(初始值0)\x0d\b 记录长安 a记录短按\x0d\eg:\x0d\ \x0d\if(!z)\x0d\{\x0d\ if(y)\x0d\ {\x0d\ a=1; \x0d\ z=1;\x0d\ }\x0d\}\x0d\else if(x>10)// 1s\x0d\{\x0d\ b=1;\x0d\}

按下时发送正常的编码,发送完毕,若按键依然按下,则发送重复码,重复码和引导码有共同的特点,就是周期短了一些(引导:135ms;重复:1125ms),这个不就可以区分了吗?

只要接收的码周期是135,即一组新发送的编码,若是1125则是重复码,重复码时,则将之前接收到的编码作为本次接收到的编码处理即可。

定义一个延时函数,检测到按键按下后,延时一个很短的时间,再检测该按键,如果已释放,则为短按,同时将长按的计数器清零;延时一个较长的时间,如再次检测到按键还处于按下状态,则为长按,同时将短按的计数器清零

放定时器呗,将按钮闭合作为计时器的输入条件,当你按按钮,计时器就开始计时,然后计时器的数值,可以拿出比较,判断时间长短。当然也可以放计数器,用定时脉冲检测按钮,按钮闭合就计数,从而判断时间长短

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

晶振:12MHZ

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

#include<reg52H>

#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 variable1c

#define bit2_shanshuo variable1d

#define bit3_shanshuo variable1e

#define jishu_key variable1f

/

动态扫描显示程序

/

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 = 1;break;

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

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

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

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

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

}

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 = 1;bit1 = 0;break;

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

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

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

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

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

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

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

}

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 = 1;bit2 = 0;break;

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

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

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

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

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

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

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

}

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 = 1;bit3 = 0;break;

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

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

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

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

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

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

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

}

}

}

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 variable1a

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 >= 0;time0--)

{

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

}

}

/

按键执行程序

/

#define timedelay1 50

void key_function()

{

unsigned char j=0;

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

delay(500); //延时500ms

delaytime = 100 ; //定时器0 定时10050ms = 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 = 1;bit2_shanshuo = 0;bit3_shanshuo = 0;break;

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

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

default: break;

}

if (K2 == 0)

{

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

switch (j)

{

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

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

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

}

}

if (K3 == 0)

{

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

switch (j)

{

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

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

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

}

}

delay(400); //延时400ms

}

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

TR0 = 0;

}

/

K1键扫描程序

/

void key_press()

{

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

{

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

delaytime = 40; //定时器1定时4050ms = 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分

短按

用电平变换中端口最好

直接if(rb0)判断就行了

长按

if(rb0)

dealy(100ms);

if(rb0)

do;

抖动,就是一个确定的延时检测时间

if(rb0)

delay(10ms);

if(rb0)

do;

以上就是关于怎么用C语言/C51程序实现单片机按键长按开机与长按关机全部的内容,包括:怎么用C语言/C51程序实现单片机按键长按开机与长按关机、单片机按键短按和长按的程序、单片机C语言,红外线遥控器,长按按键一直按下程序该怎样区分呢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10180079.html

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

发表评论

登录后才能评论

评论列表(0条)

保存