AVR 4*4键盘如何保持当前按下的值!并可以像计算器一样输入一排数

用的AVR M16。写了一个44键盘,值可以读取,但是我想让我按下的键保持,等下一次按键再改变为另一个值
此外,我还想可以在数码管上显示像计算器那样的效果,按一下数字,之前那个数向左移一位,这个程序里还没有,我希望大哥帮我看看,

如果你有更好的程序,可不可以发给我看看。

如果你的能用,真的很感谢,大量分相送~!

/*---------------------------------------------------------------
程序名称:4*4按键扫描程序
目标系统: 基于AVR单片机
应用软件: ICC AVR
注意: 晶振频率:8HMZ,经调试成功运行
循环扫描PD口接入的按键,并使用PB口的LED指示灯指示按键的码值。
并在数码管上显示数。
---------------------------------------------------------------*/
#include <iom16v.H>
#include <macros.h>

#define LED_DDR DDRB
#define LED_PORT PORTB
#define KEY_DDR DDRD
#define KEY_PORT PORTD
#define KEY_PIN PIND

#pragma data:code
const table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e};

#define uchar unsigned char
const uchar setSta_[4]={0xfe,0xfd,0xfb,0xf7};
// setSta={11111110 11111101 11111011 11110111}
const uchar getSta_[4]={0xe0,0xd0,0xb0,0x70};
/*---------------------------------------------------------------
程序名称:delay
程序功能:延时
----------------------------------------------------------------*/
void delay(uchar num)
{
uchar i,j;
for(num;num>0;num--)
{
for(i=100;i>0;i--)
for(j=100;j>0;j--);
}
}

uchar GetKeyVal()
{
uchar i,j,getSta,keyVal;
for(i=0;i<4;i++)
{
KEY_PORT=setSta_[i];
delay(1);
if(KEY_PIN!=setSta_[i])
{
getSta=KEY_PIN&0xf0;
for(j=0;j<4;j++)
if(getSta==getSta_[j])
{
keyVal=j+i*4;
return keyVal;
}
}
}
return 0xFF;
}
/*--------------------------------------------------------------------
程序名称:主函数
程序功能:
--------------------------------------------------------------------*/
void main()
{
uchar keyVal;
LED_DDR = 0XFF;
LED_PORT=0XFF;
KEY_DDR = 0X0F;

while(1)
{
keyVal = GetKeyVal();
delay(10);
LED_PORT=0XFF;

DDRC=0xff;
PORTC&=0x01; //数码管位选
DDRA=0xff;
PORTA=0xff;

if( keyVal!=0xFF )
{
LED_PORT =(keyVal); //LED低电平点亮

PORTC|=BIT(0);
PORTA=table[keyVal];
delay(100);
//这个下面是我为了保持状态而加的,不管用,别的键按不进的
//我知道这个地方已经进入死循环
while(PIND!=keyVal) //当前有按键处于按下状态,再按其他按键时程序维持当前
{
;
}
}
}
}

