173 2438 5004
KEROS加密芯片——品牌直销 | 免费样品 | 技术支持
当前位置:网站首页 > 资讯中心 正文 资讯中心

4x4矩阵按键stm32中断

keros@mark 2023-03-19 资讯中心

用STM32做矩阵键盘、自己理解的外部中断方式的几个问题。

EXTI是边沿触发的。

当你按下键时,肯定会出现抖动,那抖动一次就是一个边沿,自然会一次次的触发中断了。我以前也试验过,很不好使。

用systick扫描是一个办法,我用这个实现了线反转法扫描4X4的键盘矩阵。设置10ms中断一次,每次进中断首先检查有没有按键,如果没有就pass,如果有就先计个数再退出,重复三次操作确定都有按键(也就完成了消抖),然后翻转线路状态扫描一次确定行列位置,这样就确定键值了。

求个单片机矩阵键盘(4*4)中断(记得要中断)的C语言程序。。求高手自己写个啊

很简单的啊,不太清楚你的电路图,我把主要程序写一下:

#includereg52.h

unsigned char flag=0;//设置flag作为标志位,初值为0,一旦产生中断,将其置1

void main()

{

EA=1;//开总中断

EX0=1;//开外部中断0 ,假设是由P3.2产生的中断

IT0=1;//设置产生中断的方式,这是表示下降沿触发

P0=0X0F;//假设矩阵键盘接P0口,给所有列线低电平,所有行线高电平

while(1)

{

if(flag==1) //这个是表示,如果中断不产生,下面的程序不会运行,只有中断了,才会键盘扫描

{

按键扫描程序,这个我就不写了,写法有很多啦

}

数码管显示程序,这个我也不写了,不晓得你是什么电路图

}

}

void scan() interrupt 0

{

flag=1;//表示,一旦中断产生了,将flag置1

}

希望对你有用,呵呵

单片机4x4按键中断扫描法中的键盘编码的问题

嗯,想法很不错..

我试着帮你解释下第一个吧..

这应该是选用的线扫法(好像这么说的吧).

比如说,键盘口为,P1

在一开始输出,01111111B,再判断P1口值是否变化..

若没变化再换成,10111111B,再判断P1口值是否变化..

这样依次到,11101111B,

在有变化时就可以得到把描码了..就像是你那个表中所示.的数值就经过这四次都可以得出其中一种....

#includereg51.h

#define uchar unsigned char

#define KeyPad P0

code uchar key_tab[17]=

{0xed,0x7e,0x7d,0x7b,

0xbe,0xbd,0xbb,0xde,

0xdd,0xdb,0x77,0xb7,

0xee,0xd7,0xeb,0xe7,0XFF};

code uchar key_show[]=

{1,2,3,0x0a,

4,5,6,0x0b,

7,8,9,0x0e,

0x0c,0,0x0d,0x0f,0xff};

uchar Keyscan()

{

uchar i=0x01,j,k;

KeyPad=~i;

j=~i;

for (k=0;k4;k++)

{

if(KeyPad==j)

{

i*=2;

KeyPad=~i;

j=~i;

}

else

k=KeyPad;//取出扫描码.

}

i=0;

if(k!=4)

{

while(key_tab[i++]!=0xff)

{

if(k==key_tab[i])

k=i;

else

k=16;

}

}

return key_show[k];

}

以上是整个扫描键盘子程序..

程序编译通过,不知道实际怎么样..

其中未用中断..

不过,方法是一样的...

明白思想才是最重要的..

祝你好运!

^_^

求MSP430单片机4X4矩阵键盘的中断扫描程序?

//msp430F149

4*4矩阵键盘P1口中断扫描

#includemsp430x14x.h

#define

KEY_DIR

P1DIR

#define

KEY_OUT

P1OUT

#define

KEY_IN

P1IN

#define

KEY_IE

P1IE

#define

KEY_IES

P1IES

#define

KEY_IFG

P1IFG

/***************全局变量***************/

unsigned

char

Key_Val;

//存放键值

void

CtrlKey(unsigned

char

sw);

//控制键盘开关//sw=0关

sw=1开

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

函数名称:Init_Keypad

能:初始化扫描键盘的IO端口

数:无

返回值

:无

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

void

Init_Keypad(void)

{

KEY_DIR

=

0x0f;

//P1.0~P1.3设置为输出状态,P1.4~P1.7输入

状态(上拉H)

KEY_OUT=0;

KEY_IES

=0xf0;

//P1.4~P1.7允许中断

KEY_IE

=0xf0;

//P1.4~P1.7下降沿触发中断

KEY_IFG=0;

//中断标志清0

Key_Val

=

0;

}

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

