原创 昨天在ouravr看到的关于1602四位数据线时初始化不稳定问题的正确解决方法的文章

2008-11-17 14:58 5534 13 10 分类: MCU/ 嵌入式
几天前搞了个LCM1602来玩,网上下载了别人的程序改巴改巴就写到M48里面,就遇到了初始化很不稳定的问题.
上网查看,发现很多人都反映如此,也有人提供了解决方法但并不完美.继续找资料,查了很多pdf资料,最后在
微雪电子公布的技术文档里找到了答案.
原来1602初始化成4位数据线之前必需先初始化成8位(此时命令发送方式是8位格式,但数据线只需接4位),然后再改到4位线宽,
这样才能稳定的进入4位模式.
正确的初始化过程是这样的:

1)上电
2)等待15ms以上
3)8位模式写命令0b0011xxxx (后面4位线不用接,所以是无效的)
4)等待4.1ms以上
5)同3)
6)等待100us以上
7)同3)
以上步骤中不可查询BF状态,只能用延时控制

从一下步骤开始可以查询BF状态确定模块是否忙
8)8位模式写命令0b0010xxxx 进入4位模式

以下操作都必需用4位模式格式进行
9)4位模式写命令0b0010NFxx NF为行数和字符高度设置位,之后行数和字符高不可重设

10)4位模式写命令0b00001000 关闭现实
11)4位模式写命令0b00000001 清屏
12)4位模式写命令0b000001(I/D)S 设置光标模式

初始化完成,可以用4位模式写字符

以下是我在M48上调通的程序,虽然没有完全遵循上面的过程,但工作稳定,M48的时钟为1M或8M都能稳定初始化1602
希望大家以后不用再在这个问题上多走弯路.

/*********************  LCD 1602 Display Routine Functions *************************/
/*  winavr2007                                                                     */
/***********************************************************************************/

#include <avr/io.h> //MCU为ATmega48
#include <stdio.h>
#include <util/delay.h>


#define uchar unsigned char

#define LCD_PORT  PORTD   
#define LCD_DDR   DDRD    
#define LCD_PIN   PIND

#define RS         5
#define RW         6 
#define EN         7
#define LCD_DATA       ((1<<0)|(1<<1)|(1<<2)|(1<<3)) 
 
#define SETBIT(x,y)   (x|=(1<<y))      //set bit y in byte x
#define CLRBIT(x,y)   (x&=(~(1<<y)))   //clear bit y in byte xx
 

//--------------------------------------------------------------------------------

//延时函数我就不多说了,直接写出来
void Delay_10ms(uchar _time)
{
    while( _time>0)
    {
        _delay_ms(15);
        _time--;
    }
}


//--------------------------------------------------------------------------------

 
//设置所需函数

//写数据线命令(四线模式数据要分两次写)
void out_dataline(uchar line)
{
        SETBIT(LCD_PORT,EN);   //EN=1
        LCD_PORT&=0Xf0;               //清低四位端口
        LCD_PORT|=line/16;           //写高四位数据
        CLRBIT(LCD_PORT,EN);   //EN=0

 
        SETBIT(LCD_PORT,EN);   //EN=1
        LCD_PORT&=0Xf0;               //清低四位端口
        LCD_PORT|=line&0x0f;           //写低四位数据
        CLRBIT(LCD_PORT,EN);   //EN=0
}


//一、写指令函数
void write_command(unsigned char com)
{
        _delay_us(16);        //delay
        CLRBIT(LCD_PORT,RS);  //RS=0
        out_dataline(com);
}
 
//二、写数据函数(四线模式数据要分两次写)

void write_data(unsigned char data)
{
        _delay_us(16);        //delay
        SETBIT(LCD_PORT,RS);  //RS=1
        out_dataline(data);
}


//三、初始化LCD1602函数
void LCD_init(void)
{
        LCD_DDR=0xff;         //设为输出
        CLRBIT(LCD_PORT,RW);  //设为永远W状态
        
        _delay_ms(100);
        write_command(0x33);
        Delay_10ms(2); 
        write_command(0x32);
        Delay_10ms(2);
 
        write_command(0x28);
        write_command(0x0c);  //显示开--对应开关显示控制指令
        write_command(0x01);  //清屏--对应清屏指令
        Delay_10ms(2);         //delay
}


//四、写地址函数

//--------------------------------------------------------------------------------

//要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符
//1602液晶内部显示地址

//比如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?
//这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该?
//?1000000B(40H)+10000000B(80H)=11000000B(C0H)

//--------------------------------------------------------------------------------

void LCD_set_addr(unsigned char x,unsigned char y)//x:0~15,y:0~1
{
        if(y) 
                write_command(0xc0+x);//第二行显示
        else  
                write_command(0x80+x);//第一行显示
}
 


//五、写字符函数
void LCD_write_char(unsigned char X,unsigned char Y,
                    unsigned char data) //列x=0~15,行y=0,1
{
        LCD_set_addr( X, Y ); //写地址
        write_data(data);
}


//六、写字符串函数

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
{
    LCD_set_addr( X, Y ); //写地址    
    while (*s)  // 写显示字符
    {
                write_data( *s );
                s ++;
    }
      
}
 
//到这里我们已经把全部函数写好了下面我们用上面的函数让LCD1602显示

void main(void)
{

        LCD_init(); //初始化LCD1602
         
        //显示hello
        LCD_write_string(0,0,"hi, Jia Xiaodong");
         
        //显示字母
        LCD_write_string(3,1,"Jan-08-2008");
 
}


文章评论2条评论)

登录后参与讨论

用户377235 2013-4-27 21:06

还行。改改更健康!

用户377235 2012-11-19 17:06

大哥谢谢你 解决了
相关推荐阅读
用户472938 2011-09-02 11:31
edn啊,太慢了。决定搬家了
这里继续保留,而且同步更新...
用户472938 2011-02-25 09:54
一年多了,冒个泡
更新一下...
用户472938 2010-09-18 19:39
总要找一些事情做一做
总要找一些事情做一做。转移一下注意力继续收拾家,逐渐的处理闲置的电子产品。东西挺多的,时间会很久。以前一直没时间走走,打算从事户外运动了,一是锻炼身体,而是放松心情。。。 ...
用户472938 2010-02-07 15:23
二手ks0108驱动19264液晶资料
型号:LG192642资料下载地址http://www.ganasys.co.kr/kor/support_board/pds_file/LG192642.pdf...
用户472938 2010-02-07 15:22
12232液晶资料
 edm1836液晶edm1837液晶原理图 ...
用户472938 2010-02-07 15:21
fm收音机模块(tea5767模块)资料。
...
我要评论
2
13
关闭 站长推荐上一条 /2 下一条