自己写的计算器,功能有限希望对你有帮助
//===============================================
//芯片:
ATMEGAL16L
//时间:
2009.08.04
//晶振频率:
7.3728MHZ
//目的:
按键显示
//===============================================
#include
<iom16v.h>
#include
<macros.h>
#define
uint
unsigned
int
#define
uchar
unsigned
char
//键盘引脚的定义:
#define
KEYSCLK
(1
<<
PA4)
#define
KEYDAT
(1
<<
PA5)
#define
KEYKBS
(1
<<
PA6)
//液晶显示屏的引脚定义:
#define
LCDSCL
(1
<<
PA2)
#define
LCDSTD
(1
<<
PA1)
#define
LCDCS
(1
<<
PC6)
#define
SET_BIT(x,y)
(
x
|=
(
1
<<
Y
)
)
;
#define
CLR_BIT(x,y)
(
x
&=
~(
1
<<
y
)
)
;
#define
GET_BIT(x,y)
(
x
&
(
1
<<
y
)
)
//================================================
//延时子函数
//================================================
void
Delayms(uint
x)
{
uchar
a
;
for(;
x>0;
x--)
{
for(a=1;
a
<=
198;
a++);
}
}
//******************************************************
//LCD液晶屏显示模块
//******************************************************
void
SendByte(uchar
byte)
{
uchar
i;
uchar
com
=
0x80;
for
(i=0;
i<8;
i++)
{
PORTA
&=
~LCDSCL;
NOP();
if
((byte
&
com)
==
0x80)
{
PORTA
|=
LCDSTD;
NOP();
}
else
{
PORTA
&=
~LCDSTD;
NOP();
}
PORTA
|=
LCDSCL;
NOP();
byte
<<=
1;
}
}
void
SendWord(uchar
dat)
{
uchar
h,l;
h
=
dat
&
0xF0;
l
=
(dat
<<
4);
SendByte(h);
SendByte(l);
}
void
SendIns(uchar
ins)
{
SendByte(0xF8);
SendWord(ins);
}
void
SendDat(uchar
dat)
{
SendByte(0xFA);
SendWord(dat);
}
void
Stop()
{
PORTA
&=
~LCDSCL;
PORTA
|=
LCDSTD;
}
void
Display(uchar
pst,uchar
h,uchar
a[])
{
uchar
i;
SendIns(pst);
for(i=0;
i<h;
i++)
{
SendDat(*(a+i));
}
}
void
LcdInit()
{
DDRA
|=
0x05;
DDRC
|=
0x04;
PORTC
&=
~LCDCS;
PORTC
|=
LCDCS;
NOP();
SendIns(0x01);
SendIns(0x02);
SendIns(0x0F);
}
//******************************************************************
//keyboard-键盘输入模块
//******************************************************************
uchar
GetKey()
{
uchar
i
,
key
=
16
;
DDRA
|=
0x50
;
PORTA
&=
~KEYSCLK
;
PORTA
|=
KEYKBS
;
PORTA
&=
~KEYKBS
;
NOP()
;
PORTA
|=
KEYKBS
;
for
(i=0;
i<16;
i++)
{
if
((PINA
&
0x20)
==
0x00)
{
key
=
i;
break;
}
PORTA
&=
~KEYSCLK
;
PORTA
|=
KEYSCLK
;
}
return
key;
}
uchar
KeyConf()
{
uchar
pre;
while(1)
{
while(GetKey()
==
16);
pre
=
GetKey();
Delayms(10);
if(GetKey()
==
pre)
{
break;
}
}
while(GetKey()
!=
16);
Delayms(20);
while(GetKey()
!=
16);
return
pre;
}
uchar
KeyDisplay(uchar
mn)
{
uchar
j;
j=mn;
switch(mn)
{
case
0:
{
SendDat(
0x30
);
Stop();
}
break
;
case
1:
{
SendDat(
0x31
);
Stop();
}
break
;
case
2:
{
SendDat(
0x32
);
Stop();
}
break
;
case
3:
{
SendDat(
0x33
);
Stop();
}
break
;
case
4:
{
SendDat(
0x34
);
Stop();
}
break
;
case
5:
{
SendDat(
0x35
);
Stop();
}
break
;
case
6:
{
SendDat(
0x36
);
Stop();
}
break
;
case
7:
{
SendDat(
0x37
);
Stop();
}
break
;
case
8:
{
SendDat(
0x38
);
Stop();
}
break
;
case
9:
{
SendDat(
0x39
);
Stop();
}
break
;
case
10:
{
SendDat(
0x2B
);
Stop();
}
break
;
/*+*/
case
11:
{
SendDat(
0x2D
);
Stop();
}
break
;
/*-*/
case
13:
{
SendDat(
0x2A
);
Stop();
}
break
;//*
case
12:
{
SendDat(
0x2f
);
Stop();
}
break
;
///
case
14:
{
LcdInit();
SendIns(0x01);
Stop();
}
break
;
/*clear*/
case
15:
{
SendDat(
0x3D
);
Stop();
}
break
;
//=
/*enter*/
default:
break;
}
return
j;
}
int
number(void)
{
int
i=0,j=15,k=0,l,n,m;
int
a[13];
for(m=0;;m++)
{
a[m]=KeyDisplay(
KeyConf()
);
if(a[m]==15)
break;
}
for(n=0;a[n]!=15;n++)
{if(a[n]<10)
i=i*10+a[n];
else
break;
}
if(a[n]!=15)
j=a[n];
n++;
for(;a[n]!=15;n++)
{if(a[n]<10)
k=k*10+a[n];
else
break;
}
switch(j)
{case
10:
l
=
i+k;
break;
case
11:
l
=
i-k;
break;
case
13:
l
=
i*k;
break;
case
12:
l
=
i/k;
break;
}
return
l;
}
void
main()
{
int
x,i,j,k,l;
uchar
a[16];
DDRA
=
0xDF
;
PORTA
=
0xFF
;
DDRC
=
0xFF
;
PORTC
=
0xFF
;
//DDRB
=
0X00
;
//PORTB
=
0XFF
;
//DDRD
=
0X00
;
//PORTD
=
0XFF
;
//Delayms(
100
);
LcdInit()
;
//液晶屏初始化
SendIns(0x01)
;
//Display(0x80
,
16
,
"
************
")
;
SendIns(
0x90
);
//SendDat(
0x30
);
while(1)
{x=number();
//Delayms(1000);
for(i=0;x!=0;i++)
{
a[i]=x%10+48;
x=x/10;
}
l=i-1;
for(j=i-1;j>=0;j--)
SendDat(a[j]);
SendDat(0x20)
;
Delayms(1000);
SendIns(0x01);
}
}
温馨提示:内容为网友见解,仅供参考
第1个回答  推荐于2016-06-25
自己写的计算器,功能有限希望对你有帮助
//===============================================
//芯片: ATMEGAL16L
//时间: 2009.08.04
//晶振频率: 7.3728MHZ
//目的: 按键显示
//===============================================

