xbwpc 发表于 2010-5-15 19:19:12

LCD1602 四线程序测试成功(每根线单独定义)

上图:
http://cache.amobbs.com/bbs_upload782111/files_29/ourdev_554536.JPG
(原文件名:未命名.JPG)

http://cache.amobbs.com/bbs_upload782111/files_29/ourdev_554537.JPG
(原文件名:未命名2.JPG)

http://cache.amobbs.com/bbs_upload782111/files_29/ourdev_554538.JPG
(原文件名:未命名3.JPG)
程序:
#include<AT89X52.h>

//lcd part
#define        LINE1                           0
#define        LINE2                           1
#define        LINE1_HEAD                            0x80
#define        LINE2_HEAD                            0xC0
#define        CLEARSCREEN                            LCD_en_com(0x01)
/*************************************/
//change this part at different board
sbit DB7=P2^6;
sbit DB6=P2^5;
sbit DB5=P2^4;
sbit DB4=P2^3;
sbit LCD1602_RS=P2^0;   //data command select1 data0 commandpin 4
sbit LCD1602_RW=P2^1;   //read write select   1 read   0 write   pin 5
sbit LCD1602_EN=P2^2;   //LCD enable signal             pin 6
/********************************************************************/
void delay(unsigned int n)      
{
    unsigned int i=0,j=0;
    for (i=n;i>0;i--)
   for (j=0;j<12;j++);
}
void LCD_en_com(unsigned char command)
{
        DB7=(command>>7)%2;
        DB6=(command>>6)%2;
        DB5=(command>>5)%2;
        DB4=(command>>4)%2;
        LCD1602_RS = 0;           //RS 0
        LCD1602_RW = 0;                //RW 0
        LCD1602_EN = 1;        //EN --\|/__        Write command
        delay(2);
        LCD1602_EN = 0;

        DB7=(command>>3)%2;
        DB6=(command>>2)%2;
        DB5=(command>>1)%2;
        DB4=(command>>0)%2;
        LCD1602_RS = 0;           //RS 0
        LCD1602_RW = 0;                //RW 0
        LCD1602_EN = 1;        //EN --\|/__        Write command
        delay(2);
        LCD1602_EN = 0;
}
void LCD_en_dat(unsigned char command)
{
    DB7=(command>>7)%2;
        DB6=(command>>6)%2;
        DB5=(command>>5)%2;
        DB4=(command>>4)%2;
        LCD1602_RS = 1;        //RS 1
        LCD1602_RW = 0;                //RW 0
        LCD1602_EN = 1;        //EN --\|/__        Write data
        delay(2);
        LCD1602_EN = 0;

        DB7=(command>>3)%2;
        DB6=(command>>2)%2;
        DB5=(command>>1)%2;
        DB4=(command>>0)%2;
        LCD1602_RS = 1;        //RS 1
        LCD1602_RW = 0;                //RW 0
        LCD1602_EN = 1;        //EN --\|/__        Write data
        delay(2);
        LCD1602_EN = 0;
}
void LCD_set_xy(unsigned char x,unsigned char y)
{
        unsigned char address;
        if(y == LINE1)       
                address = LINE1_HEAD + x;
        else                        
                address = LINE2_HEAD + x;
        delay(10);
        LCD_en_com(address);
}
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s)
{
        LCD_set_xy(x,y);
        while(*s)
        {
                LCD_en_dat(*s);   
                s++;
        }
}
void LCD_init(void)
{
delay(50);
LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)
delay(10);
LCD_en_com(0x32);//然后再改到4位线宽,这样初始化才稳定
delay(10);
LCD_en_com(0x28);//四线模式设置
delay(10);
LCD_en_com(0x0c);//显示开--对应开关显示控制指令
delay(10);
CLEARSCREEN;
delay(30);
}
/********************************************************************/

void main(void)
{
LCD_init();
   LCD_write_string(0,LINE1,"0123456789abcdef");
   LCD_write_string(3,LINE2,"Advanced");
while(1);                  
}

