本帖最后由 hkxiaoma 于 2015-6-16 10:18 编辑
废话不多说 直接上程序 希望大家积极分享自己的写法
用51举例 向下看 楼下还有的哦
- #include
- typedef unsigned char uchar;
- ***it KEY_Lplus = P1^0;
- void key();
- void Init_timer1(void);
- uchar Key1_ing=0;
- uchar K1count=0;
- uchar Key1_flag=0;//按键标志
- void main()
- {
- Key1_ing=0;K1count=0;Key1_flag=0;
- while(1)
- {
- if(Key1_flag==1)//按键有效
- {
- Key1_flag=0;
- ;//执行语句
- }
- }
- }
- void Timer1_isr(void) interrupt 3
- {
- key();
- TH1 = 0XF8;
- TL1 = 0X30;
- TR1 = 1;
- }
- void Init_Timer1(void)//定时器1初始化
- {
- TMOD = 0x11; //开定时器0 1
- EA = 1;
- ET1 = 1;
- TH1 = 0XF8;//2ms
- TL1 = 0X30;
- TR1 = 1;
- }
- void key()
- {
- if (!KEY_Lplus|Key1_ing)
- {
- if(!KEY_Lplus)
- {
- if(Key1_ing) {K1count=(K1count>=250)?250:(K1count+1);}
- else {Key1_ing=1;K1count=0;}
- }
- else
- {
- Key1_ing=0;
- if (K1count>=20)
- {
- Key1_flag=1;
- K1count=0;
- }
- else
- {
- K1count=0;
- }
- }
- }
- }
复制代码
10
-
-
按键.rar
498 Bytes
, 阅读权限: 20
, 下载次数: 7
|
|
|
|
- uchar Read_Keyboart_Indep() //独立键盘
- {
- static uchar Key_Static=0; //状态机变量
- uchar Key_Press; //读取按键电平变量
-
- Key_Press=0x0f&P2; //读取按键值变量
- switch(Key_Static) //选择按键状态
- {
- case 0:if(Key_Press!=0x0f) Key_Static=1; //有按键按下,转到下一状态
- break;
-
- case 1:if(Key_Press!=0x0f)
- {
- Key_Static=2;
- return Key_Press; //返回按键值
- }
- else Key_Static=0;
- break;
-
- case 2:if(Key_Press==0x0f) Key_Static=0; //判断按键是否松开,松开就返回到0态
- break;
-
- default:Key_Static=0;break;
- }
-
- return KeyIndep_NULL; //没有按键按下,返回空值
- }
复制代码
|
|
|
|
|
本帖最后由 hkxiaoma 于 2015-5-20 13:03 编辑
- 来自送码源A-湘-蓝 的分享
- define _MAIN_C
- #include "config.h"
- /*
- ********************************************************************************
- * ----------------------- Local variables -------------------------------------
- ********************************************************************************
- */
- const uint8 code LedNum[] = { //数码管显示的字符转化表
- LED_NUM_0, LED_NUM_1, LED_NUM_2, LED_NUM_3, LED_NUM_4,
- LED_NUM_5, LED_NUM_6, LED_NUM_7, LED_NUM_8, LED_NUM_9,
- LED_NUM_A, LED_NUM_b, LED_NUM_C, LED_NUM_d, LED_NUM_E, LED_NUM_F,
- };
- volatile uint8 KeySta[4][4]; //当前的按键状态
- /*
- ***************************************************************************************************
- * ---------------------------------- Source codes ------------------------------------------------
- ***************************************************************************************************
- */
- /*
- * 函数名:KeyScan
- * 描 述:矩阵式按键扫描函数
- * 备 注:本函数需在定时中断中调用,其定时时间和DEBOUNCE_MASK常数共同决定消抖时间;
- * 如调用本函数的中断服务函数用using指定了寄存器组,则本函数也需用using指定相同的寄存器组。
- */
- void KeyScan(void)
- {
- uint8 i;
- static uint8 iKeyOut=0;
- static uint8 KeyScanBuff[4][4];
- /* 扫描按键输入 */
- KeyScanBuff[iKeyOut][0] = ((KeyScanBuff[iKeyOut][0]<<1) | KEY_IN_1) & DEBOUNCE_MASK;
- KeyScanBuff[iKeyOut][1] = ((KeyScanBuff[iKeyOut][1]<<1) | KEY_IN_2) & DEBOUNCE_MASK;
- KeyScanBuff[iKeyOut][2] = ((KeyScanBuff[iKeyOut][2]<<1) | KEY_IN_3) & DEBOUNCE_MASK;
- KeyScanBuff[iKeyOut][3] = ((KeyScanBuff[iKeyOut][3]<<1) | KEY_IN_4) & DEBOUNCE_MASK;
- /* 消抖后更新按键状态 */
- for (i=0; i<4; i++) {
- if (KeyScanBuff[iKeyOut] == DEBOUNCE_MASK) {
- KeySta[iKeyOut] = KEY_UP;
- }
- else if (KeyScanBuff[iKeyOut] == 0) {
- KeySta[iKeyOut] = KEY_DOWN;
- }
- }
-
- /* 执行下一列按键输出 */
- iKeyOut = (iKeyOut+1) & 0x3;
- switch (iKeyOut) {
- case 0:
- KEY_OUT_4 = 1;
- KEY_OUT_1 = 0;
- break;
- case 1:
- KEY_OUT_1 = 1;
- KEY_OUT_2 = 0;
- break;
- case 2:
- KEY_OUT_2 = 1;
- KEY_OUT_3 = 0;
- break;
- case 3:
- KEY_OUT_3 = 1;
- KEY_OUT_4 = 0;
- break;
- default:
- break;
- }
- }
- /*
- * 函数名:KeyHandle
- * 描 述:按键动作分离及动作执行函数
- * 备 注:
- */
- void KeyHandle(void)
- {
- uint8 i, j;
- static uint8 bkKey[4][4];
-
- /* 检索按键状态的变化 */
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) {
- if (bkKey[j] != KeySta[j]) {
- if (bkKey[j] == KEY_UP) {
- /* 按键按下时的动作 */
- _nop_();
- }
- else {
- /* 按键弹起时的动作 */
- DISP_DB = LedNum[i*4+j];
- }
- bkKey[j] = KeySta[j];
- }
- }
- }
- }
- /*
- * 函数名:main
- * 描 述:工程的C语言入口函数
- * 备 注:
- */
- int main (void)
- {
- //按键扫描使用timer1
- TMOD = 0x11;
- PT1 = 0;
- ET1 = 1;
- TR1 = 1;
-
- DISP_A0 = 0;
- DISP_A1 = 0;
- DISP_A2 = 0;
- EN_LED2 = 1;
- EN_LED1 = 0;
- DISP_DB = 0xFF;
-
- EA = 1;
- while(1) {
- KeyHandle();
- }
- }
- /*
- * 函数名:Timer1_ISR
- * 描 述:Timer1定时中断服务函数
- * 备 注:定时1ms,执行按键扫描
- */
- void Timer1_ISR() interrupt 3
- {
- /* Timer1定时1ms */
- TL1 = (uint8)((65535 - SYS_MCLK/1000) + 20);
- TH1 = (uint8)(((65535 - SYS_MCLK/1000) + 20) >> 8);
- /* 按键扫描 */
- KeyScan();
- }
复制代码
|
|
|
|
|
楼主你的第二个思路挺像手把手教程里面的按键程序
#include
***it KEY_IN_1 = P2^4;
***it KEY_IN_2 = P2^5;
***it KEY_IN_3 = P2^6;
***it KEY_IN_4 = P2^7;
***it KEY_OUT_1 = P2^3;
***it KEY_OUT_2 = P2^2;
***it KEY_OUT_3 = P2^1;
***it KEY_OUT_4 = P2^0;
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
{ '1', '2', '3', 0x26 }, //数字键1、数字键2、数字键3、向上键
{ '4', '5', '6', 0x25 }, //数字键4、数字键5、数字键6、向左键
{ '7', '8', '9', 0x28 }, //数字键7、数字键8、数字键9、向下键
{ '0', 0x1B, 0x0D, 0x27 } //数字键0、ESC键、 回车键、 向右键
};
unsigned char pdata KeySta[4][4] = { //全部矩阵按键的当前状态
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
};
extern void KeyAction(unsigned char keycode);
/* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
void KeyDriver()
{
unsigned char i, j;
static unsigned char pdata backup[4][4] = { //按键值备份,保存前一次的值
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
};
for (i=0; i<4; i++) //循环检测4*4的矩阵按键
{
for (j=0; j<4; j++)
{
if (backup[i][j] != KeySta[i][j]) //检测按键动作
{
if (backup[i][j] != 0) //按键按下时执行动作
{
KeyAction(KeyCodeMap[i][j]); //调用按键动作函数
}
backup[i][j] = KeySta[i][j]; //刷新前一次的备份值
}
}
}
}
/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
void KeyScan()
{
unsigned char i;
static unsigned char keyout = 0; //矩阵按键扫描输出索引
static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
};
//将一行的4个按键值移入缓冲区
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
//消抖后更新按键状态
for (i=0; i<4; i++) //每行4个按键,所以循环4次
{
if ((keybuf[keyout][i] & 0x0F) == 0x00)
{ //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[keyout][i] = 0;
}
else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
{ //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[keyout][i] = 1;
}
}
//执行下一次的扫描输出
keyout++; //输出索引递增
keyout &= 0x03; //索引值加到4即归零
switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚
{
case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
default: break;
}
}
|
|
|
|
|
没看到有连按的,手写一个
//按住不动时,参数每10ms +1
uchar f;//设置参数
uchar key;
while(PINA&0X01)
{
f++;
_delay_ms(10);
}
|
|
|
|
|
mark,稍后再看
|
|
|
|
|
![](https://staticbbs.elecfans.com/static/image/smiley/default/biggrin.gif) 你好 led大神
|
|
|
|
|