#include <reg51.h>
#include <intrins.h>
//端口定义
sbit LCDRS = P1^0; //寄存器选择 1:数据寄存器 0:指令寄存器
sbit LCDRW = P1^1; //读写 选择 1:读 0:写
sbit LCDEN = P1^2; //使能 1:可读写
sbit LCDBF = P0^7; //LCD忙标志 Busy Flag
sfr DBPORT = 0x80; //数据端口
0//常量定义
#define LCD_DATA 1
#define LCD_COMMAND 0
#define LCD_READ 1
#define LCD_WRITE 0
void lcd_wait()
//等待LCD空闲
{ LCDEN=0;
DBPORT=0xff; //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
LCDRS=LCD_COMMAND;
LCDRW=LCD_READ;
LCDEN=1; _nop_();
while(LCDBF)
{ LCDEN=0; _nop_();
LCDEN=1; _nop_();
}
LCDEN=0;
}
void lcd_command(unsigned char command)
//用参数传递写类型,消耗ROM更多,调用也不方便,不如写两个函数
//相同部分没有写成一个函数进行调用,因其本身占用ROM不多,而太多嵌套调用函数占用堆栈
//写入指令
{ lcd_wait();
LCDRS=LCD_COMMAND;
LCDRW=LCD_WRITE;
DBPORT=command; //注意写时序,先建立数据,再使能
LCDEN=1; _nop_();
LCDEN=0;
}
void lcd_putchar(unsigned char character)
//写入数据
{ lcd_wait();
LCDRS=LCD_DATA;
LCDRW=LCD_WRITE;
DBPORT=character;
LCDEN=1; _nop_();
LCDEN=0;
}
/*
void lcd_creat(unsigned char *char_code,unsigned char nofc)
//自定义字符
{ lcd_command(0x40);
while(nofc)
{ lcd_putchar(*char_code);
char_code++;
nofc--;
}
} */
void lcd_moveto(unsigned char x, unsigned char y)
//设定要读写的字符 行,列 坐标
{ if(x==0)
lcd_command(0x80|y);
if(x==1)
lcd_command(0xc0|y);
}
void lcd_print(unsigned char *str)
//显示字符串
{ while(*str!='\0')
{ lcd_putchar(*str);
str++;
}
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 100; i++);
}
}
void lcd_init()
//LCD模块电源若不符合内部自动启动电路要求,需使用指令启动
//仿真不需要,只要在程序中执行命令LCD_INIT,LCD_CLRS,并设置需要的显示模式,输入模式
{ unsigned char i;
LCDEN=0;
LCDRS=LCD_COMMAND;
LCDRW=LCD_WRITE;
DBPORT=0x30;
for(i=0;i<3;i++)
{ LCDEN=1; _nop_(); //LCD模块热启动,不检查忙信号
LCDEN=0;
delayms(5);
}
lcd_command(0x38);
lcd_command(0x01);
lcd_command(0x0f);
lcd_command(0x06);
lcd_command(0x80+0x01);
}
void main()
{
lcd_init();
lcd_wait();
lcd_putchar('a');
}
电路图:
电路图.rar
(2008-07-17 16:43:29, Size: 19.5 KB, Downloads: 10)