726bf 发表于 2010-5-15 19:32:27

改天试一试我的1602

wanglituan 发表于 2010-5-16 01:11:59

不错有时间试试

bh7ohz 发表于 2010-5-16 10:35:33

学习了,谢谢你。

ggyyll8683 发表于 2010-5-16 12:00:23

学习

boy364100 发表于 2010-5-16 12:56:40

这个强

hongyancl 发表于 2010-5-16 15:16:23

回复【1楼】726bf
-----------------------------------------------------------------------

ddddddd

gpzdc986 发表于 2010-5-16 15:21:40

mark

guhenggao 发表于 2010-5-17 14:09:30

mark

wandy2010 发表于 2010-5-19 11:27:55

DB7=(command>>7)%2;

这句是程序的精华,把显示数据的指定位上的数据(或0或1)取出来,送到数据线上。

LCD1602的这种用法非常好,尤其是用洞洞板做东西,MCU与LCD的引脚连线可以怎么方便怎么连,连好线后改程序定义。

wandy2010 发表于 2010-5-19 11:29:29

另外还有一种取数据位的方法,是左移,然后将进位寄存器的值送给数据线

yangyb 发表于 2010-5-19 12:07:15

mark

726bf 发表于 2010-5-19 13:08:08

期待高人说一下LCD1602的初始化问题,我把这个程序烧写在我的STC12C2052(贴片20脚)里面,用P1口的P0.7~P0.3接LCD屏,P1其余接RS E RW,可上电后,屏幕第一行只显示方块,第二行无显示。http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3383406&bbs_page_no=1&search_mode=3&search_text=shamork&bbs_id=9999搜索了一下,看到这个帖子,看完也是一头慕水。

wandy2010 发表于 2010-5-19 15:30:43

楼上说的情况,相当于没接单片机时的表现,你拿一块1602,接上电源,调好对比度,就会显示一行黑块,在第一行。

你可以把1602的RW线接地,然后分析一下其他地方控制有没有问题。

wandy2010 发表于 2010-5-19 15:37:19

这个程序里面的注释比较详细,参考一下:

/*********************************包含头文件********************************/
#include <reg51.h>
#include <intrins.h>

/*********************************端口定义**********************************/
sbit rs        = P2^0;       
sbit rw = P2^1;
sbit ep = P2^2;

/********************************显示数据表*********************************/
unsigned char code dis1[] = {"www.hificat.com"};
unsigned char code dis2[] = {"0571-85956028"};

/*****************************************************************************
函数功能:LCD延时子程序
入口参数:ms
出口参数:
*****************************************************************************/
void delay(unsigned char ms)
{                                                       
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i< 250; i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}

/*****************************************************************************
函数功能:测试LCD忙碌状态
入口参数:
出口参数:result
*****************************************************************************/
bit lcd_bz()
{                                                       
        bit result;
        rs = 0;
        rw = 1;
        ep = 1;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        result = (bit)(P0 & 0x80);
        ep = 0;
        return result;       
}

/*****************************************************************************
函数功能:写指令数据到LCD子程序
入口参数:cmd
出口参数:
*****************************************************************************/
void lcd_wcmd(unsigned char cmd)
{                                               
        while(lcd_bz());                        //判断LCD是否忙碌
        rs = 0;
        rw = 0;
        ep = 0;
        _nop_();
        _nop_();       
        P0 = cmd;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        ep = 1;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        ep = 0;               
}

/*****************************************************************************
函数功能:设定显示位置子程序
入口参数:pos
出口参数:
*****************************************************************************/
void lcd_pos(unsigned char pos)
{                                               
        lcd_wcmd(pos | 0x80);
}

/*****************************************************************************
函数功能:写入显示数据到LCD子程序
入口参数:dat
出口参数:
*****************************************************************************/
void lcd_wdat(unsigned char dat)       
{                                                       
        while(lcd_bz());                        //判断LCD是否忙碌
        rs = 1;
        rw = 0;
        ep = 0;
        P0 = dat;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        ep = 1;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        ep = 0;       
}