#include <iom16v.h>
#include <macros.h>

#define uint unsigned int
#define uchar unsigned char

//键盘引脚的定义:
#define KEYSCLK (1 << PA4)
#define KEYDAT (1 << PA5)
#define KEYKBS (1 << PA6)

//液晶显示屏的引脚定义:
#define LCDSCL (1 << PA2)
#define LCDSTD (1 << PA1)
#define LCDCS (1 << PC6)

#define SET_BIT(x,y) ( x |= ( 1 << Y ) ) ;
#define CLR_BIT(x,y) ( x &= ~( 1 << y ) ) ;
#define GET_BIT(x,y) ( x & ( 1 << y ) )

//================================================
//延时子函数
//================================================

void Delayms(uint x)
{
uchar a ;
for(; x>0; x--)
{
for(a=1; a <= 198; a++);
}
}

//******************************************************
//LCD液晶屏显示模块
//******************************************************

void SendByte(uchar byte)
{
uchar i;
uchar com = 0x80;
for (i=0; i<8; i++)
{
PORTA &= ~LCDSCL;
NOP();
if ((byte & com) == 0x80)
{
PORTA |= LCDSTD;
NOP();
}
else
{
PORTA &= ~LCDSTD;
NOP();
}
PORTA |= LCDSCL;
NOP();
byte <<= 1;
}
}

void SendWord(uchar dat)
{
uchar h,l;
h = dat & 0xF0;
l = (dat << 4);
SendByte(h);
SendByte(l);
}

void SendIns(uchar ins)
{
SendByte(0xF8);
SendWord(ins);
}

void SendDat(uchar dat)
{
SendByte(0xFA);
SendWord(dat);
}

void Stop()
{
PORTA &= ~LCDSCL;
PORTA |= LCDSTD;
}

void Display(uchar pst,uchar h,uchar a[])
{
uchar i;
SendIns(pst);
for(i=0; i<h; i++)
{
SendDat(*(a+i));
}
}