最新回复
djh2007 (2008-7-17 16:44:50)
budhy (2008-7-17 17:00:46)
QUOTE:
问题好像处于以上程序。试一试用延时来等待 LCD 的反映。djh2007 (2008-7-18 13:08:28)
budhy (2008-7-18 14:36:10)
QUOTE:
楼主是在反应我在楼3#的意见吗?用延时代替等待LCD空闲,应该对电平没有影响的。djh2007 (2008-7-18 15:41:33)
绝处逢生 (2008-7-18 19:37:34)
#include <intrins.h>
//端口定义
sbit LCDRS = P1^0; //寄存器选择 1:数据寄存器 0:指令寄存器
sbit LCDRW = P1^1; //读写 选择 1:读 0:写
sbit LCDEN = P1^2; //使能 1:可读写
sbit LCDBF = P0^7; //LCD忙标志 Busy Flag
sfr DBPORT = 0x80; //数据端口0
//常量定义
#define LCD_DATA 1
#define LCD_COMMAND 0
#define LCD_READ 1
#define LCD_WRITE 0
void lcd_wait()
//等待LCD空闲
{ LCDEN=0;
DBPORT=0xff; //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
LCDRS=LCD_COMMAND;
LCDRW=LCD_READ;
LCDEN=1; _nop_();
while(LCDBF)
{ LCDEN=0; _nop_();
LCDEN=1; _nop_();
}
LCDEN=0;
}
void lcd_command(unsigned char command)
//用参数传递写类型,消耗ROM更多,调用也不方便,不如写两个函数
//相同部分没有写成一个函数进行调用,因其本身占用ROM不多,而太多嵌套调用函数占用堆栈
//写入指令
{ lcd_wait();
LCDRS=LCD_COMMAND;
LCDRW=LCD_WRITE;
DBPORT=command; //注意写时序,先建立数据,再使能
LCDEN=1; _nop_();
LCDEN=0;
}
void lcd_putchar(unsigned char character)
//写入数据
{ lcd_wait();
LCDRS=LCD_DATA;
LCDRW=LCD_WRITE;
DBPORT=character;
LCDEN=1; _nop_();
LCDEN=0;
}
/*
void lcd_creat(unsigned char *char_code,unsigned char nofc)
//自定义字符
{ lcd_command(0x40);
while(nofc)
{ lcd_putchar(*char_code);
char_code++;
nofc--;
}
} */
void lcd_moveto(unsigned char x, unsigned char y)
//设定要读写的字符 行,列 坐标
{ if(x==0)
lcd_command(0x80|y);
if(x==1)
lcd_command(0xc0|y);
}
void lcd_print(unsigned char *str)
//显示字符串
{ while(*str!='\0')
{ lcd_putchar(*str);
str++;
}
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 100; i++);
}
}
void lcd_init()
//LCD模块电源若不符合内部自动启动电路要求,需使用指令启动
//仿真不需要,只要在程序中执行命令LCD_INIT,LCD_CLRS,并设置需要的显示模式,输入模式
{ unsigned char i;
LCDEN=0;
LCDRS=LCD_COMMAND;
LCDRW=LCD_WRITE;
DBPORT=0x30;
for(i=0;i<3;i++)
{ LCDEN=1; _nop_(); //LCD模块热启动,不检查忙信号
LCDEN=0;
delayms(5);
}
lcd_command(0x38); //8bit数据传送,2行显示,5*7字型,检测忙信号
lcd_command(0x08); //关闭显示,检测忙信号
lcd_command(0x01); //清屏,检测忙信号
lcd_command(0x06); //显示光标右移设置,检测忙信号
lcd_command(0x0c); //显示屏打开,光标不显示,不闪烁,检测忙信号
}
void main()
{
lcd_init();
lcd_wait();
while(1)
{
lcd_command(0x80);
lcd_putchar('a');
}
}
budhy (2008-7-18 19:56:21)
绝处逢生 (2008-7-18 20:43:38)
搞1602显示已经好几天了,也遇到不少难点,其中汉字显示部分我还没攻下,另外,通过4*4键盘向1602输入一串英文字符也没完全实现。希望在1602的学习过程中能与楼主和budhy多交流。
djh2007 (2008-7-18 21:54:45)
我也发上来给大家看下
#include <reg51.h>
#include <intrins.h>
//端口定义
sbit LCDRS=P2^1; //寄存器选择 1:数据寄存器 0:指令寄存器
sbit LCDRW=P2^0; //读写 选择 1:读 0:写
sbit LCDEN=P2^2; //使能 1:可读写
sbit LCDBF=P1^7; //LCD忙标志 Busy Flag
sfr DBPORT=0x90; //数据端口
unsigned char code ch[]="djh";
void delayms(unsigned char);
void lcd_wait()
//等待LCD空闲
{
while(1)
{
LCDEN=0;
LCDRS=0;
LCDRW=1;
DBPORT=0xff;
LCDEN=1;
if(!LCDBF)break;
}
LCDEN=0;
}
void lcd_command(unsigned char command)
//用参数传递写类型,消耗ROM更多,调用也不方便,不如写两个函数
//相同部分没有写成一个函数进行调用,因其本身占用ROM不多,而太多嵌套调用函数占用堆栈
//写入指令
{ lcd_wait();
LCDRS=0;
LCDRW=0;
DBPORT=command; //注意写时序,先建立数据,再使能
LCDEN=1;
LCDEN=0;
}
void lcd_putchar(unsigned char character)
//写入数据
{
lcd_wait();
LCDRS=1;
LCDRW=0;
DBPORT=character;
LCDEN=1;
LCDEN=0;
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char x,y;
for(x=ms;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_init()
//LCD模块电源若不符合内部自动启动电路要求,需使用指令启动
//仿真不需要,只要在程序中执行命令LCD_INIT,LCD_CLRS,并设置需要的显示模式,输入模式
{ unsigned char i;
LCDEN=0;
LCDRS=0;
LCDRW=0;
DBPORT=0x38;
for(i=0;i<3;i++)
{ LCDEN=1; _nop_(); //LCD模块热启动,不检查忙信号
LCDEN=0;
delayms(10);
}
lcd_command(0x06);
lcd_command(0x0f);
lcd_command(0x38); //设置显示两行
lcd_command(0x01);
}
void main()
{
unsigned char num;
lcd_init();
lcd_command(0x80+0x01);
lcd_putchar('a');
lcd_command(0x80+0x40);
for(num=0;num<3;num++)
{
lcd_putchar(ch[num]);
delayms(5);
}
while(1);
}
我改得半死 所有有可能的我都改 包够换了电路
哎 不知道楼上的已经改好了,要不我就不用那么辛苦了
djh2007 (2008-7-18 21:56:48)
liaoguobao00 (2008-8-03 09:52:53)