单片机按键的解决方法Word格式.docx

上传人:b****8 文档编号:22253554 上传时间:2023-02-03 格式:DOCX 页数:15 大小:88.97KB
下载 相关 举报
单片机按键的解决方法Word格式.docx_第1页
第1页 / 共15页
单片机按键的解决方法Word格式.docx_第2页
第2页 / 共15页
单片机按键的解决方法Word格式.docx_第3页
第3页 / 共15页
单片机按键的解决方法Word格式.docx_第4页
第4页 / 共15页
单片机按键的解决方法Word格式.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

单片机按键的解决方法Word格式.docx

《单片机按键的解决方法Word格式.docx》由会员分享,可在线阅读,更多相关《单片机按键的解决方法Word格式.docx(15页珍藏版)》请在冰豆网上搜索。

单片机按键的解决方法Word格式.docx

3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。

GPIO外部中断:

STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间智能使用一个,如:

PA0,PB0,PC0,PD0,PE0,PF0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能使用了,在此情况下我们使用类似于PB1,PC2这种末端序号不同的外部中断源,每一组使用一个中断标志EXTIx.EXTI0~EXTI4这5个外部中断有着自己单独的中断响应函数。

EXTI5~EXTI9共用一个中断响应函数,EXTI10~EXTI15共使用一个中断响应函数。

对于中断的控制,STM32有一个专用的管理机构NVIC.中断的使能,挂起,优先级,活动等等都是由NVIC在管理的。

编写IO口外部中断步骤及其注意事项:

(1)设置中断优先级组;

(2)开启时钟(IO口时钟,复用时钟);

(3)设置中断线并对中断进行初始化配置(设置中断线,确定中断模式,中断触发沿设置,使用指定设置初始化外部中断);

(4)设置中断管理器NVIC各参数(包括:

使能产生外部中断外设的IO口所在的外部中断通道;

设置外部中断的优先级---抢占优先级,响应优先级;

使能外部中断通道;

使用设置好的各个中断管理器上的参数来初始化中断管理器)。

外部中断服务函数完成中断操作需要最终达到的目标。

3、矩阵形式

键盘矩阵原理:

a*b矩阵键盘由a条行线和b条列线组成,行线接端口P3(p3表任一端口)P3.0、P3.1、P3.2……p3.(a-1);

列线接p3.a,p3.(a+1)……P3.(b-1).按键位于每条行线和列线的交叉点上。

按键的识别可采用行扫描法和线反转法,这里采用简单的线反转法,只需三步。

第一步,执行程序使X0~X3均为低电平,此时读取各列线Y0~Y3的状态即可知道是否有键按下。

当无键按下时,各行线与各列线相互断开,各列线仍保持为高电平;

当有键按下时,则相应的行线与列线通过该按键相连,该列线就变为低电平,此时读取Y0Y1Y2Y3的状态,得到列码。

第二步,执行程序使Y0~Y3均为低电平,当有键按下时,X0~X3中有一条行线为低电平,其余行线为高电平,读取X0X1X2X3的状态,得到行码。

第三步,将第一步得到的列码和第二步得到的行码合并得到按键的位置码,即是Y3Y2Y1Y0X3X2X1X0(因为行线和列线各有一条电平,其余为高电平,所以位置码低四位和高四位分别只有一位低电平,其余为高电平)。

也就是说,当某个键按下时,该键两端所对应的行线和列线为低电平,其余行线和列线为高电平.比如,当0键按下时,行线X0和列线Y0为低电平,其余行列线为高电平,于是可以得到0键的位置码Y3Y2Y1Y0x3X2X1X0为11101110即是0xEE.

全部按键码为:

矩阵键盘在单片机上的简单应用-----显示数码管:

0~F(51单片机)

#include<

reg51.h>

#defineucharunsignedchar

#defineuintunsignedint

Sbitbuzzer=P1^0;

Ucharcode_dis[]=//0~9,A~F

{

0xC0,0XF9,0XA4,0xB0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0z88,0x83,

0xC6,0xA1,0x86,0x8E

};

Ucharcode_tab[]=//矩阵键盘按键位置码

0x77,0xb7,0xd7,0xe7,

0x7b,0xbb,0xdb,0xeb,

0x7d,0xbd,0xdd,0xed,

0x7e,0xbe,0xde,0xee

voiddelay(uintx)

//延时函数

uchari;

while(x--)

for(i=0;

i<

120;

i++);

}

ucharscan()//矩阵键盘扫描函数,得到按键号,采用线反转法

uchara,b,c,i;

P3=0XF0;

//P3口输出11110000

a=P3;

//读取列码

delay(10);

//防抖延时10ms

P3=0X0F;

//P3口输出00001111

b=P3;

//读取行码

c=a+b;

//得到位置码

16;

i++)