void LcdInit()
{
DDRA |= 0x05;
DDRC |= 0x04;

PORTC &= ~LCDCS;
PORTC |= LCDCS;
NOP();
SendIns(0x01);
SendIns(0x02);
SendIns(0x0F);
}

//******************************************************************
//keyboard-键盘输入模块
//******************************************************************

uchar GetKey()
{
uchar i , key = 16 ;

DDRA |= 0x50 ;

PORTA &= ~KEYSCLK ;
PORTA |= KEYKBS ;
PORTA &= ~KEYKBS ;
NOP() ;
PORTA |= KEYKBS ;

for (i=0; i<16; i++)
{
if ((PINA & 0x20) == 0x00)
{
key = i;
break;
}
PORTA &= ~KEYSCLK ;
PORTA |= KEYSCLK ;
}

return key;
}

uchar KeyConf()
{
uchar pre;
while(1)
{
while(GetKey() == 16);
pre = GetKey();
Delayms(10);
if(GetKey() == pre)
{
break;
}
}
while(GetKey() != 16);
Delayms(20);
while(GetKey() != 16);
return pre;
}

uchar KeyDisplay(uchar mn)
{
uchar j;
j=mn;
switch(mn)
{
case 0: { SendDat( 0x30 ); Stop(); } break ;
case 1: { SendDat( 0x31 ); Stop(); } break ;
case 2: { SendDat( 0x32 ); Stop(); } break ;
case 3: { SendDat( 0x33 ); Stop(); } break ;
case 4: { SendDat( 0x34 ); Stop(); } break ;
case 5: { SendDat( 0x35 ); Stop(); } break ;
case 6: { SendDat( 0x36 ); Stop(); } break ;
case 7: { SendDat( 0x37 ); Stop(); } break ;
case 8: { SendDat( 0x38 ); Stop(); } break ;
case 9: { SendDat( 0x39 ); Stop(); } break ;
case 10: { SendDat( 0x2B ); Stop(); } break ; /*+*/
case 11: { SendDat( 0x2D ); Stop(); } break ; /*-*/
case 13: { SendDat( 0x2A ); Stop(); } break ;//*
case 12: { SendDat( 0x2f ); Stop(); } break ; ///
case 14: { LcdInit(); SendIns(0x01); Stop(); } break ; /*clear*/
case 15: { SendDat( 0x3D ); Stop(); } break ; //= /*enter*/
default: break;
}
return j;
}
int number(void)
{ int i=0,j=15,k=0,l,n,m;
int a[13];
for(m=0;;m++)
{

a[m]=KeyDisplay( KeyConf() );
if(a[m]==15)
break;
}
for(n=0;a[n]!=15;n++)
{if(a[n]<10)
i=i*10+a[n];
else break;
}
if(a[n]!=15)
j=a[n];
n++;
for(;a[n]!=15;n++)
{if(a[n]<10)
k=k*10+a[n];
else break;
}
switch(j)
{case 10: l = i+k; break;
case 11: l = i-k; break;
case 13: l = i*k; break;
case 12: l = i/k; break;
}
return l;
}
void main()
{ int x,i,j,k,l;
uchar a[16];
DDRA = 0xDF ;
PORTA = 0xFF ;
DDRC = 0xFF ;
PORTC = 0xFF ;
//DDRB = 0X00 ;
//PORTB = 0XFF ;
//DDRD = 0X00 ;
//PORTD = 0XFF ;
//Delayms( 100 );
LcdInit() ; //液晶屏初始化
SendIns(0x01) ;
//Display(0x80 , 16 , " ************ ") ;
SendIns( 0x90 );
//SendDat( 0x30 );
while(1)
{x=number();
//Delayms(1000);
for(i=0;x!=0;i++)
{ a[i]=x%10+48;
x=x/10;
}
l=i-1;
for(j=i-1;j>=0;j--)
SendDat(a[j]);
SendDat(0x20) ;
Delayms(1000);
SendIns(0x01);
}
}本回答被提问者采纳

Warning: Invalid argument supplied for foreach() in /www/wwwroot/aolonic.com/skin/templets/default/contents.html on line 45
相似回答