所有人回答的都不对,其实是忘了将1602第5脚rw设置为0了,而郭天祥的板子是直接接地,所以不用设置,但是别的板子却不能照搬了。所以程序应改为
sbit lcdrw=P3^6;
void write_com(uchar com)
{
lcdrs=0;
lcdrw=0;//加这一条
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
lcdrw=0;//加这一条
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
其实,也无所谓的几 个显示界面。第二次显示时,将第一次的显示内容清屏了,再显示新的内容就行了吗,哪有那么复杂吗?
如果还是再次出现设置界面,就把显示第一个界面内容的程序写成一个显示子程序,显示第二个界面的程序也写成一个显示子程序。每个显示子程序前有一条清屏的指令。这样,需要显示哪个界面就调哪个显示子程序。
看你的程序感觉很费劲,呵呵,我发一个我的程序给你吧!
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
uchar count,s1num;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";
uchar code table1[]=" 00:00:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
dula=0;
wela=0;
lcden=0;
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/ if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
希望能帮助你,呵呵
你把跟lcd数据连接的一些外设都去掉 程序的话
#include<reg52h>
#include<intrinsh>
#define uchar unsigned char
#define uint unsigned int
//这三个引脚参考资料
sbit LCD1602_EN=P2^7; //1602使能引脚
sbit LCD1602_RW=P2^6; //1602读写引脚
sbit LCD1602_RS=P2^5; //1602数据/命令选择引脚
/
名称 : LCD1602_delay()
功能 : 延时,延时时间大概为5US。
输入 : 无
输出 : 无
/
void LCD1602_delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void LCD1602_Delay(uint i)
{
uint x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/
名称 : bit Busy(void)
功能 : 这个是一个读状态函数,读出函数是否处在忙状态
输入 : 输入的命令值
输出 : 无
/
bit Busy(void)
{
bit busy_flag = 0;
LCD1602_RS = 0;
LCD1602_RW = 1;
LCD1602_EN = 1;
LCD1602_delay();
busy_flag = (bit)(P0 & 0x80);
LCD1602_EN = 0;
return busy_flag;
}
/
名称 : LCD1602_wcmd(uchar del)
功能 : 1602命令函数
输入 : 输入的命令值
输出 : 无
/
void LCD1602_wcmd(uchar del)
{
while(Busy());
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_EN = 0;
LCD1602_delay();
P0 = del;
LCD1602_delay();
LCD1602_EN = 1;
LCD1602_delay();
LCD1602_EN = 0;
}
/
名称 : LCD1602_wdata(uchar del)
功能 : 1602写数据函数
输入 : 需要写入1602的数据
输出 : 无
/
void LCD1602_wdata(uchar del)
{
while(Busy());
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_EN = 0;
LCD1602_delay();
P0 = del;
LCD1602_delay();
LCD1602_EN = 1;
LCD1602_delay();
LCD1602_EN = 0;
}
/
名称 : L1602_init()
功能 : 1602初始化,请参考1602的资料
输入 : 无
输出 : 无
/
void LCD1602_init(void)
{
LCD1602_wcmd(0x38);//设置16X2显示
LCD1602_wcmd(0x08);//关显示
LCD1602_wcmd(0x0c);//开显示
LCD1602_wcmd(0x0e);//开显示显示光标
LCD1602_wcmd(0x0f);//开显示显示光标光标闪烁
LCD1602_wcmd(0x06);//写入指针加一
LCD1602_wcmd(0x04);//写入指针减一
// LCD1602_wcmd(0x07);//写入整屏左移
// LCD1602_wcmd(0x05);//写入整屏右移
LCD1602_wcmd(0x01);//清屏
//LCD1602_wcmd(0x80+0X10);
}
/
名称 : LCD1602_char(uchar hang,uchar lie,char sign)
功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
输入 : 行,列,需要输入1602的数据
输出 : 无
/
void LCD1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
LCD1602_wcmd(a);
LCD1602_wdata(sign);
}
/
名称 : LCD1602_string(uchar hang,uchar lie,uchar p)
功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
输入 : 行,列,需要输入1602的数据
输出 : 无
/
void LCD1602_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)
{
LCD1602_wcmd(a++);
if((p == '\0')||(b==16)) break;
b++;
LCD1602_wdata(p);
p++;
}
}
/
名称 : Main()
功能 : 主函数
输入 : 无
输出 : 无
/
void Main()
{
LCD1602_Delay(30);
LCD1602_init();
LCD1602_string(1,1," Welcome To ");
LCD1602_string(2,1," The MCU World ");
LCD1602_char(1,1,'');
LCD1602_char(1,16,'');
while(1);
}
试试这个 有用请给好评
#include "LCD1602H"
#include <reg52H>
sbit lcdrs=P2^5; //命令/数据
sbit lcdrw=P2^6; //读/写
sbit lcden=P2^7; //使能端
static void delay(uchar zz)
{
uchar a,b;
for(a=zz;a>0;a--)
for(b=35;b>0;b--);
}
void WriteData(uchar x) //写数据
{
lcden=0;
lcdrs=1;
lcdrw=0;
P0=x;
delay(10);
lcden=1 ;
delay(10);
lcden=0;
lcdrw=1;
}
void WriteCommand(uchar y) //写命令
{
lcden=0; // 写指令 输入:RS=0,RW=0,E=下降沿脉冲,DB0~DB7=指令码 输出:无
lcdrs=0; // 写数据 输入:RS=1,RW=0,E=下降沿脉冲,DB0~DB7=数据 输出:无
lcdrw=0; // 读数据 输入:RS=1,RW=1,E=1 输出:DB0~DB7=数据
P0=y; // 读状态 输入:RS=0,RW=1,E=1 输出:DB0~DB7=状态字
delay(10);
lcden=1 ;
delay(10);
lcden=0;
lcdrw=1;
}
void Init_LCD1602()
{
WriteCommand(0x01);//清屏
WriteCommand(0x38);//1602显示,57点阵设置
WriteCommand(0x38);
WriteCommand(0x0c); //开显示,不显示光标
}
void delay_1ms(uint x)//延时
{ uchar j; //加一变量 uchar i,j;
while((x--)!=0) //改为for(i=0;i<x;i++)
{ for(j=0;j<125;j++) ;
}
}
//检查LCD忙状态
bit lcd_busy() //其实大多数都delayms(5)代替的,尤其是仿真时不能用此函数
{
bit result;
rs=0;
rw=0;
e = 1;
delay_1ms(1);
result = (bit)(data&0x80); //不知data是不是已经#define了
e = 0;
return(result);
}
//写指令数据到LCD
void write1602_com(uchar com)
{while(lcd_busy());
rs = 0;
rw = 0;
e = 0;
delay_1ms(1);
data= com;
delay_1ms(1);
e = 1;
delay_1ms(1);
e = 0;
}
//写显示数据到LCD
void write1602_data(uchar dat)
{while(lcd_busy());
rs = 1;
rw = 0;
e = 0;
data = dat;
delay_1ms(1);
e = 1;
delay_1ms(1);
e = 0;
}
void start(void) //LCD初始化
{delay_1ms(15);
write1602_com(0x38);
delay_1ms(5);
write1602_com(0x38);
delay_1ms(5);
write1602_com(0x38);
delay_1ms(5);
write1602_com(0x0F);//显示开,关光标
delay_1ms(5);
write1602_com(0x06);//移动光标
delay_1ms(5);
write1602_com(0x01);//清除LCD的显示内容
delay_1ms(5);
}
/ 设定显示位置 /
/
void lcd_data(uchar dat) //1602两行地址不是连续的,第二行是0xC0开始的
{
write1602_com(dat|0x80); //数据指针=80+地址变量
}
/
void lcd_data(uchar dat)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xb0;
else
p=pos+0x80;
write1602_com(p);
write1602_data(c);
}
void main()
{
start();
delay_1ms(10);
write1602_com(0x01); //已经清屏,不知道这句的意义
delay_1ms(10);
delay_1ms(5);
lcd_data(0x00);
delay_1ms(5);
for(i=0;i<12;i++)
{
if(i==13){ //建议这句话加上大括号,放到后边,放在这影响不好
while(1);}
write1602_data(table2[i]);//应先写地址再写数据,而你这地址是不变的,最终导致数组数据在
//一个地址上陆续显示,不知道会是啥效果,并且希望你的数组不是const的。
//可以写个连续显示的函数,加指针的
delay_1ms(1);
}
}
我这1602的程序及仿真还有很多,可以向我联系的
以上就是关于我看郭天祥的十天学会51单片机里的程序,买了块TX的51开发板 编写1602液晶显示的程序全部的内容,包括:我看郭天祥的十天学会51单片机里的程序,买了块TX的51开发板 编写1602液晶显示的程序、1602 换屏显示,首先能够出现一个设置初值的界面,设置完成后,按一下按键出现主界面。两个显示界面、1602液晶显示屏不按程序显示等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)