{

if(c==tab[i])returni;

//查表得到按键序号并返回

return-1;

//无按键,则返回-1

Voidbeep(void)//蜂鸣器发出声音,模拟按键声音

Uchari;

For(i=0;

100;

i++)

Buzzer=~buzzer;

Delay

(1);

Buzzer=0;

Voidmain(void)

ucharkey;

buzzer=0;

//关闭蜂鸣器

while

(1)

{key=scan();

//得到按键号

if(key!

=-1)//有按键则显示,并且蜂鸣器发出声音

{P0=dis[key];

beep();

delay(100);

}

扫描法:

矩阵键盘工作原理:

由于按键没有接地,4行 

4列正好占用8个I/O 

如果4行我们送P3.0到P3.3送入0111然后去读取4列的值,如果P3.0的按键按下那么P3.4---P3.7的值等于0111,假如是第2个键按下的话那么读回来的值是1011,如果第3个键按下去读回来的值是1101,如果第4个键按下去读回来的值是11 

10 

,如果没有键按下去读回来就是1111。

所以我们就根据读回来的值来判断按下去的是那个键。

当然这是对P3.0这一行,因为矩阵键盘是扫描的,所以下次把P3.0给1 

P3.1给0对第2行,陆续的第3行第4行,0111101111011110 

而每次都去从新扫描一遍列值列有4个值,以确定是那个键按下。

无论何时任何一个时间有一个按键被按下就跳出循环。

当然不可能有2个键刚好一起按下你的手没有这么好的力度,就算有2个键一起按键,程序也有先后检测的顺序,只能检测一个后面的检测不到。

P3=0XFE;

//第一行给0

temp;

定义个变量

temp=P3;

读回来 

由于读需要先写1 

因为P3=FE 

已经把高4位给1了 

所以能读了

temp&

oxf0 

如果没有按键按下结果还是0xf0.如果有键按下结果就不是0xf0了。

num 

然后我们再定义一个变量 

让它赋值给这个按下去的按键值。

一次类推把第一行赋值0扫描一遍然后把第2行赋值0扫描一遍..............共扫描16遍。

只要有键按下就会得到一个值num就从1排到16.共16个按键4*4的矩阵键盘。

我再总结下思路:

首先低4位是行共4行 

分别把每行给0低电平 

就4次0111 

、1011、1101、1110对吧

然后去检测高4位 

4列啊 

先不考虑极端情况,4列就4个按键只要按下一个P3口的高4位就会有一个值。

根据这个值就能判断是那个键了。

如:

P3=11111110 

低四位是行先把第一行给0 

有按键下的话temp=P3 

11011110 

然后temp&

0xf0 

与运算下就判断下还等于oxf0吗?

如还等于就没有按下,如果不等于就肯定有按键按下。

定义个变量让它等于这个不是0XF0的值,做个标记。

依次类推。

然后用这个思路写个程序吧!

写的不太好看的不是很清楚只是做个参考吧,只要把思路理清楚就行了。

是这样我们分别按这16个按键让它分别显示是第几个比如按下第一个数码管就显示1第2个数码管就显示2,依次类推。

一直到F 

(为了方便让所有的数码管显示同一个数0---F)

#include

#defineucharunsignedchar

sbitdula=P2^6;

sbitwela=P2^7;

sbitkey1=P3^4;

ucharcodetable[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,

0//加这个0就是什么都不显示

ucharnum,temp,num1;

voiddelay(uintz)

uintx,y;

for(x=z;

x>

0;

x--)

for(y=110;

y>

y--);

ucharkeyscan();

//声明一下

//voiddisplay(ucharnum1);

//这里可以做个显示函数,但是我没做。

voidmain(){

num=17;

//让它显示0什么都不显示。

因为函数返回num值

dula=1;

P0=0;

dula=0;

wela=1;

P0=0xc0;

wela=0;

//以上P0口控制数码管的一上电什么都不显示

while

(1){

num1=keyscan();

//没按下返回17

dula=1;

P0=table[num1-1];

//17-1=16

dula=0;

//用ucharkeyscan()带返回值的函数代替整个矩阵键盘 

当然显示就不要了dula 

那3行我注释掉了

ucharkeyscan(){

P3=0xfe;

//高4位是f等于写了1111也满足了先写1的要求

temp=P3;

//读回来了

=0xf0;

//因为我们只是读回来高4位

while(temp!

=0xf0){//下面的几个while循环判断可以用if好理解。

只看到第一行就行了。

//这几个while都是做判断用的

delay(5);

//消除抖动的

temp=P3;

while(temp!

=0xf0){//确实不等于0xf0有按键按下

temp=P3;

//我们这个时候只是把P3口的值赋给了temp

switch(temp){//检测P3口。

case 

0xee:

num=1;

break;

case 

0xde:

num=2;

break;

0xbe:

num=3;

case0x7e:

num=4;

=0xf0)//有按键按下可能是不等于的 

循环在这里面 

松手检测

temp=temp&

0xf0;

//这个是松手检测 

松手这里就等于了0xf0

}//下面就显示一下 

退出整个一行的循环,不加松手检测会退不出去循环

//到这里是把第一行检测了。

//////以下下是其他几行检测的代码

P3=0xfd;

//读回来

=0xf0){

0xed:

num=5;

0xdd:

num=6;

0xbd:

num=7;

case0x7d:

num=8;

temp=temp&

退出整个2行的循环。

不加松手检测会退不出去循环

//到这里是把第2行检测了。

P3=0xfb;

temp=P3;

temp&

while(temp!

delay(5);

temp=P3;

while(temp!

0xeb:

num=9;

0xdb:

num=10;

0xbb:

num=11;

case0x7b:

num=12;

{temp=P3;

//这个是松手检测松手这里就等于了0xf0 

}//下面就显示一下 

退出整个3行的循环。

不加松手检测会退不出去循环 

//到这里是把第3行检测了。

}

P3=0xf7;

switch(temp)//检测P3口

{

0xe7:

num=13;

0xd7:

num=14;

0xb7:

num=15;

case0x77:

num=16;

退出整个4行循环。

不加松手检测会退不出去循

//到这里是把第4行检测了。

return 

num;

//其实键盘扫描就需要一个值。

4、电阻分压控制按键

电阻分压控制按键方式原理:

利用电阻分压,使得不同按键处的电压值不同,通过检测按键处的电压值,判断是哪个按键按下了。

不同的按键可以看做是使用一个电位器旋钮采集一个ADC通道上的ADC值过程中电位器旋钮旋动过程中的不同位置。

注:

串联在电路中的电阻可以是相同阻值的电阻,也可以是不同电阻值的电阻。

一切视具体情况而定。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电力水利

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1