/*****************************************************************************
函数功能:LCD初始化子程序
入口参数:
出口参数:
*****************************************************************************/
void lcd_init()
{                                                       
        lcd_wcmd(0x38);                       
        delay(1);
        lcd_wcmd(0x0c);               
        delay(1);
        lcd_wcmd(0x06);               
        delay(1);
        lcd_wcmd(0x01);                       
        delay(1);
}

/*****************************************************************************
函数功能:主程序
入口参数:
出口参数:
*****************************************************************************/
void main(void)
{
        unsigned char i;
        lcd_init();                                        // 初始化LCD                       
        delay(10);
        lcd_pos(0x01);                                //设置显示位置
        i = 0;
        while(dis1 != '\0')
        {                                                       
                lcd_wdat(dis1);                //显示字符
                i++;
        }
        lcd_pos(0x42);                                // 设置显示位置
        i = 0;
        while(dis2 != '\0')
        {
                lcd_wdat(dis2);                // 显示字符
                i++;
        }
        while(1);                               
}

bg6agf 发表于 2010-5-19 16:54:02

复【10楼】wandy2010
db7=(command&gt;&gt;7)%2;
这句是程序的精华,把显示数据的指定位上的数据(或0或1)取出来,送到数据线上。
lcd1602的这种用法非常好,尤其是用洞洞板做东西,mcu与lcd的引脚连线可以怎么方便怎么连,连好线后改程序定义。
-----------------------------------------------------------------------



不好吧。。。这种写法不知道编译出来是什么效果

用&0x01比较好吧。

wanglituan 发表于 2010-5-19 18:10:22

希望大家能更多的讨论

726bf 发表于 2010-5-19 20:42:50

回复【14楼】wandy2010
楼上说的情况,相当于没接单片机时的表现,你拿一块1602,接上电源,调好对比度,就会显示一行黑块,在第一行。
你可以把1602的rw线接地,然后分析一下其他地方控制有没有问题。
-----------------------------------------------------------------------

多谢wandy2010的指导,刚试了,发现这屏特殊,直接上电源,什么都没显示,接个10K的电位器调也不管用。估计是坏了

wandy2010 发表于 2010-5-19 22:24:39

回复【16楼】bg6agf 无垠春雪
复【10楼】wandy2010
db7=(command&gt;&gt;7)%2;   
这句是程序的精华,把显示数据的指定位上的数据(或0或1)取出来,送到数据线上。
lcd1602的这种用法非常好,尤其是用洞洞板做东西,mcu与lcd的引脚连线可以怎么方便怎么连,连好线后改程序定义。
-----------------------------------------------------------------------
不好吧。。。这种写法不知道编译出来是什么效果
用&amp;0x01比较好吧。
-----------------------------------------------------------------------

愿闻其详,详细点说一下吧!

xbwpc 发表于 2010-5-20 19:51:48

用&仍需要移位,用>>一次性解决,并且可读性好

bluefeel 发表于 2010-5-20 20:58:46

液晶复位时序不好,不是标准的复位方式,出现豆腐块很正常,具体看看HD44780数据手册的上电复位时间间隔
void LCD_init(void)         //液晶初始化
{
        EN_L();
        RW_L();
        IO &= 0X0f;
        IO |= 0x30;
        LCD_en();
        delay_nms(10);
        IO &= 0X0f;
        IO |= 0x30;
        LCD_en();
        delay_nms(5);
        LCD_write_command(0x32);
        delay_nms(5);
        LCD_write_command(0x28);//4位显示
        delay_nms(5);
        LCD_write_command(0x0c);//显示开
        delay_nms(5);
        LCD_write_command(0x01);//清屏
        delay_nms(5);
        LCD_write_command(0x06);//输入方式设置
        delay_nms(5);
}
http://cache.amobbs.com/bbs_upload782111/files_29/ourdev_555547.jpg
(原文件名:QQ截图未命名.jpg)

726bf 发表于 2010-5-21 10:43:04

