⑴ 51单片机,定时中断与键盘扫描的问题。
-----------------------------------------------------------
从上面的这段代码来看,你在主函数里调用了扫描函数扫描按键,软件置TF0=1产生定时中断,而事实上,T0已在处理在定时中断的当中,然而中断函数使用了下面的语句:
while(keybuf!='E')
{
move(0x00);//移动LCD光标
getkey();
wrdata(keybuf);//向LCD当前位置写入键盘值,此处scan()无效
}
这些语句很容易让程序处在中断当中而无法退出,建议你在中断当中用if语句适合。
同时,我建议你在编写程序时注意程序的结构,尽量模块化,一个函数在中断外部调用了,就不要在中断外部再调用,中断当中注意使用while语句,防止处在中断当中退不出来或不确定状态。
------------------------------------------------
米德电子-Mide
Technology研发中心
http://www.csmide.cn
------------------------------------------------
⑵ 单片机 键盘扫描 这个程序是如何工作的
别人写的代码我很难分析,代码也不全,就不想费时间分析,大概的思路,就是将接键盘的IO口设为输入,当按下时位低电平,就能判断哪个被按下。具体的是,4*4,四行四列,表示16个数,四个接行数,数个接列数,具体的接法就不说了,网上有,叫矩阵键盘,然后就是一直扫描,if语句判断哪行被按下,在扫描列,就可以对应到具体的按键了,然后就可以跳到相应的处理函数进行处理。
⑶ 单片机4x4按键中断扫描法中的键盘编码的问题
嗯,想法很不错..
我试着帮你解释下第一个吧..
这应该是选用的线扫法(好像这么说的吧).
比如说,键盘口为,P1
在一开始输出,01111111B,再判断P1口值是否变化..
若没变化再换成,10111111B,再判断P1口值是否变化..
这样依次到,11101111B,
在有变化时就可以得到把描码了..就像是你那个表中所示.的数值就经过这四次都可以得出其中一种....
#include<reg51.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;k<4;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];
}
以上是整个扫描键盘子程序..
程序编译通过,不知道实际怎么样..
其中未用中断..
不过,方法是一样的...
明白思想才是最重要的..
祝你好运!
^_^
⑷ 单片机行列式键盘扫描原理
单片机行列式键盘扫描原理如下:
1、行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。
2、延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。
3、单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平。
4、此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。
(4)单片机中断键盘怎么扫描扩展阅读
单片机学习方法
1、基础理论知识学习
基础理论知识包括模拟电路、数字电路和C语言知识。。在学习单片机之前,觉得模拟电路和数字电路基础不好的话,不要急着学习单片机,应该先回顾所学过的模拟电路和数字电路知识,为学习单片机加强基础。
2、单片机实践
准备一台电脑、一块单片机开发板、一套视频教程、一本单片机教材和一本C语言教材。电脑是用来编写和编译程序,并将程序代码下载到单片机上;开发板来运行单片机程序,验证实际效果。
⑸ 单片机键盘扫描程序
2*3的键盘,太简单了,不值得用循环,特别是双重循环。
最简明、高效的程序如下:
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
char scan_key(void)
{
P13 = 0;
if (!P10) return 0;
if (!P11) return 1;
if (!P12) return 2;
P13 = 1;
P14 = 0;
if (!P10) return 3;
if (!P11) return 4;
if (!P12) return 5;
}
本程序,使用的变量最少,也不涉及其它接口。
代码最少,执行效率最高。
⑹ 简述单片机键盘扫描工作过程
键盘由行线列线交叉而成。列线接有上拉电阻。对第一行的行线置0,然后读取列线码,如果所有列线都是1说明买有被按下的键,继续扫描下一行。直到能读到0为止,读到0时所扫描的行就是该键的行码,而0所在的位是列码。一般的键盘扫描都做成中断形式,把列线所有线相与,只要有一个0就输出0,将这个信号送给中断,就可以实现在有键被按下时开启扫描了。
⑺ 单片机利用中断扫描独立式按键
你定时器中断后,扫描下即便扫描到有按键按下先做个标记,等待下次中断进入后,根据标记先判断是否按键还处于按下状态,是的话,经过你的再次定时器中断,也已经实现了消抖延时的作用。此时可以采集按键值。
⑻ 单片机外部中断有那些用处可不可以在中断里放一个键盘扫描程序
外部中断,需要有一个外部脉冲信号加到P3.2 或P3.3,引起中断,才能执行到中断服务程序。
要在中断里放一个键盘扫描程序,那得需要键盘引起中断才行的。多个独立式按键,或矩阵式键盘,都不方便产生一个中断信号的。
外部中断,不是为了键盘的,为什么会想到用键盘呢?
⑼ 单片机独立式按键的外部中断扫描
#include<reg51.h>
#include<intrins.h>
#defineucharunsignedchar
ucharkey;
voidext0()interrupt0
{
if(P1&0x01)key=1;
elseif(P1&0x02)key=2;
elseif(P1&0x04)key=3;
elseif(P1&0x08)key=4;
elsekey=0;
}
voiddelay(uchara)
{
uchari;
while(a--)for(i=0;i<120;i++);
}
main()
{
ucharled,i,j;
while(1)
{
switch(key)
{
case1:
led=0xfe;
for(i=0;i<10;i++)
for(j=0;j<8;j++)
{
P1=led;
led=_crol_(led,1);
delay(200);
}
break;
case2:
led=0x7f;
for(i=0;i<10;i++)
for(j=0;j<8;j++)
{
P1=led;
led=_cror_(led,1);
delay(200);
}
break;
case3:
led=0x0f;
for(i=0;i<10;i++)
{
P1=led;
delay(200);
led=~led;
P1=led;
delay(200);
led=~led;
}
break;
case4:
for(i=0;i<10;i++)
{
P1=0x00;
delay(200);
P1=0xff;
delay(200);
}
break;
}
}
}
⑽ 求MSP430单片机4X4矩阵键盘的中断扫描程序
//msp430F149
4*4矩阵键盘P1口中断扫描
#include<msp430x14x.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_IFG&0xf0)!=0)
{
Key_Event();
if(Key_Val!=0)
//键值!=0有键按下
{
CtrlKey(0);
//关键盘中断
}
}
KEY_IFG=0;KEY_OUT=0;
//清中断标志
}