❶ 急求一个基于89C51单片机,8255A,用矩阵键盘输入数字,并在LCD1602上显示出来的C语言程序
#include<reg52.h>
#include<absacc.h>
#definePAXBYTE[0xF8FF]
#definePBXBYTE[0xF9FF]
#definePCXBYTE[0xFAFF]
#defineCOMXBYTE[0xFBFF]
#defineLCD1602_RS_SET() PB|=1<<0
#defineLCD1602_RS_RST() PB&=~(1<<0)
#defineLCD1602_RW_RST() PB&=~(1<<1)
#defineLCD1602_E_SET() PB|=1<<2
#defineLCD1602_E_RST() PB&=~(1<<2)
staticvoidDelay_ms(unsignedchartime)
{
unsignedchari;
while(time--)
{
for(i=0;i<100;i++);
}
}
staticvoidLCD1602_WriteByte(unsignedcharvalue,bitdataTypedef)
{
if(dataTypedef)
LCD1602_RS_SET();
else
LCD1602_RS_RST();
LCD1602_RW_RST();
PA=value;
LCD1602_E_SET();
Delay_ms(2);
LCD1602_E_RST();
}
staticvoidLCD1602_Init(void)
{
LCD1602_WriteByte(0x38,0);
Delay_ms(10);
LCD1602_WriteByte(0x01,0);
Delay_ms(10);
LCD1602_WriteByte(0x06,0);
Delay_ms(10);
LCD1602_WriteByte(0x0C,0);
Delay_ms(10);
}
staticvoidLCD1602_ShowString(unsignedcharaddress,unsignedchar*string)
{
LCD1602_WriteByte(address,0);
while(*string)
{
LCD1602_WriteByte(*string++,1);
}
}
=0xFF;
sbitKEY1=KeyStatus^4;
sbitKEY2=KeyStatus^5;
sbitKEY3=KeyStatus^6;
sbitKEY4=KeyStatus^7;
staticunsignedcharKeyValue=48;
staticvoidKEY_Testing(void)
{
PC=0xFE;
KeyStatus=PC&0xFF;
if(KeyStatus!=0xFF)
{
if(!KEY1)KeyValue='7';
if(!KEY2)KeyValue='8';
if(!KEY3)KeyValue='9';
if(!KEY4)KeyValue='/';
}
PC=0xFD;
KeyStatus=PC&0xFF;
if(KeyStatus!=0xFF)
{
if(!KEY1)KeyValue='4';
if(!KEY2)KeyValue='5';
if(!KEY3)KeyValue='6';
if(!KEY4)KeyValue='*';
}
PC=0xFB;
KeyStatus=PC&0xFF;
if(KeyStatus!=0xFF)
{
if(!KEY1)KeyValue='1';
if(!KEY2)KeyValue='2';
if(!KEY3)KeyValue='3';
if(!KEY4)KeyValue='-';
}
PC=0xF7;
KeyStatus=PC&0xFF;
if(KeyStatus!=0xFF)
{
if(!KEY1)KeyValue='?';
if(!KEY2)KeyValue='0';
if(!KEY3)KeyValue='=';
if(!KEY4)KeyValue='+';
}
}
voidmain()
{
COM=0x88;
PA=0xFF;
PB=0xFF;
PC=0xFF;
LCD1602_Init();
LCD1602_ShowString(0x82,"HelloWorld!");
LCD1602_ShowString(0xC0,"KeyPressed--->");
while(1)
{
KEY_Testing();
LCD1602_WriteByte(0xCF,0);
LCD1602_WriteByte(KeyValue,1);
}
}
❷ 求基于8051单片机用C语言编写的双矩阵键盘扫描程序(5个IO口控制25个按键)
怎么可能会出现优先级的问题,有键按下就是有键按下,没键按下就是没键按下。行列式键盘有两种处理方法,一种是行优先法,一种是列优先法。通常按键处理要软件去抖动,即判断有键按下时要延时20~30ms再检测,避开抖动。
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
/*延时1ms*/
void Delay(uint z)
{
uint i;
while(z--)
{
for(i=120;i>0;i--)
}
}
/*键扫描函数*/
uchar KeyScan()
{
uint i;
uchar h="0xef",b,c;
for(i=5,P1=h;i>0;i--)
{
if((P1&0x0f)!=0x0f)
{
Delay(30);
if((P1&0x0f)!=0x0f)
{
uchar key,p;
p=P1;
for(key=0;key<25;key++)
{
if(p==keytab[key])
{
do{
_nop_();
}while((P1&0x0f)==0x0f); //等待按键放开,很重要
//P1=0xff;
return(key);
}
}
}
}
}
}
❸ 51单片机 c语言编程 4*4矩阵键盘如何实现等待按键松开功能
uchar shaomiao()
{
uchar l,h;
P1=0xf0;//获取高四位抄信息。在此低四位接到行。行低电平
l=P1|0x0f;
P1=l;//只把被按下键所在列置低
h=P1|0xf0;
switch(h)
{
case 0xfe:h=0;break;//1111 1110
case 0xfd:h=1;break;
case 0xfb:h=2;break;
case 0xf7:h=3;break;
}
switch(l)
{
case 0xef:l=0;break;//1110 1111
case 0xdf:l=1;break;
case 0xbf:l=2;break;
case 0x7f:l=3;break;
}
P1=0xf0;
/******你说的关键问题解决如下******/
while(P1!=0xf0)
{
while(P1!=0xf0);//等待放开按键
delayms(50);//防止抖动
}
return(h*4+l);
}
❹ 单片机中独立键盘和矩阵键盘如何一起使用 请用C语言写个程序说明,谢谢。
这个很好处理呀,比如以下举例,独立+矩阵,实现独立按键相当于类似SHIFT作用的效果。
#include<reg51.h>
#define uchar unsigned char
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0到f
uchar keyval,num;
sbit skey=P1^0; //独立键P1.0
void delay(uchar a)
{
uchar i,j;
for(i=0;i<a;i++)
for(j=0;j<125;j++);
}
uchar kbscan(void) //矩阵键扫描程序
{
unsigned char sccode,recode;
P3=0x0f; //发0扫描,列线输入
if ((P3 & 0x0f) != 0x0f) //有键按下
{
delay(20); //延时去抖动
if ((P3&0x0f)!= 0x0f)
{
sccode = 0xef; //逐行扫描初值
while((sccode&0x01)!=0)
{
P3=sccode;
if((P3&0x0f)!=0x0f)
{
recode=(P3&0x0f)|0xf0;
while((P3&0x0f)!=0x0f);//等待键抬起
return((~sccode)+(~recode));
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return 0; //无键按下,返回0
}
void getkey(void)
{
unsigned char key;
key=kbscan();
if(key==0)
{
return;
}
switch(key)
{
case 0x11:keyval=7;break;
case 0x12:keyval=4;break;
case 0x14:keyval=1;break;
case 0x18:keyval=10;break;
case 0x21:keyval=8;break;
case 0x22:keyval=5;break;
case 0x24:keyval=2;break;
case 0x28:keyval=0;break;
case 0x41:keyval=9;break;
case 0x42:keyval=6;break;
case 0x44:keyval=3;break;
case 0x48:keyval=11;break;
case 0x81:keyval=12;break;
case 0x82:keyval=13;break;
case 0x84:keyval=14;break;
case 0x88:keyval=15;break;
default:keyval=0xff;break;
}
//以下处理独立按键
if(skey==0)
{
if(keyval!=0xff)keyval+=16; //如果独立键按下,键值加16
while(skey==0); //等待独立键释放
}
}
void t0isr() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
switch(num)
{
case 0:P2=0x01;break;
case 1:P2=0x02;break;
case 2:P2=0x04;break;
case 3:P2=0x08;break;
default:break;
}
if(keyval<16) P0=~tab[keyval]; //独立键未按正常显示
else P0=~(tab[keyval]|0x80); //独立键按下显示+DP
num++;
num&=0x03;
}
main()
{
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
getkey();
}
}
❺ 求 关于 用单片机和4*4矩阵键盘输入数字并在LCD1602上显示出来的C语言程序
这个你看看可以参考!
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
//这三个引脚参考资料
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令选择引脚
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为5US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/********************************************************************
* 名称 : bit Busy(void)
* 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
bit Busy(void)
{
bit busy_flag = 0;
RS = 0;
RW = 1;
E = 1;
delay();
busy_flag = (bit)(P0 & 0x80);
E = 0;
return busy_flag;
}
/********************************************************************
* 名称 : wcmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void wcmd(uchar del)
{
while(Busy());
RS = 0;
RW = 0;
E = 0;
delay();
P0 = del;
delay();
E = 1;
delay();
E = 0;
}
/********************************************************************
* 名称 : wdata(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void wdata(uchar del)
{
while(Busy());
RS = 1;
RW = 0;
E = 0;
delay();
P0 = del;
delay();
E = 1;
delay();
E = 0;
}
/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
wcmd(0x38);
wcmd(0x0c);
wcmd(0x06);
wcmd(0x01);
}
/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
wcmd(a);
wdata(sign);
}
/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a,b=0;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
while(1)
{
wcmd(a++);
b++;
if((*p == '\0')||(b==16)) break;
wdata(*p);
p++;
}
}
/********************************************************************
* 名称 : Keyscan()
* 功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。
* 输入 : 无
* 输出 : 按键值
***********************************************************************/
uchar Keyscan(void)
{
uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};
for(j=0; j<4; j++)
{
P1 = Buffer[j];
temp = 0x10;
for(i=0; i<4; i++)
{
if(!(P1 & temp))
{
return (i+j*4);
}
temp <<= 1;
}
}
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
uchar Key_Value; //读出的键值
L1602_init();
L1602_string(1,1," 4*4 KeyBoard ");
L1602_string(2,1,"You Press The ");
while(1)
{
P1 = 0xf0;
if(P1 != 0xf0)
{
Delay_1ms(20); //按键消抖
if(P1 != 0xf0)
{
Delay_1ms(20); //按键消抖
if(P1 != 0xf0)
{
Key_Value = Keyscan();
}
}
}
L1602_char(2,15,Key_Value / 10 + 48);
L1602_char(2,16,Key_Value % 10 + 48);
}
}
❻ C51单片机4X4矩阵键盘检测程序问题
P3=0xfe; //P3=0b1111 1110,令P3.0=0,同时令高四位为高电平,作好读端口准备(51IO特点)
temp=P3; //读回P3口的状态
temp=temp&0xf0; //temp&1111 0000,0与任何数结果为0,把temp变量的低四位屏蔽了,高四位因为任何数与1等于它本身,所以把高四位对应的端口状态读进来。
while(temp!=0xf0) //上步处理后,高四为不全为1,说明有按键按下(结合矩阵键盘的电路结构才能理解,这里不方便上图)
{
delay(5);
temp=P3;
temp=temp&0xf0;//这三句跟上面重复,功能是软件消抖
while(temp!=0xf0) //延时一段时间后判断还有按键按下,说明是真有按键按下,进入按键扫描与键值的判断,否则可能是意外抖动引起的,就不进行按键扫描。
{
temp=P3;
switch(temp).....
我想注释完应该能读懂,关键是要理解矩阵键盘的扫描原理。