我换了一个新的,情况一样,查了屏的资料如下,初始化定义的时候该如何定义呢http://cache.amobbs.com/bbs_upload782111/files_29/ourdev_555653.jpg
(原文件名:S6A0069.jpg)

726bf 发表于 2010-5-22 00:55:51

回复【20楼】xbwpc
用&amp;仍需要移位,用&gt;&gt;一次性解决,并且可读性好
-----------------------------------------------------------------------

经人指点,发现问题了,如果数据(command)=0000 0101 ,那么经过DB5=(command>>1)%2这一条指令后,会变成1,而不是0

以上为菜鸟见解,如果有错,望高人指出!这段代码应该要怎么修改呢?

xbwpc 发表于 2010-5-22 11:47:55

回复【23楼】726bf Mos
DB5=(command>>1)%2这一条指令后,会变成1,而不是0 ?
-----------------------------------------------------------------------
那岂不是单片机位操作计算错误?

wandy2010 发表于 2010-5-24 13:17:33

建议 726bf Mos 抄一段别人的程序试一下,如果能用,慢慢找原因,别人修改你的程序,挺费心的,不如你学别人的

726bf 发表于 2010-5-24 16:11:08

回复【25楼】wandy2010
建议 726bf mos 抄一段别人的程序试一下,如果能用,慢慢找原因,别人修改你的程序,挺费心的,不如你学别人的
-----------------------------------------------------------------------

我就是抄楼主的程序试的。

xbwpc 发表于 2010-5-24 19:39:06

我的程序一直工作稳定啊,stc89c52rc+24m clock

726bf 发表于 2010-5-25 18:51:52

回复【27楼】xbwpc
我的程序一直工作稳定啊,stc89c52rc+24m clock
-----------------------------------------------------------------------

弄好了,可以正常显示了。

fshunj 发表于 2010-7-3 17:39:11

MARK

heibaogame 发表于 2010-8-16 13:47:37

DB7=(command>>7)%2;

这个方法太好了!!!!

racemaker 发表于 2010-9-6 16:21:25

领教了
void LCD_init(void)
{
delay(50);
LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)
delay(10);
LCD_en_com(0x32);//然后再改到4位线宽,这样初始化才稳定
delay(10);
LCD_en_com(0x28);//四线模式设置
delay(10);
LCD_en_com(0x0c);//显示开--对应开关显示控制指令
delay(10);
CLEARSCREEN;
delay(30);
}



LZ想问你一下0x33,0x32是什么命令?

PBB888 发表于 2010-9-13 13:10:12

看看

grant-liao 发表于 2010-12-10 09:35:55

高手啊。复制再说。以后想写什么直接调用就好了。
对了能否详细解释一下下面的
DB7=(command>>3)%2;
DB6=(command>>2)%2;
DB5=(command>>1)%2;
DB4=(command>>0)%2;

millwood0 发表于 2010-12-10 10:03:18

"DB7=(command>>7)%2; "

try this:

DB7=(command & 0x80)? 1:0;

infinitely more readable and portable and efficient.

grant-liao 发表于 2010-12-10 13:44:10

回复【34楼】millwood0
-----------------------------------------------------------------------

这两个是一样的吗?
要解释就麻烦多写点。本人水平有限理解不了啊。

grant-liao 发表于 2010-12-10 14:33:04

自己随便拿个算了一下
终于明白了
DB7=(command>>3)%2;
DB6=(command>>2)%2;
DB5=(command>>1)%2;
DB4=(command>>0)%2;
楼主真的是太牛。这个也想出来了。

grant-liao 发表于 2010-12-10 14:55:47

void LCD_init(void)
{
delay(50);
LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)
delay(10);
LCD_en_com(0x32);//然后再改到4位线宽,这样初始化才稳定
delay(10);
LCD_en_com(0x28);//四线模式设置
delay(10);
LCD_en_com(0x0c);//显示开--对应开关显示控制指令
delay(10);
CLEARSCREEN;
delay(30);
}
楼主有点懒哦,看了后面朋友的时序才明白为什么是0x33.0x32.0x28.0x0c
其实要写都是高四位。但是楼主程序把低四位也处理到了高四位。
所以一次输入0x33就相当写了两次0011.
真是经典啊。

