想请教一下关于12864的问题,希望能得到您的帮助!
初学51单片机,想结合12864和矩阵键盘来实现一个简单的显示。
结果,遇到了问题,自认为查了不少资料,依然没有找到解决途径。实在无法,前来求助,希望高人赐教。
问题可能比较简单,还请高人花费一些时间指点一下迷津。
在下感激不尽。
问题如下:
本人打算通过按一个键实现两个不同的显示界面。按第一次,显示界面正常。再按第二次的时候,本应该第二次显示的内容一闪而过,紧接着,依然显示的是第一次的界面。多次实验依然如此。不解。
代码如下:
首先,做一下说明,因为代码不完善,也没有那么高效,优美。毕竟小白,请多包涵。谢谢!
#include<reg52.h>
#include <stdlib.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_data P0
sbit col1=P1^7; //列端口定义
sbit col2=P1^6;
sbit col3=P2^0;
sbit col4=P2^1;
sbit LCD_EN=P3^4;
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
sbit LCD_PSB=P3^7;
uchar code dis0[]={"****智能控制****"};
uchar code dis1[]={"当前功能显示区"};
uchar code dis2[]={"当前水温: "};
uchar code dis3[]={"当前水位比: "};
uchar code dis4[]={"按S17 开始上水"};
uchar code dis5[]={"目标水位比: "};
uchar code dis6[]={"按S5 停止上水 "};
uchar code dis7[]={"上水中... "};
uchar code dis8[]={"按S18 开始加热"};
uchar code dis9[]={"目标水温"};
uchar code dis10[]={"按S6 停止加热"};
uchar code dis11[]={"加热中... "};
/*uchar code dis12[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00};//清行*/
void delay1ms(uint);
void dekay(uchar);
void keyscan();
void write_cmd(uchar cmd);
void write_dat(uchar dat);
void lcd_pos(uchar X,uchar Y);
void lcd_init();
uchar num,i,temp;
uint counter,a,counter1,b;
void main()//固定界面显示
{
delay1ms(10);
lcd_init();
lcd_pos(0,0);//临大物联
i=0;
while(dis0[i]!='\0')
{
write_dat(dis0[i]);
i++;
}
lcd_pos(1,0);//当前水温
i=0;
while(dis2[i]!='\0')
{
write_dat(dis2[i]);
i++;
}
lcd_pos(2,0);//当前水位比
i=0;
while(dis3[i]!='\0')
{
write_dat(dis3[i]);
i++;
}
lcd_pos(3,0);//当前功能显示区
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
delay1ms(10);
while(1)
{
P1=0xff;
P2=0xff;
P3=0xff;
keyscan();
}
}
void delay1ms(uint x)//延时
{
uint i,j;
for(j=0;j<x;j++)
for(i=0;i<110;i++);
}
void delay(uchar i)//延时
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void keyscan()
{
col1=0;col2=1;col3=1;col4=1;//上水按键区
temp=P2&0x3f;
if(col1==0)
{
delay(80);
if(temp!=0x3f)
{
counter++;
//a=counter%2;
temp=P2&0x3c;
switch(temp)
{
case 0x1c: //进入上水功能界面
switch(counter)
{
case 1: //第一功能键,显示上水界面
delay(20);
lcd_pos(1,0);
i=0;
while(dis4[i]!='\0')
{
write_dat(dis4[i]);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis5[i]!='\0')
{
write_dat(dis5[i]);
i++;
}
delay(20);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 2: //第二功能键,开始上水
delay(20);
lcd_pos(1,0);
i=0;
while(dis6[i]!='\0')
{
write_dat(dis6[i]);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis3[i]!='\0')
{
write_dat(dis3[i]);
i++;
}
delay(20);
lcd_pos(3,0);
i=0;
while(dis7[i]!='\0')
{
write_dat(dis7[i]);
i++;
}
counter=0;
break;
}
case 0x2c: //增加水位比
//lcd_pos(1,0);
//write_dat(0x20);
delay(10);
lcd_pos(1,0);
i=0;
while(dis4[i]!='\0')
{
write_dat(dis4[i]);
i++;
}
//lcd_pos(2,0);
//write_dat(0x20);
delay(10);
lcd_pos(2,0);
i=0;
while(dis5[i]!='\0')
{
write_dat(dis5[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 0x34: //降低水位比
//lcd_pos(1,0);
//write_dat(0x20);
delay(10);
lcd_pos(1,0);
i=0;
while(dis4[i]!='\0')
{
write_dat(dis4[i]);
i++;
}
//lcd_pos(2,0);
//write_dat(0x20);
delay(10);
lcd_pos(2,0);
i=0;
while(dis5[i]!='\0')
{
write_dat(dis5[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 0x38: //退出键以及上水中止键
//lcd_pos(1,0);
//write_dat(0x20);
delay(10);
lcd_pos(1,0);
i=0;
while(dis2[i]!='\0')
{
write_dat(dis2[i]);
i++;
}
//lcd_pos(2,0);
//write_dat(0x20);
delay(10);
lcd_pos(2,0);
i=0;
while(dis3[i]!='\0')
{
write_dat(dis3[i]);
i++;
}
//lcd_pos(3,0);
//write_dat(0x20);
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
}
}
//while(!key1);
}
col1=1;col2=0;col3=1;col4=1; //加热按键区
temp=P2&0x3f;
if(col2==0)
{
delay(80);
if(temp!=0x3f)
{
counter1++;
b=counter1%2;
temp=P2&0x3c;
switch(temp)
{
case 0x1c: //进入加热功能界面
switch(b)
{
case 1: //第一功能键,显示加热界面
delay(10);
lcd_pos(1,0);
i=0;
while(dis9[i]!='\0')
{
write_dat(dis9[i]);
i++;
}
delay(10);
lcd_pos(2,0);
i=0;
while(dis8[i]!='\0')
{
write_dat(dis8[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 0: //第二功能键,开始加热
delay(10);
lcd_pos(1,0);
i=0;
while(dis2[i]!='\0')
{
write_dat(dis2[i]);
i++;
}
delay(10);
lcd_pos(2,0);
i=0;
while(dis10[i]!='\0')
{
write_dat(dis10[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis11[i]!='\0')
{
write_dat(dis11[i]);
i++;
}
break;
}
case 0x2c: //提高温度
delay(10);
lcd_pos(1,0);
i=0;
while(dis9[i]!='\0')
{
write_dat(dis9[i]);
i++;
}
delay(10);
lcd_pos(2,0);
i=0;
while(dis8[i]!='\0')
{
write_dat(dis8[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 0x34: //降低温度
delay(10);
lcd_pos(1,0);
i=0;
while(dis9[i]!='\0')
{
write_dat(dis9[i]);
i++;
}
delay(60);
lcd_pos(2,0);
i=0;
while(dis8[i]!='\0')
{
write_dat(dis8[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
case 0x38: //退出键以及加热中止键
delay(10);
lcd_pos(1,0);
i=0;
while(dis2[i]!='\0')
{
write_dat(dis2[i]);
i++;
}
delay(10);
lcd_pos(2,0);
i=0;
while(dis3[i]!='\0')
{
write_dat(dis3[i]);
i++;
}
delay(10);
lcd_pos(3,0);
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
break;
}
}
//while(!key1);
}
}
void write_cmd(uchar cmd)//写指令数据到LCD
{
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
P0=cmd;
delay1ms(5);
LCD_EN=1;
delay1ms(5);
LCD_EN=0;
}
void write_dat(uchar dat)//写显示数据到LCD
{
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
delay1ms(5);
LCD_EN=1;
delay1ms(5);
LCD_EN=0;
}
void lcd_pos(uchar X,uchar Y)//设定显示位置
{
uchar pos;
if(X==0)
{X=0x80;}
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0x88;}
else if(X==3)
{X=0x98;}
pos=X+Y;
write_cmd(pos);
}
void lcd_init()//LCD初始化
{
LCD_PSB=1;
write_cmd(0x30);
delay1ms(5);
write_cmd(0x0c);
delay1ms(5);
write_cmd(0x01);
delay1ms(5);
}
望高人可以抽出一点时间来指点一下愚生,在下感激不尽!
增加一个按键释放判断吧,如果只用一个按键进行界面切换的话,不做按键释放判断,在退出键盘扫描之后,又再次进入键盘扫描的时候,按键没有释放就会判断为又一次按键,然后进行界面切换
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
您好,请问在什么位置加呢,我不太会用这个按键释放。它这是怎么判断呢,用标志位法的话,一开始定义变量为0,按下去为1,松开为0?或是用等待按键释放,该怎么写啊,我都想了一下午了,还是没改出来。如果您方便的话,可以为我讲解一下吗,谢谢!
小白一枚路过
能否帮我看一下,亲
抱歉,给您发了这么多次,,,我网络不太好,刚才一直在等待,就多点了几次。然后,,不好意思。
你把按键扫描和按键的功能处理放在了一起,这样结构有点交叉,模块化不好,看起来有些累,以后最好分开,按键扫描是一个功能块,按键的功能处理是一个功能块。按键释放的判断最简单的就是判断没有按键按下,你这里应该可以加在void keyscan()的最后一个花括号之前,就是void keyscan(){ { { { 。} } } 1}数字1的位置,这时候按键功能都处理完了,判断按键有没有释放就可以了
好,谢谢您,小弟正在修改中,小弟还有一事相求,若能解答,感激不尽,请问,在12864中,想要单独的清除一行,写入空格将其覆盖即可,是吗,用一个数组,里面全是0x20,这样可以吗?小弟认为行得通,但是不知为何我在这样操作时,不会将其覆盖从而实现清行的功能,不能达到预期结果,小弟不知为何。望解答,小弟在此先谢过了!
12864是点阵屏,不是1602那种字符屏,虽然两种都是点阵方式显示,但1602是输入ASCII字符方式显示,12864是输入点阵信息显示,两者是不同的,一个5x8的英文字符,12864需要8个字节的数据来显示,清除显示是写入0x00,全显示是0xff,也就是12864的一个点显示是置1,清除是置0。这是普通不带字库的12864的操作方法,带字库的好像不一样,没用过,你需要看看你使用的屏的资料。
大家好!我们是专业做显示屏的,有这方面需求可联系!肖生:13570852659(微信同号)QQ:434316338