请问一下液晶EL1602第2行不能显示的问题
主要想看一下第二行的地址是多少现在试了0xc0,0x40,0x90等都没有第2行显示 现在只显示1行
而且通电后第2行没有背景黑框 up 你是不是没有设置成两行的工作模式?
8bit 总线要写指令 0x38, 4bit 总线要写指令 0x2, 0x8 thanks 第2行好像还是没有显示
相关初始化如下:
void LCD_Init(void)
{
LCD_WriteCmd(0x01); // LCD清屏
LCD_WriteCmd(0x06); //数据读、写操作后,光标右移动,AC自动增一
LCD_WriteCmd(0x0C); //开显示;关光标;关闪烁
LCD_WriteCmd(0x38); //8位数据接口;两行显示;5x8点阵字符
} 还是只显示一行16个字符"12345abcde12345a"
完整的程序如下
//******** EL1602 test *********
#include <iom16v.h>
#include <macros.h>
//LCD数据端口PC0-PC7
#define LCD_DATA_PORTPORTC
#define LCD_DATA_DDR DDRC
#define LCD_DATA_PIN PINC
//LCD控制端口PA5,PA7
#define LCD_CONTROL_PORT PORTA
#define LCD_CONTROL_DDR DDRA
#define RS 5
#define E 7
#define LINEWIDTH 16//行宽
#define LINES 2 //行数
//--------------------------------------------------------------------------------------------------
//Public function prototypes
//--------------------------------------------------------------------------------------------------
void Delay_1us(void);
void Delay_1ms(void);
void Delay_nus(unsigned int n);
void Delay_nms(unsigned int n);
#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 x
#define CHKBIT(x,y) (x&(1<<y)) //check bit y in byte x
#define uchar unsigned char // 0~255
#define uint unsigned int // 0~65535
void LCD_Init(void); //LCD初始化
void LCD_Clear(void); //LCD清屏
void LCD_CheckState(void); //--保留
void LCD_WriteCmd(unsigned char scmd); //写一个命令到LCD
void LCD_WriteData(unsigned char DData);//写一个数据到LCD
void LCD_Set_xy(unsigned char Y, unsigned char X); //设置光标位置
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c1); //写一个字符到LCD
void LCD_WriteStr(unsigned char Y,unsigned char X,unsigned char *pstr); //写字符串到LCD显示
void LCD_WriteStrAuto(unsigned char *pstr); //从显示屏的初始位置写入数据,自动换行
void LCD_Init(void)
{
Delay_nms(100);
LCD_WriteCmd(0x01); // LCD清屏
LCD_WriteCmd(0x06); //数据读、写操作后,鼠标右移动,AC自动增一
LCD_WriteCmd(0x0C); //开显示;关光标;关闪烁
LCD_WriteCmd(0x38); //8位数据接口;两行显示;5x8点阵字符
}
//LCD清屏
voidLCD_Clear(void)
{
LCD_WriteCmd(0x01);
Delay_nms(1);
}
void LCD_WriteCmd(unsigned char scmd) //send command
{
CLRBIT(LCD_CONTROL_PORT,E);
CLRBIT(LCD_CONTROL_PORT,RS);
LCD_DATA_DDR=0xFF;
LCD_DATA_PORT=scmd;
NOP();
SETBIT(LCD_CONTROL_PORT,E);
NOP();
CLRBIT(LCD_CONTROL_PORT,E);
Delay_nus(20);
}
void LCD_WriteData(unsigned char DData)
{
CLRBIT(LCD_CONTROL_PORT,E);
SETBIT(LCD_CONTROL_PORT,RS);
LCD_DATA_DDR=0xFF;
LCD_DATA_PORT=DData;
NOP();
SETBIT(LCD_CONTROL_PORT,E);
NOP();
CLRBIT(LCD_CONTROL_PORT,E);
Delay_nus(20);
}
//设置光标位置,先Y坐标后X坐标
void LCD_Set_xy(unsigned char Y, unsigned char X)
{
unsigned char i=0x00;
switch(Y & 0x0f) //确定行号
{
case 0x00:
i=0x80;//0x80
break;
case 0x01:
i=0xC0; //0x90;
break;
default :
break;
}
i = (X & 0x0f)|i; //确定列号
LCD_WriteCmd(i);
}
//从显示屏指定的行(Y),列(X)的位置写入字符
void LCD_WriteChar(unsigned char X,unsigned char Y,unsigned char c1)
{
LCD_WriteCmd(0x38); // 8bit I/F, basic command, graphic off
LCD_Set_xy(X,Y);
LCD_WriteData(c1);
Delay_nms(1); //2006.11.19
}
//从显示屏指定的行(Y),列(X)的位置写入字符串
void LCD_WriteStr(unsigned char X,unsigned char Y,unsigned char *pstr1) //英文LCD
{
unsigned char j;
unsigned char *pstr = pstr1;
LCD_WriteCmd(0x38); // 8bit I/F, basic command, graphic off
LCD_Set_xy(Y,X);
j=Y * LINEWIDTH + X;
while (*pstr && j< (LINEWIDTH * LINES))
{
if (j%LINEWIDTH==0) //判断是否换行
{
LCD_Set_xy(j/LINEWIDTH,0); //如换行, 则光标移动到行首
Delay_nms(1);
}
LCD_WriteData(*pstr++);
j++;
Delay_nms(1);
}
Delay_nms(1); //2006.11.19
}
//从显示屏的初始位置写入字符串,自动换行
void LCD_WriteStrAuto(unsigned char *pstr1)//英文LCD
{
unsigned char i;
unsigned char j;
unsigned char *pstr = pstr1;
LCD_WriteCmd(0x38); // 8bit I/F, basic command, graphic off
LCD_Clear();
LCD_Set_xy(0,0);
Delay_nms(1);
j=0;
while (*pstr && j<LINEWIDTH*LINES)
{
if (j%LINEWIDTH==0) //判断是否换行
{
LCD_Set_xy(j/LINEWIDTH,0); //如换行, 则光标移动到行首
Delay_nms(1);
}
LCD_WriteData(*pstr++);
j++;
Delay_nms(1);
}
Delay_nms(1);
}
void main(void)
{
CLI(); // disable interrupts
Delay_nms(1000);
//LCD端口初始化
LCD_DATA_DDR=0xFF;
LCD_CONTROL_DDR|=(1<<RS|1<<E); //置位RS,E等
CLRBIT(LCD_CONTROL_PORT,E);
CLRBIT(LCD_CONTROL_PORT,RS);
LCD_DATA_PORT|=0xFF;
//LCD功能初始化
LCD_Init();
Delay_nms(10);
while(1)
{
LCD_WriteStrAuto("12345abcde12345abcde");
Delay_nms(2000);
}
}
/*-----------------------------------------------------------------------
延时函数
系统时钟:8M
-----------------------------------------------------------------------*/
void Delay_1us(void) //1us延时函数
{
asm("nop");
}
void Delay_nus(unsigned int n) //N us延时函数
{
unsigned int i=0;
for (i=0;i<n;i++)
Delay_1us();
}
void Delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i=0;i<1140;i++);
}
void Delay_nms(unsigned int n) //N ms延时函数
{
unsigned int i=0;
for (i=0;i<n;i++)
Delay_1ms();
} C51 我也只是初学,也没有 AVR 的编译环境。所以你 AVR C 的程序我也没法帮你试,但是有几点建议:
1,初始化的指令序列,和控制 IC 手册上要求的不一样,如果你是 8bit 接法,要按时序写 3 次 0x38。然后才开始设置。当然,我也有不完全按照手册要求进行初始化成功的。应该是 LCM 内部初始化 OK,不需要外部指令做初始化了。
2,建议你先用一套简单的指令来试验。直接用一个循环写两行的内容。下面是我程序里的做法。避免因为其他逻辑出错,导致误认为 LCM 工作不正常。这样可以快速地缩小问题的范围。下面的循环在我的系统上,是可以正常显示一行大写 "ABCD...." ,第二行小写"abcd..."的。当然,其他的程序段我省略了。
for (i; i < 16; i++) {
w_CMD_LCM1602(0x80 + i); //定位第一行左一位置,并逐个向右
delay_ms_0(1);
w_DAT_LCM1602(0x41 + i); //从 'A' 开始写大写字符
delay_ms_0(1);
w_CMD_LCM1602(0xC0 + i); //定位第二行左一位置,并逐个向右
delay_ms_0(1);
w_DAT_LCM1602(0x61 + i); //从 'a' 开始写小写字符
delay_ms_0(1);
}
3,建议你对你设置光标位置的 LCD_Set_xy(Y,X) 当中 LCD_WriteCmd(i);这行下个中断,看看写进去的命令值是多少,第一行应该是从 0x80 开始。第二行应该是从 0xC0 开始。
(修改错字) 还有可以看一下论坛里其他的帖子,1602 讨论还挺多的。8bit 的例子也很多。我之前也有发一个帖子,其中有关于初始化的文档。你可以参考一下。
http://ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4344053&bbs_page_no=3&bbs_id=1006 谢谢,明天连写3次初始化,并直接写第2行试试; 以前用其他液晶好像很容易调通的 已解决,感谢【3楼】 easywater 的提示
LCD_WriteChar,LCD_WriteStr,LCD_WriteStrAuto 中也修改成0x38就ok了 我也遇到这个问题了.
页:
[1]