jianjun42 发表于 2010-12-10 16:47:11

个人感觉C语言驱动LCD好麻烦,用bascom要简单的多

xzm8469105 发表于 2010-12-11 01:17:42

DB7=(bit)(command&0x80);

scigal 发表于 2011-3-23 15:22:25

mark.正好在做这个,做出来的再和大家交流

danceman_uk 发表于 2011-3-23 18:10:33

mark.学习了!

danceman_uk 发表于 2011-3-25 13:01:02

这样子,就能一组IO搞定1602.省布线了

xiao100 发表于 2011-3-26 23:45:09

good mark

aeiowx 发表于 2011-3-27 00:03:15

MARK

ERDTxiduoduo 发表于 2011-3-27 10:53:47

mark

danceman_uk 发表于 2011-3-28 21:47:06

http://cache.amobbs.com/bbs_upload782111/files_37/ourdev_626280JFCBSX.jpg
上图,面包板测试成功 (原文件名:1.avi_snapshot_00.02_.jpg)

pan90 发表于 2011-3-29 11:49:08

mark

downtoearth 发表于 2011-3-29 12:16:07

mark

niepan 发表于 2011-3-29 19:20:54

回复【楼主位】xbwpc
-----------------------------------------------------------------------

上个改过的




#ifndef _4PIN_1602_H
#define        _4PIN_1602_H
#include<AT89X52.h>

//lcd part
#define   LINE1      0
#define   LINE2      1
#define   LINE1_HEAD   0x80
#define   LINE2_HEAD   0xC0
#define   CLEARSCREEN   LCD_en_com(0x01)
/*************************************/
//change this part at different board
sbit DB7=P2^7;
sbit DB6=P2^6;
sbit DB5=P2^5;
sbit DB4=P2^4;

sbit LCD1602_RS=P2^3;   //data command select1 data0 commandpin 4
sbit LCD1602_RW=P2^1;   //read write select   1 read   0 write   pin 5
sbit LCD1602_EN=P2^0;   //LCD enable signal             pin 6
/********************************************************************/
void delay(unsigned int n)      
{
    unsigned int i=0,j=0;
    for (i=n;i>0;i--)
   for (j=0;j<12;j++);   
}
void LCD_en_com(unsigned char command)
{
DB7=(bit)(command&0x80);
DB6=(bit)(command&0x40);
DB5=(bit)(command&0x20);
DB4=(bit)(command&0x10);


//DB7=(command>>7)%2;         //DB7=(bit)(command&0x80);
//DB6=(command>>6)%2;
//DB5=(command>>5)%2;
//DB4=(command>>4)%2;
LCD1602_RS = 0;    //RS 0
LCD1602_RW = 0; //RW 0
LCD1602_EN = 1; //EN --\|/__ Write command
delay(2);

LCD1602_EN = 0;
DB7=(bit)(command&0x08);
DB6=(bit)(command&0x04);
DB5=(bit)(command&0x02);
DB4=(bit)(command&0x01);


//DB7=(command>>3)%2;
//DB6=(command>>2)%2;
//DB5=(command>>1)%2;
//DB4=(command>>0)%2;
LCD1602_RS = 0;    //RS 0
LCD1602_RW = 0; //RW 0
LCD1602_EN = 1; //EN --\|/__ Write command
delay(2);
LCD1602_EN = 0;
}
void LCD_en_dat(unsigned char command)
{
//DB7=(command>>7)%2;
//DB6=(command>>6)%2;
//DB5=(command>>5)%2;
//DB4=(command>>4)%2;
DB7=(bit)(command&0x80);
DB6=(bit)(command&0x40);
DB5=(bit)(command&0x20);
DB4=(bit)(command&0x10);

LCD1602_RS = 1; //RS 1
LCD1602_RW = 0; //RW 0
LCD1602_EN = 1; //EN --\|/__ Write data
delay(2);
LCD1602_EN = 0;
DB7=(bit)(command&0x08);
DB6=(bit)(command&0x04);
DB5=(bit)(command&0x02);
DB4=(bit)(command&0x01);

//DB7=(command>>3)%2;
//DB6=(command>>2)%2;
//DB5=(command>>1)%2;
//DB4=(command>>0)%2;
LCD1602_RS = 1; //RS 1
LCD1602_RW = 0; //RW 0
LCD1602_EN = 1; //EN --\|/__ Write data
delay(2);
LCD1602_EN = 0;
}
void LCD_set_xy(unsigned char x,unsigned char y)
{
unsigned char address;
if(y == LINE1)
address = LINE1_HEAD + x;
else
address = LINE2_HEAD + x;
delay(10);
LCD_en_com(address);
}
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s)
{
LCD_set_xy(x,y);
while(*s)   
{
LCD_en_dat(*s);   
s++;
}
}
void LCD_init(void)
{
delay(50);
LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)
delay(10);
LCD_en_com(0x32);//然后再改到4位线宽,这样初始化才稳定
delay(10);
LCD_en_com(0x28);//四线模式设置
delay(10);
LCD_en_com(0x0c);//显示开--对应开关显示控制指令
delay(10);
CLEARSCREEN;
delay(30);
}
/********************************************************************/

