标题:
LCD1602如何连续输入?附单片机程序
[打印本页]
作者:
xinshoulei
时间:
2020-1-22 15:39
标题:
LCD1602如何连续输入?附单片机程序
#include"reg52.h"
#define led P0 //定义led数码管连在P0口
#define key P3 //定义矩阵键盘连在P3口
#define LCD1602_D P0 //lcd I/O口连在P0口
#define uchar unsigned char
#define uint unsigned int
sbit E=P3^4; //定义lcd端口
sbit RW=P3^6;
sbit RS=P3^5;
void LcdWriteCom(uchar com); //函数声明
void WriteDat(uchar dat);
void Lcdxs(uchar x,uchar y,uchar dat);
uchar code lcd[]={0x2f,0x2a,0x2d,0x2b,0x3d,0x39,0x36,0x33,0x30,0x38,0x35,0x32,0x2e,0x37,0x34,0x31}; // 123+456-789*#0/=
// / * - + = 9 6 3 0 8 5 2 . 7 4 1
uchar a,c;
void delay(uint i) //延时函数
{
while(i--)
{;}
}
void keydownup() //矩阵按键扫描程序
{
char b=0;
key=0x0f;
if(key!=0x0f)
{
delay(1000); //延时消抖
if(key!=0x0f)
{
key=0x0f; //检测列 使高四位为低,低四位为高,判断低四位是否有低电平出现(有则key!=0x0f)
switch(key)
{
case 0x07:a=0;break;
case 0x0b:a=1;break;
case 0x0d:a=2;break;
case 0x0e:a=3;break;
}
key=0xf0; //检测行 使高四位为高,低四位为低,判断高四位是否有低电平出现(有则key!=0xf0)
switch(key)
{
case 0x70:a=a; break;
case 0xb0:a=a+4; break;
case 0xd0:a=a+8; break;
case 0xe0:a=a+12;break;
}
while((b<50)&&key!=0xf0) //判断按键按下后是否松开 超时或者按键松开则跳出循环
{
delay(1000);
b++;
}
}
}
}
void LcdWriteCom(uchar com) //写指令函数
{
E=0; //允许使能
RS=0; //指令
RW=0; //写入
LCD1602_D=com;
delay(1);
E=1; //写入时序
delay(1);
E=0;
}
void WriteDat(uchar dat) //写数据函数
{
E=0; //允许使能
RS=1; //数据
RW=0; //写入
LCD1602_D=dat;
delay(1);
E=1; //写入时序
delay(1);
E=0;
}
void Lcdxs(uchar x,uchar y,uchar dat) //显示一个字符的函数
{
uchar t;
if(y==1)
t=0x80+x;
else
t=0xc0+x;
LcdWriteCom(t);
WriteDat(dat);
}
void main()
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不开光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
delay(100);
while(1)
{
keydownup(); //矩阵按键扫描程序
Lcdxs(0,1,lcd[a]); //显示按键按下后数组中对应的值
}
}
怎么改,让他连续输入
作者:
杨雪飞
时间:
2020-1-23 14:55
lcdxs(0,1,lcd[a])
设置一个变量K,按键每按一下K+1
lcdxs(0,k,lcd[a])
作者:
angmall
时间:
2020-1-23 19:21
我给你来个程序参考
#include<reg52.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define lcddata P1
sbit LCDRS = P3^3;
sbit LCDRW = P3^4;
sbit LCDEN = P3^5;
sbit beep = P3^7;
sbit zhongduan = P3^2;
sbit kaifang = P0^6;
sbit cifang = P0^7;
sbit qingling=P0^5;
sbit kaiguan=P0^4;
uchar keyscan1(void);
void keyscan(void);
void count(void);
void anjianshibie();
void write_com(uchar i);
void write_data(uchar i);
void write_string(uchar *s);
void write_num(long n);
void lcdwrite_float(float n);
void lcd_init(void);
void xinxing();
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar code table[]=
{
1,2,3,0x2b-0x30, // 1, 2, 3, +
4,5,6,0x2d-0x30, // 4, 5, 6, -
7,8,9,0x2a-0x30, // 7, 8, 9, x
0,0x3d-0x30,0x2e-0x30,0x2f-0x30 // 0, =, 清零, /
};
uchar code table1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x01,0x18,0x1c,0x1e,0x1e,0x1e,0x1e,0x1e,
0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00
};
uchar num='N',flag=0,flag1=0,flag2=0,fuhao=0,temp=0,shu[18]={0},beepflag=1,y=0,j;
float a=0,b=0,c=0,d,point=0;
void main()
{
xinxing();
delayms(1000);
write_com(0x01);
write_com(0x80);
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=0; //电平触发(边沿触发IT0=1;)
while(1)
{
keyscan();
anjianshibie();
}
}
/*按键检测*/
uchar keyscan1(void) //键盘扫描函数,使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值中间变量
P2=0x0f; //行线输出全为0
cord_h=P2&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delayms(10); //去抖
if((P2&0x0f)!=0x0f)
{
if(beepflag==1) //若开声音则每一次按键均鸣叫
{
beep=0;
delayms(50);
beep=1;
}
cord_h=P2&0x0f; //读入列线值
P2=cord_h|0xf0; //输出当前列线值
cord_l=P2&0xf0; //读入行线值
while((P2&0xf0)!=0xf0); //等待松开并输出
return(cord_h+cord_l); //键盘最后组合码值
}
}
return(0xff); //返回该值
}
void keyscan()
{
switch(keyscan1())
{
case 0xEE:num=0;break;
case 0xDE:num=1;break;
case 0xBE:num=2;break;
case 0x7E:num=3;break;
case 0xED:num=4;break;
case 0xDD:num=5;break;
case 0xBD:num=6;break;
case 0x7D:num=7;break;
case 0xEB:num=8;break;
case 0xDB:num=9;break;
case 0xBB:num=10;break;
case 0x7B:num=11;break;
case 0xE7:num=12;break;
case 0xD7:num=13;break;
case 0xB7:num=14;break;
case 0x77:num=15;break;
}
}
/*按键识别函数*/
void anjianshibie()
{
if(num==0||num==1||num==2||num==4||num==5||num==6||num==8||num==9||num==10||num==12||num==14)
{
if(temp>=2)
{
write_com(0x01);
write_string("math error");
}
else
{
if(flag==0)
{
if(num==14)
{flag2=1;}
if(num!=14&&flag2==0)
{a=a*10+table[num];}
if(num!=14&&flag2==1)
{
y++;
point=table[num]*pow(0.1,y);
a=a+point;
}
write_data(0x30+table[num]);
delayms(5);
}
if(flag==1)
{
if(num==14)
{flag2=1;}
if(num!=14&&flag2==0)
{b=b*10+table[num];}
if(num!=14&&flag2==1)
{
y++;
point=table[num]*pow(0.1,y);
b=b+point;
}
write_data(0x30+table[num]);
delayms(5);
}
}
num='N'; //一定要加这个,否则会出现满屏的按键对应的数
}
if(num==3||num==7||num==11||num==15)
{
flag=1;
flag2=0;
y=0;
temp++;//判断运算符号按下的个数
switch(num)
{
case 3:fuhao=1;break; //加
case 7:fuhao=2;break; // 减
case 11:fuhao=3;break; // 乘
case 15:fuhao=4;break; // 除
}
write_data(0x30+table[num]);
num='N';
}
if(num==13) //13等号,14清零
{
temp=0; //temp清零
flag=0;
flag2=0;
if(flag1==0)
{write_com(0x80+0x40);}
write_data(0x30+table[num]);
delayms(5);
count(); //计算c的值
/* if(c==0)
{
write_com(0x80+0x41);//如果c为零,直接在等号后边显示出来
write_data(0x30);
}
if(c>0)
{
d=c;
}
if(c<0)
{
d=0-c;
write_data(0x2d); //把小数点显示出来
} */
lcdwrite_float(c);
flag1++;
num='N';
}
if(kaifang==0)
{
delayms(10);
if(kaifang==0) //去抖
{
if(beepflag==1) //若开声音则每一次按键均鸣叫
{
beep=0;
delayms(50);
beep=1;
}
temp++;
flag=1;
flag2=0;
y=0;
write_data(0xe8);
fuhao=5;
}
while(!kaifang); //按键释放
}
if(cifang==0)
{
delayms(10); // 去抖
if(cifang==0)
{
if(beepflag==1) //若开声音则每一次按键均鸣叫
{
beep=0;
delayms(50);
beep=1;
}
temp++;
flag=1;
flag2=0;
y=0;
write_data(0x5e);
fuhao=6;
}
while(!cifang); // 按键释放
}
if(qingling==0)
{
delayms(10); // 去抖
if(qingling==0)
{
if(beepflag==1) //若开声音则每一次按键均鸣叫
{
beep=0;
delayms(50);
beep=1;
}
write_com(0x01);
a=0;
b=0;
c=0;
point=0;
flag=0;
flag1=0;
flag2=0;
temp=0;
fuhao=0;
j=0;
num='N';
}
while(!qingling); // 按键释放
}
/*if(kaiguan==0)
{
delayms(10); // 去抖
if(kaiguan==0)
{
beepflag=~beepflag;
}
while(!cifang); // 按键释放
}*/
}
/*计算函数*/
void count()
{
if(fuhao==1) //如果符号键是+,执行加法运算
{
c=a+b;
a=c;
b=0;
}
if(fuhao==2) // 如果符号键是-,执行减法运算
{
c=a-b;
a=c;
b=0;
}
if(fuhao==3) //如果符号键是*执行乘法运算
{
c=a*b;
a=c;
b=0;
}
if(fuhao==4) //如果符号键是/ 执行除法运算
{
if(b==0)
{
write_com(0x01);
write_string("math error"); //被除数不能为零,否则输出math error
}
else
{
c=a/b;
a=c;
b=0;
} //这么设置就可连续运算
}
if(fuhao==5)
{
if(b<0)
{
write_com(0x01);
write_string("math error");
}
else
{
c=sqrt(b);
}
}
if(fuhao==6)
{
float x=a;
c=a;
for(;b>1;b--)
{
c=x*a;
x=c;
}
}
}
/*写命令*/
void write_com(uchar i)
{
LCDEN=0;
LCDRS=0;
lcddata=i;
delayms(5);
LCDEN=1;
delayms(5);
LCDEN=0;
}
/*******写数据***********/
void write_data(uchar i)
{
LCDEN=0;
LCDRS=1;
lcddata=i;
delayms(5);
LCDEN=1;
delayms(5);
LCDEN=0;
}
/*写字符串*/
void write_string(uchar *s)
{
while(*s)
{
write_data(*s);
s++;
delayms(5);
}
}
/*******初始化液晶*******/
void lcd_init(void)
{
LCDEN=0;
LCDRW=0;
//write_com(0x01); //显示清屏
// write_com(0x01); //显示清屏
write_com(0x38);//设置成1602显示
delayms(5);
write_com(0x38);//设置成1602显示
delayms(5);
write_com(0x38);//设置成1602显示
delayms(5);
// write_com(0x0f); //开显示 0x0e-->显示开,光标开
write_com(0x0c);//显示开
write_com(0x06); //设置光标移动方向增量方式,并指定显示不移动
write_com(0x01);
}
/*开机界面*/
void xinxing()
{
uchar mingzi[]="by 51Hei" ;
uchar num1; //循环变量
lcd_init(); //初始化
write_com(0x40);
for(num1=0;num1<64;num1++)
{
write_data(table1[num1]);
}
write_com(0x85);
for(num1=0;num1<4;num1++)
{
write_data(num1);
}
write_com(0xc5);
for(num1=4;num1<8;num1++)
{
write_data(num1);
}
write_com(0x80+0x4a);
for(num1=0;num1<6;num1++)
{
write_data(mingzi[num1]);
}
}
void waibu(void) interrupt 0 //using 1
{
if(zhongduan==0) //如果检测到低电平
{
delayms(10); //延时,去抖动,一般为10ms
if(zhongduan==0) //如果去抖动之后还是低电平,说明按下了
{
if(beepflag==1) //若开声音则每一次按键均鸣叫
{
beep=0;
delayms(50);
beep=1;
}
beepflag=~beepflag; //进入中断程序执行程序
}
while(!zhongduan); //等待释放,如果没有释放,则一直等待
}
}
/******显示7位小数*********/
void lcdwrite_float(float n)
{
uchar i=0;
long nxtemp;
if(n==0)
{
write_data('0');
return;
}
if(n<0)
{
write_data('-');
n=0-n;
}
nxtemp=n;
n=n;//+0.000002;
write_num(nxtemp);
if((n-nxtemp)>0)
{
write_data('.');
nxtemp=(n-nxtemp)*10000000;
// n=n-1;
// nxtemp=n;
// if(nxtemp%10!=0)
write_data(nxtemp/1000000+0x30);//显示第7位小数
// if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0)||(nxtemp%1000000/100000!=0))
write_data(nxtemp%1000000/100000+0x30);//显示第6位小数
// if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0))
write_data(nxtemp%1000000%100000/10000+0x30);//显示第5位小数
// if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0))
write_data(nxtemp%1000000%100000%10000/1000+0x30);//显示第4位小数
// if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0))
write_data(nxtemp%1000000%100000%10000%1000/100+0x30);//显示第3位小数
// if((nxtemp%1000000%100000%10000%1000%100/10!=0))
write_data(nxtemp%1000000%100000%10000%1000%100/10+0x30);//显示第2位小数
write_data(nxtemp%10+0x30);//显示第1位小数 */
}
else
return;
}
/*显示多位数*/
void write_num(long n)
{
// uchar length=0,j=0,a[8]={0,0,0,0,0,0,0,0};
long nx;
/* if(n==0)
{
write_data('0');
return;
}
if(n<0)
{
write_data('-');
n=0-n;
} */
// nx=n;
// for(j=0;j<8;j++)
// {
// if(nx>=1)
// length++;
// nx/=10;
// }
nx=n;
if(nx==0)
{
write_data('0');
}
else
{
while(nx>0)
{
shu[j]=nx%10; //把n的每一位放进数组
nx=nx/10;
j++;
}
for(;j>0;j--)
{ //显示整数n的每一位
write_data(shu[j-1]+0x30);
delayms(5);
}
}
}
复制代码
作者:
xinshoulei
时间:
2020-1-23 20:24
杨雪飞 发表于 2020-1-23 14:55
lcdxs(0,1,lcd[a])
设置一个变量K,按键每按一下K+1
lcdxs(0,1,lcd[a])
if语句判读是否按下
按下k+1,没按下k不变
a=k+1;
lcdxs(0,k,lcd[a])
作者:
man1234567
时间:
2020-2-1 07:55
1602的三线接在了P3口,高低端都占了些,而P3又定义成矩阵键盘并且还以高低口有无信号做为标志,这样肯定不好玩。建议将1602的三线换到P1或P2试试。
作者:
剑魂箫韵
时间:
2020-2-17 20:39
angmall 发表于 2020-1-23 19:21
我给你来个程序参考
请问一下硬件是如何连接的,比如P0、P1口要连接什么
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1