按键Word格式文档下载.docx
《按键Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《按键Word格式文档下载.docx(18页珍藏版)》请在冰点文库上搜索。
N
2
//去抖年龄下限
MaxRate
50
//重复前的延迟值
600ms
MinRate
20
//重复速度
240ms
leddark
83
//闪烁时灭时间1s
ledshow
//闪烁时亮时间1s
decimal
0x80
//小数点的段数
KEY_DDR
DDRC
KEY_PORTO
PORTC
KEY_PORTI
PINC
OUT
0x3f
IN
0xc0
KeyValue
LEDD_DDR
DDRB
LEDD_PORTO
PORTB
LEDS_DDR
DDRD
LEDS_PORTO
PORTD
LEDS_MASK
0xfc
LEDS_NUM
0x06
TRUE
1
FALSE
0
/*定义键盘扫描程序返回数据类型*/
typedef
struct
{
shiftcnt;
//上档键的个数值
funcnt;
//功能键的个数值
shiftval;
//最后扫描到的上档键的值
funval;
//最后扫描到的功能键的值
}
keyret;
/*定义显示字符段码*/
const
led_stroke[19]
=
//0,1,2,3,4,5,6,7,8,9
0x3F,
0x06,
0x5B,
0x4F,
0x66,
0x6D,
0x7D,
0x07,
0x7F,
0x6F,
//a,b,C,d,e,F,P,
0x77,
0x7C,
0x39,
0x5E,
0x79,
0x71,
0x73,
//all
on
all
off
0xff,
0x00
};
/*定义位选码*/
led_cs[LEDS_NUM]
0xfb,
//11111011
0xf7,
//11110111
0xef,
//11101111
0xdf,
//11011111
0xbf,
//10111111
0x7f
//01111111
led_buf[LEDS_NUM]
0x81,
0x82,
0x83,
0x84,0x85
*pb
&
led_buf[1];
//定义指向数码管数据缓冲区的指针
/*定义全局变量*/
task,
state;
//task:
按键状态,0:
去抖
1,重复的延迟
2,重复
//state:
显示位置变量
keydone,
keyprocess;
//keydone:
按键任务完成标志,为1表示已完成
//keyprocess:
按键有效标志,为1时表示对按键执行
keypre[2]
0x00,
//存放上次功能键和上档键的键值
//keypre0存放功能键
blink,
ledtime;
//blink:
闪烁控制寄存器,某位为1时闪烁
//d7d6d5d4d3d2d1d0
//xxxx1111
//ledtime:
累计闪烁时已点亮和已熄灭的时间
ledtask;
//ledtask:
当前的闪烁状态,0代表亮
keymark;
//keymark:
只是当前工作状态,为1时处于设定状态,为0时正常工作
enflash;
//enflash:
闪烁使能标志,1闪烁
shut_dis()
LEDS_PORTO|=LEDS_MASK;
//shut
display
/*******************************************************************************
*函数原型:
_crol_(uchar
data,uchar
shiftbit);
*功能:
字节左移shiftbit
*参数:
*说明:
shiftbit)
data
=0xff;
if(shiftbit>
8)return
0;
return
((~data)<
}
_cror_(uchar
字节右移shiftbit
((~data)>
>
void
send_shift(uchar
d);
将显示数据由B口送出
data)
data;
lflash();
闪烁处理。
ledtask指示当前的显示状态:
亮或灭,ledtask为0时亮
lflash()
if
(enflash
(blink
0x3f))
(ledtime--
==
0)
(!
ledtask)
ledtime
leddark;
else
ledshow;
ledtask
~ledtask;
//显示状态翻转
display(uchar
pos);
将pos对应的显示缓冲区的内容显示在第pos位数码管上
pos)
sflag;
shut_dis();
//关显示
sflag
(6-pos))
0x01;
//取出pos对应的数码管的闪烁控制位
(pos
send_shift(led_buf[0]);
//指示灯显示时直接将显示内容送显示端口
else
||
(sflag
!
ledtask))
//不闪烁或正处于闪烁的亮阶段
((led_buf[pos]
0x80)
0)
//不显示小数点,查表得到段码送显示端口
send_shift(led_stroke[led_buf[pos]
0x7f]
|decimal);
//显示小数点,把查表得到段码与小数点的段码与的结果送显示端口
0x7f]);
send_shift(0xff);
//pos位数码管不显示
led_cs[pos];
//送出位选码
scankey(keyret
*kpd);
键盘扫描,返回上档键个数,上档键值,功能键个数,功能键值
*kpd)
i,j;
OUT;
//定义数据端口为输出
|=
KeyValue;
//输出数据(输出检测码)
IN;
//定义数据端口为输入
i
(KEY_PORTI
KeyValue);
//取出键盘位
(i
KeyValue)
//检测是否有键按下
~KeyValue;
//组成完整的字节
(~i
RCtrl)
//该键是上档键
kpd->
shiftcnt++;
//上档键个数加1
?
//这里不对
for(j=0;
j<
6;
j++)
if((0x01<
j)==RCtrl)
shiftval
j+1;
//上档键值存入上档键值缓冲
j)==~i)
funcnt++;
//功能键个数加1
funval
=j+1;
//数据端口还原为输出
key();
key()
krpt
RConti;
static
keycnt;
keyesc;
keyret
keytemp
(keydone)
//上次按键任务已完成
scankey(&
keytemp);
//扫描键盘
keytemp.funcnt
keytemp.shiftcnt
1)
//功能键计数器为0或上档键个数多于1
enflash
1;
//允许闪烁
//
USART0_TransmitString("
shiftcnt!
"
);
keypre[0]
0x00;
//清零上次功能键和上档键缓冲
keypre[1]
//清零
keyesc
//键释放标志
清零
task
//按键状态
标志为去抖阶段
keycnt
//年龄计数器
keyesc)
//键已释放
按下上挡键后按键释放标志请零
keyesc!
(keytemp.funcnt
//有多于一个的功能键按下
//置位按键释放标志
//本次功能键值和上次不同或本次上档键值和上次不同且上次有上档键
(keytemp.funval
keytemp.shiftval
keypre[1])
keytemp.funval;
//用本次键值更新上次键值
keytemp.shiftval;
//年龄计数器复位
keytemp.shiftval)
//2次功能键相同,上次无上档键本次有
//置位keyesc,屏蔽先按下功能键,再按下上档键这种按键组合
keycnt++;
//2次功能键和上档键都相同
switch
(task)
case
0:
(keycnt
N)
keyprocess
//键值处理
((keytemp.shiftcnt
(krpt
-
1)
0x01))
//是一对复合键或该键不允许连击
task++;
//按键状态转入重复的延缓阶段
//按键年龄清0
break;
1:
//重复的延缓阶段
MaxRate)//按键年龄等于重复的延缓阶段
//不允许闪烁
//进行键值处理
//按键转入重复状态
2:
//重复阶段
MinRate)//重复时间到
key1_handler();
按键1处理
正常工作模式下,按下按键1即进入设定状态,此时第一个数码管闪烁,同时对应led1
的指示灯亮。
设定模式下,按下按键1,在led1和led4之间循环切换选择被选中的数码
管闪烁,相应的指示灯亮
key1_handler()
keymark)
//进入设定状态
led_buf[0]
0xfe;
//点亮第一个led
pb
//pb指向第一个数码管
//blink
0x80;
//第一个数码