#endif

513696765 发表于 2011-3-30 15:49:23

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4622534&bbs_page_no=1&search_mode=1&search_text=1602&bbs_id=9999

summerstar 发表于 2011-4-30 22:38:47

mm

zhangjinxing 发表于 2011-5-1 00:47:48

mark

millwood0 发表于 2011-5-1 01:45:55

"DB7=(command>>7)%2;"

try this:

"DB7=(command & 0x80)? 1:0;"

always work on any compiler.

millwood0 发表于 2011-5-1 07:50:17

"LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)"

if you look at 44780's datasheet, you will see that the above isn't in compliance with the datasheet.

"DB7=(bit)(command&0x80);"

poor portability and it is compiler dependent: "bit" isn't a C type.

millwood0 发表于 2011-5-1 08:46:24

"LCD1602_RS = 1; //RS 1   
LCD1602_RW = 0; //RW 0   "

if you change those from set / clear bit operations, you can pretty much run the same code on many different chips.

wpnx 发表于 2011-5-1 10:00:13

mark 学习

xbwpc 发表于 2011-5-1 11:28:11

回复【53楼】millwood0
"db7=(command&gt;&gt;7)%2;"
try this:
"db7=(command &amp; 0x80)? 1:0;"
always work on any compiler.

-----------------------------------------------------------------------

I do not think it is very necessary.Though it is fast,you need to delay after you write a byte.

xbwpc 发表于 2011-5-1 11:38:19

And in fact these operations are not called very often.
My English is poor(I am a junior high school student).Can you speak Chinese?

stevenxia 发表于 2011-5-2 13:44:47

有没有朋友用74164写过lcd1602啊本人写出来只能显示0123等数字 其他显示各种符号如我要显示12345678这几个数结果显示为123 后面的都是各种符号如大于小于等找了一天找不出原因

millwood0 发表于 2011-5-3 01:01:20

I posted one a while back. it utilizes user-defined pins and you can assign the pins however you want. it can be also driven off hardware or software spi.

sunicecream 发表于 2011-5-3 01:35:05

记号一下,有时间看看,挺有意思的

zjth1 发表于 2011-5-28 11:25:27

M20110501

yanyinzhong 发表于 2011-7-5 20:05:55

回复【楼主位】xbwpc
-----------------------------------------------------------------------

用阁下的程序,使用proteus仿真可以,实际板子用stc89c58驱动1602不行求解

hewencao 发表于 2011-7-5 21:42:00

回复【楼主位】xbwpc
-----------------------------------------------------------------------

学习了...

xbwpc 发表于 2011-7-6 15:47:01

