C:Userszhoukai53670
#include<avr/io.h>
#include<avr/delay.h>
int main()
{
char temp,key;
DDRA = 0x0f;
while(1)
{
PORTA = 0x08;//设置行4输出高电平,其它为低电平
temp = PINA;//读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//是否有按键按下
{
_delay_ms(20);//延时20ms消抖
temp = PINA;//再次读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//确认有按键按下
{
temp = PINA;
temp &= 0xf0;
switch(temp)
{
case 0x10 : key =1;break;
case 0x20 : key =2;break;
case 0x40 : key =3;break;
case 0x80 : key =4;break;
}
}
}
while(temp != 0x00)//松手检测
{
temp = PINA;
temp &= 0xf0;
}
PORTA = 0x04;//设置行3输出高电平,其它为低电平
temp = PINA;//读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//是否有按键按下
{
_delay_ms(20);//延时20ms消抖
temp = PINA;//再次读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//确认有按键按下
{
temp = PINA;
temp &= 0xf0;
switch(temp)
{
case 0x10 : key =5;break;
case 0x20 : key =6;break;
case 0x40 : key =7;break;
case 0x80 : key =8;break;
}
}
}
while(temp != 0x00)//松手检测
{
temp = PINA;
temp &= 0xf0;
}
PORTA = 0x01;//设置行2输出高电平,其它为低电平
temp = PINA;//读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//是否有按键按下
{
_delay_ms(20);//延时20ms消抖
temp = PINA;//再次读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//确认有按键按下
{
temp = PINA;
temp &= 0xf0;
switch(temp)
{
case 0x10 : key =9;break;
case 0x20 : key =10;break;
case 0x40 : key =11;break;
case 0x80 : key =12;break;
}
}
}
while(temp != 0x00)//松手检测
{
temp = PINA;
temp &= 0xf0;
}
PORTA = 0x01;//设置行1输出电平,其它为低电平
temp = PINA;//读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//是否有按键按下
{
_delay_ms(20);//延时20ms消抖
temp = PINA;//再次读取PA口电平
temp &= 0xf0;//屏蔽行电平
if(temp != 0x00)//确认有按键按下
{
temp = PINA;
temp &= 0xf0;
switch(temp)
{
case 0x10 : key =13;break;
case 0x20 : key =14;break;
case 0x40 : key =15;break;
case 0x80 : key =16;break;
}
}
}
while(temp != 0x00)//松手检测
{
temp = PINA;
temp &= 0xf0;
}
}
}
哪位大哥帮我看一看这个程序有什么问题?
我用PROTUES仿真的时候,当按键被按下后,对应被设置为输入的IO口就出现高电平,这是正常的,可是我松手后对应被设置为输入的IO口还是高电平,感觉像是开关没有弹起一样,后来试了好久都找不到原因。后来我注释掉其中三行,只留一行按键却很正常,哪位大哥帮我看一看,我真的很想知道原因。
此帖出自
小平头技术问答
如果是输入下拉状态就用高电平扫,比如0001,0010,0100,1000...
函 数 名:uchar Key_scan(void)
功 能:4x4按键,按键扫描
说 明:对按键进行扫描,从而得到键编码
入口参数:无
返 回 值:有键按下返回:键编码=行扫描值+列扫描值;无按键返回0
*****************************************************/
uchar Key_scan(void)
{
uchar key; // 存放键编码
P1=0xf0; // 取高 4 位值.即:列扫描值
key=P1&0xf0; // 存放键编码的高4位
P1=0x0f; // 取低 4 位值.即:行扫描值
key=(P1&0x0f)|key; // 低4位与高4位进行合并
if(key!=0xff)
{
return(key); // 有键按下,返回键编码
}
return(0); // 无键按下,返回0
}
/*****************************************************
函 数 名:uchar Key_switch(void)
功 能:按键转换程序
说 明:对按键码进行转换
入口参数:无
返 回 值:ASCII码
*****************************************************/
uchar Key_switch(void)
{
uchar key;
key=Key_scan();
Delay5Ms();
switch(key)
{
case 0xee:return(49);break; /* "1"键 */
case 0xed:return(50);break; /* "2"键 */
case 0xeb:return(51);break; /* "3"键 */
case 0xe7:return(65);break; /* "A"键 */
case 0xde:return(52);break; /* "4"键 */
case 0xdd:return(53);break; /* "5"键 */
case 0xdb:return(54);break; /* "6"键 */
case 0xd7:return(66);break; /* "B"键 */
case 0xbe:return(55);break; /* "7"键 */
case 0xbd:return(56);break; /* "8"键 */
case 0xbb:return(57);break; /* "9"键 */
case 0xb7:return(67);break; /* "C"键 */
case 0x7e:return(42);break; /* "*"键 */
case 0x7d:return(48);break; /* "0"键 */
case 0x7b:return(35);break; /* "#"键 */
case 0x77:return(68);break; /* "D"键 */
case 0x00:return(00);break; /* "无"键 */
}
return(00);
}
[ 本帖最后由 Timson 于 2013-7-2 10:04 编辑 ]
一周热门 更多>