函数名称:Check_Key

能:扫描键盘的IO端口,获得键值

数:无

返回值

:无

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

//p14\5\6\7

接上拉电阻

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

key_Val

对应键值

列:[p14]

[p15]

[p16]

[p17]

行:

[p13]→

1

2

3

4

[p12]→

5

6

7

8

[p11]→

9

10

11

12

[p10]→

13

14

15

16

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

void

Check_Key(void)

{

unsigned

char

row

,col,tmp1,tmp2;

unsigned

char

keymap[]

=

{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};//设置键盘逻辑键值

与程序计算键值的映射

tmp1

=

0x08;

for(row

=

0;row

4;row++)

//行扫描

{

KEY_OUT

=

0x0f;

//P1.4~P1.7输出全1

KEY_OUT

-=

tmp1;

//P1.4~p1.7输出四位中有一个为0

tmp1

=1;

if((KEY_IN

0xf0)0xf0)

//是否P1IN的P1.0~P1.3中有一位为0

{

tmp2

=

0x10;

//

tmp2用于检测出哪一位为0

for(col

=

0;col

4;col++)

//

列检测

{

if((KEY_IN

tmp2)

==

0x00)

//

是否是该列,等于0为是

{

Key_Val

=

keymap[row*4

+

col];

//

获取键值

return;

//

退出循环

}

tmp2

=

1;

//

tmp2右移1位

}

}

}

}

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

函数名称:delay

能:延时约15ms,完成消抖功能

数:无

返回值

:t=

tmp*5*clk

根据使用时钟调整tmp值

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

void

delay(void)

{

unsigned

int

tmp;

for(tmp

=

12000;tmp

0;tmp--);

}

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

函数名称:Key_Event

能:检测按键,并获取键值

数:无

返回值

:无

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

void

Key_Event(void)

{

unsigned

char

tmp;

KEY_OUT

=0;

//

设置P1OUT全为0,等待按键输入

tmp

=

KEY_IN;

//

获取

p1IN

if((tmp

0xf0)

0xf0)

//如果有键按下

{

delay();

//消除抖动

Check_Key();

//

调用check_Key(),获取键值

}

}

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

控制打开或者关闭键盘中断

SW=

0:关闭;

ELSE:打开

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

void

CtrlKey(unsigned

char

sw)

{

if(sw==0)

KEY_IE

=0;

//关闭端口中断

else

KEY_IE

=0xf0;

//打开端口中断

}

/*端口1按键中断*/

#pragma

vector=PORT1_VECTOR

__interrupt

void

Port(void)

{

if((KEY_IFG0xf0)!=0)

{

Key_Event();

if(Key_Val!=0)

//键值!=0有键按下

{

CtrlKey(0);

//关键盘中断

}

}

KEY_IFG=0;KEY_OUT=0;

//清中断标志

}

STM32 4*4矩阵键盘的疑惑 程序中通过扫描方式实现,但不能实现功能。调用库函数时,有个函数不明白设置的

GPIO_Write(GPIOB,(GPIOB-ODR 0xfff0 | 0xf))

这个地方是说!你先把GPIOB口的输出寄存器低四位清零,让后在把他与0xf相与在把低四位置高。

GPIOB是32位寄存器所以,0xfff0正好是32位,那个0xf是0x0f的意思!

我要用嵌入式知识配置4个按键的中断,下面是stm32外部中断的初始化函数的参考代码,该怎么修改。

寄存器配置一定要看手册来配,不然谁会

STM32的GPIO多很多,所有的GPIO口都可用作外部中断,但同组的只能选择一个,如GPIOA的第1脚与其他都是1脚(如GPIOC的第一脚)的归为一组,所以SYSCFG-EXTICR[0] = ~(0x0f (0 * 4));这句是来配置外部中断0的中断线选择GPIOA的,即GPIOA的第0脚;

EXTICR[0]是选择外部中断0到3的,其他以此类推。

例如你的按键为PC5,则你选择外部中断5,

SYSCFG-EXTICR[1] = ~(0x0f (1 * 4));

配置成上升沿触发EXTI-RTSR |= 1 5;

或者配置成下降沿触发EXTI-FTSR |= 1 5;

或者两者都行,这需要看你的外部电路,按下由低电平转高则选上升沿

最后开放对应中断线的请求EXTI-IMR |= 1 5;

后面那几行根据你的要求写中断分组,中断优先级,最后写你的中断函数

本文标签:4x4矩阵按键stm32中断

产品列表
产品封装
友情链接