回复【63楼】yanyinzhong
-----------------------------------------------------------------------

我用stc89c52rc(24mhz),12c5a60s2(4mhz),11f04e(rc),都试过,运行很稳定阿
我现在凡是51中用1602都是这个程序,一次也没出过问题。
试试加大延时。

有问题急问我的话加QQ:731655696 注明ourdev

wh1988 发表于 2011-7-6 15:58:44

学习中,mark

xiaoyigechaos 发表于 2011-7-6 21:32:15

终于找到了哈哈测试成功

Rjaen 发表于 2011-7-7 09:09:52

呵呵,学习学习

lgw65 发表于 2011-7-7 09:18:10

mark

tonyone 发表于 2011-7-7 11:16:50

mark

lewisz 发表于 2011-7-15 01:27:04

mark LCD1602 四线

lukyers 发表于 2011-7-15 08:20:30

mark

lgs2007m 发表于 2011-7-16 13:23:50

mark

dream_one 发表于 2011-7-16 14:56:04

哈哈,不错,来学习下。

xibuol 发表于 2011-7-19 00:07:21

标记一下

batou 发表于 2011-8-12 14:00:41

mark

berryluker2 发表于 2011-8-12 22:34:37

如果P89C51的P0口来驱动1602,是不是会有问题?
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_667034CAXBG9.jpg
(原文件名:schem.jpg)

voval 发表于 2011-8-15 13:41:37

mark~

sxbgfz 发表于 2011-8-18 15:01:20

建议楼主用宏定义把它变成可移植程序,avr等单片机没有位声明

sdf159372008 发表于 2011-8-27 22:27:00

mark收藏

Tankng 发表于 2011-8-28 10:04:17

前些天,坛子里有个贴子。就是四根线来给1602传数据。他的做法是:
unsigned char bdata dat;
sbit dat0=dat^0;
sbit dat1=dat^1;
sbit dat2=dat^2;
sbit dat3=dat^3;
//sbit dat4=dat^4;
//sbit dat5=dat^5;
//sbit dat6=dat^6;
//sbit dat7=dat^7;
后面,数据的传输这样处理:
//DB0,DB1,DB2,DB3先已定义好
void L_Dat(uchar SHUJU)
{
    dat=SHUJU;
    DB0=dat^0;
    DB1=dat^1;
  DB2=dat^2;
    DB3=dat^3;
}

void write_command(uchar com)
{
    rw=0;
    rs=0;
    L_Dat(com>>4);
    en=0;
    _nop_();
    en=1;

    L_Dat(com>>4);
    en=0;
    _nop_();
    en=1;
}
没试过,哪位有空试试。应该能行的。我觉得这样处理的关键在于:定义了一个可以进行位寻址的变量-unsigned char bdata dat.
欢迎指正!

Tankng 发表于 2011-8-28 10:08:49

上面写错了个位置,write_command()里第二个L_Dat(com),里面的com应该不再移四位。(我先写了上面,下面复制的。忘了修正)

xmfish 发表于 2011-8-28 11:59:32

很好的方法

xbwpc 发表于 2011-11-10 08:55:41

回复【83楼】Tankng
-----------------------------------------------------------------------

这种位寻址的方法更高效,但所用的单片机要支持位寻址操作。

好久之前的贴了,这几天准备重写一个。

xbwpc 发表于 2011-11-10 09:00:54

上个图先:

http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_693676MC16J3.JPG
(原文件名:1602Drv.JPG)

y5000 发表于 2011-11-13 04:17:49

mark

zlj2008 发表于 2011-11-13 23:31:29

记下

xbwpc 发表于 2011-11-14 22:31:30

代码:
点击此处下载 ourdev_695210PLBQ9C.rar(文件大小:23K) (原文件名:LCD1602 Driver Test.rar)

可能有Bug,大家自行测试吧,没时间了,这些主要是前段时间搞信息学奥赛的时候写的。
上高一了,在实验班里好累。

wpnx 发表于 2011-11-16 07:38:51

mark

liang118038 发表于 2011-12-9 18:42:17

回复【48楼】downtoearth
-----------------------------------------------------------------------

void LCD_init(void)
{
delay(50);   
LCD_en_com(0x33);//原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位)
delay(10);
LCD_en_com(0x32);//然后再改到4位线宽,这样初始化才稳定
delay(10);   
LCD_en_com(0x28);//四线模式设置
delay(10);
LCD_en_com(0x0c);//显示开--对应开关显示控制指令
delay(10);
CLEARSCREEN;
delay(30);
}

其实LCD_en_com(0x33);这段根本是多余的关键是下面两段

LCD_en_com(0x32);
delay(10);   
LCD_en_com(0x28);
delay(10);

才是真正起作用的关键!

raxb 发表于 2011-12-9 20:42:03

回复【79楼】berryluker2
-----------------------------------------------------------------------

大哥,P0口不用接上拉吗?

raxb 发表于 2011-12-9 20:45:03

http://cache.amobbs.com/bbs_upload782111/files_48/ourdev_703179ZK5JGI.png
lCD1602 (原文件名:1602.png)

#include<reg2051.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd P3
sbit en=P1^7;
sbit rs=P1^6;
sbit rw=P1^5;
uchar buffer;
void delay(uchar x)
{
        uchar i,j;
        for(i=x;i>0;i--)
                for(j=120;j>0;j--);
}
void delay1(unsigned long v)
{
while(v--);
}
void w_data(uchar input)
{
       delay1(100);
       rs=1;
       rw=0;
       en=0;
       lcd=(input&0xf0)>>4;
       en=1;
       delay1(100);
       en=0;
       lcd=input&0x0f;
       en=1;
       delay1(100);
       en=0;
}
void w_code(uchar input)
{
    delay1(100);
        rs=0;
        rw=0;
        en=0;
        lcd=(input&0xf0)>>4;
        en=1;
        delay1(100);
        en=0;
        lcd=input&0x0f;
        en=1;
        delay1(100);
        en=0;
}
void lcd_init(void)
{
    lcd=0x00;       
        w_code(0x03);
        delay1(5);
    w_code(0x03);
        delay1(5);
        w_code(0x02);
        delay1(5);
        w_code(0x03);
        delay1(5);
        w_code(0x28);
        w_code(0x08);
        w_code(0x06);
        w_code(0x01);
        w_code(0x0c);
}
void get_xy(uchar x,uchar y)
{
        if(y==1)
        {
       w_code(0xc0+x);
        }
        else
        {
       w_code(0x80+x);
        }
}
void w_str(uchar x,uchar y,uchar *p)
{
        get_xy(x,y);
        while(*p)
        {
       w_data(*p);
       p++;
        }
        delay(5);
}
void main(void)
{
        lcd_init();
        w_str(0,0,"The volt is: ");
        w_str(6,1,"12.34567 V");
        while(1);
}

xuyapple 发表于 2011-12-10 10:45:44

谢谢楼主分享^_^
学到不少东西~
听过有人用两个I/O口驱动1602,嘻嘻

327462422 发表于 2011-12-10 16:37:52

顶一个,学习中····

452840622 发表于 2011-12-11 22:38:40

回复【30楼】heibaogame 黑豹
-----------------------------------------------------------------------

很好啊

452840622 发表于 2011-12-11 22:39:22

回复【楼主位】xbwpc 文
-----------------------------------------------------------------------

我一定要式的 啊

452840622 发表于 2011-12-11 22:39:53

回复【10楼】wandy2010 老铁
-----------------------------------------------------------------------

好的

miyadai 发表于 2011-12-12 14:30:17

mark!

angel_gph 发表于 2011-12-12 17:49:23

33>>32>>28
是可以驱动!!还弄不清楚为什么要这样

cdkzigbee 发表于 2011-12-12 18:11:30

如何在1602液晶上显示汉字
页: [1] 2
查看完整版本: LCD1602 四线程序测试成功(每根线单独定义)