求助 我写的1602显示程序 错在哪里
时间:10-02
整理:3721RD
点击:
#include<reg51.h>
#define LCDBUS P0 /* 数据端口 */
sbit LCD_RS = P2^4; /* 数据、指令选择信号 */
sbit LCD_RW = P2^5; /* 读写选择信号 */
sbit LCD_EN = P2^6; /* 读写使能信号 */
/********************************* 命令码 **************************************/
#define SCREEN_CLEAR 0x01 /* Screen Clear, Set AC to 0,Cursor Reposition
功能:1>清除液晶显示器,即将 DDRAM 的内容全部填入"空白"的 ASCII码20H;
2> 光标归位,即将光标撤回液晶显示屏的左上方;
3> 将地址计数器(AC)的值设为0。 */
#define CURSOR_RETURN 0x02 /*DDRAM AD=0, Return,Content Changeless
功能:1> 把光标撤回到显示器的左上方;
2> 把地址计数器(AC)的值设置为0;
3> 保持DDRAM的内容不变。 */
#define INPUT_SET 0x06 //Set moving direction of cursor,Appoint if move
//|0|0|0|0|0|1|I/D|S|
//功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
//I/D=0写入新数据后光标左移,I/D=1写入新数据后光标右移
// S=0写入新数据后显示屏不移动,S=1写入新数据后显示屏整体右移1个字符 */
#define DISPLAY_SWITCH 0x08 //显示关,无光标Set display on/off,cursor on/off,blink on/off
#define DISPLAY_ON 0x04 //|0|0|0|0|1|D|C|B| D=0显示功能关 D=1显示功能开
#define DISPLAY_CURSOR 0x02 // C=0无光标 C=1有光标
#define DISPLAY_CURSOR_BLINK 0x01 // B=0光标闪烁 B=1光标不闪烁 */
#define SHIFT 0x10 //*Remove cursor and whole display,DDRAM changeless
#define CURSOR_RIGHT_MOV 0x08 //|0|0|0|1|S/C|R/L|*|*|
#define CURSOR_NOT_MOV 0x04 //功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:
//S/C=0 光标移动,S/C=1 光标固定;R/L=0光标左移1格,且AC值减1,R/L=1光标右移1格,且AC值加1
#define MODLE0 0x38 //0X38: 8位数据接口;两行显示;5 * 7 点阵字符
#define MODLE1 0x28 //0X28: 4位数据接口;两行显示;5 * 7 点阵字符
#define CGRAM_AD_SET 0x40 //Set CGRAM AD,send receive data.设定下一个要存入数据的CGRAM的地址
//|0|1|CGRAM地址(6bit)|
//DB5DB4DB3 为字符号,也就是你将来要显示该字符时要用到的字符
//地址。(000~111)(能定义八个字符)
//DB2DB1DB0为行号。(000~111)(八行)
#define DDRAM_AD_SET 0x80 //Set DDRAM AD,send receive data设定下一个要存入数据的DDRAM的地址
//|1|DDRAMRAM地址(7bit)|
void soft_nop(){;}
void Lcd1602_CheckBusy( void ){//检查Lcd1602是否忙
unsigned char BusyFlag; /* 忙标志 */
BusyFlag = 1; /* 先置位忙标志 */
while ( BusyFlag ) /* 如果忙,一直等待 */
{
BusyFlag = (Lcd1602_ReadStatus()) & 0x80; /* 稍微延时后继续查询 */
}
LCD_EN = 0; /* 拉低EN */
}
void Lcd1602_Cls(){/*清除显示*/
Lcd1602_WriteCmd(SCREEN_CLEAR);
}
unsigned char Lcd1602_ReadStatus(){
unsigned char lcdStatus;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
soft_nop();
lcdStatus = LCDBUS;
LCD_EN = 0;
soft_nop();
LCDBUS= 0xff;
return lcdStatus;
}
unsigned char Lcd1602_ReadData(){
unsigned char lcdData;
LCD_RS = 1;
LCD_RW = 1;
LCD_EN = 1;
soft_nop();
lcdData = LCDBUS;
LCD_EN = 0;
LCDBUS= 0xff;
return lcdData;
}
void Lcd1602_WriteCmd( unsigned char cmd ){//向Lcd1602写入命令
Lcd1602_CheckBusy( ); /* 检查Lcd1602是否忙 */
LCDBUS = cmd;
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 1;
soft_nop();
LCD_EN = 0;
LCDBUS = 0xff;
}
void Lcd1602_WriteData( unsigned char dat,unsigned char pos ){//向Lcd1602写入数据
unsigned char lcdData = dat,disPos = pos;
Lcd1602_CheckBusy( ); /* 检查Lcd1602是否忙 */
Lcd1602_MoveTo(disPos);
LCDBUS = lcdData;
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 1;
soft_nop();
LCD_EN = 0;
LCDBUS = 0xff;
}
void Lcd1602_WriteString( unsigned char *Str,unsigned char x){//向Lcd1602写入字符串
unsigned char ByteCnt = 0,pos = x;
while ( *Str != 0 )
{
Lcd1602_WriteData( *Str,pos++ ); /* 写入数据 */
Str++; /* 指向下一个要写的数据 */
}
}
void Lcd1602_Init(){//初始化Lcd1602
Lcd1602_WriteCmd( MODLE0 ); /*8位数据端口,16*2行显示,5*7字符 */
Lcd1602_WriteCmd( DISPLAY_SWITCH | DISPLAY_ON ); /* 开显示 */
Lcd1602_WriteCmd( INPUT_SET ); /* 读写数据后,移动光标,画面不动 */
Lcd1602_WriteCmd( SCREEN_CLEAR ); /* 清屏 */
}
void Lcd1602_MoveTo(unsigned char position){ //移动光标到指定位.0-31
unsigned char disPos;
while (position >=16)
position += 0x31;
disPos=DDRAM_AD_SET|position;
Lcd1602_WriteCmd(disPos);
}
#define LCDBUS P0 /* 数据端口 */
sbit LCD_RS = P2^4; /* 数据、指令选择信号 */
sbit LCD_RW = P2^5; /* 读写选择信号 */
sbit LCD_EN = P2^6; /* 读写使能信号 */
/********************************* 命令码 **************************************/
#define SCREEN_CLEAR 0x01 /* Screen Clear, Set AC to 0,Cursor Reposition
功能:1>清除液晶显示器,即将 DDRAM 的内容全部填入"空白"的 ASCII码20H;
2> 光标归位,即将光标撤回液晶显示屏的左上方;
3> 将地址计数器(AC)的值设为0。 */
#define CURSOR_RETURN 0x02 /*DDRAM AD=0, Return,Content Changeless
功能:1> 把光标撤回到显示器的左上方;
2> 把地址计数器(AC)的值设置为0;
3> 保持DDRAM的内容不变。 */
#define INPUT_SET 0x06 //Set moving direction of cursor,Appoint if move
//|0|0|0|0|0|1|I/D|S|
//功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
//I/D=0写入新数据后光标左移,I/D=1写入新数据后光标右移
// S=0写入新数据后显示屏不移动,S=1写入新数据后显示屏整体右移1个字符 */
#define DISPLAY_SWITCH 0x08 //显示关,无光标Set display on/off,cursor on/off,blink on/off
#define DISPLAY_ON 0x04 //|0|0|0|0|1|D|C|B| D=0显示功能关 D=1显示功能开
#define DISPLAY_CURSOR 0x02 // C=0无光标 C=1有光标
#define DISPLAY_CURSOR_BLINK 0x01 // B=0光标闪烁 B=1光标不闪烁 */
#define SHIFT 0x10 //*Remove cursor and whole display,DDRAM changeless
#define CURSOR_RIGHT_MOV 0x08 //|0|0|0|1|S/C|R/L|*|*|
#define CURSOR_NOT_MOV 0x04 //功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:
//S/C=0 光标移动,S/C=1 光标固定;R/L=0光标左移1格,且AC值减1,R/L=1光标右移1格,且AC值加1
#define MODLE0 0x38 //0X38: 8位数据接口;两行显示;5 * 7 点阵字符
#define MODLE1 0x28 //0X28: 4位数据接口;两行显示;5 * 7 点阵字符
#define CGRAM_AD_SET 0x40 //Set CGRAM AD,send receive data.设定下一个要存入数据的CGRAM的地址
//|0|1|CGRAM地址(6bit)|
//DB5DB4DB3 为字符号,也就是你将来要显示该字符时要用到的字符
//地址。(000~111)(能定义八个字符)
//DB2DB1DB0为行号。(000~111)(八行)
#define DDRAM_AD_SET 0x80 //Set DDRAM AD,send receive data设定下一个要存入数据的DDRAM的地址
//|1|DDRAMRAM地址(7bit)|
void soft_nop(){;}
void Lcd1602_CheckBusy( void ){//检查Lcd1602是否忙
unsigned char BusyFlag; /* 忙标志 */
BusyFlag = 1; /* 先置位忙标志 */
while ( BusyFlag ) /* 如果忙,一直等待 */
{
BusyFlag = (Lcd1602_ReadStatus()) & 0x80; /* 稍微延时后继续查询 */
}
LCD_EN = 0; /* 拉低EN */
}
void Lcd1602_Cls(){/*清除显示*/
Lcd1602_WriteCmd(SCREEN_CLEAR);
}
unsigned char Lcd1602_ReadStatus(){
unsigned char lcdStatus;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
soft_nop();
lcdStatus = LCDBUS;
LCD_EN = 0;
soft_nop();
LCDBUS= 0xff;
return lcdStatus;
}
unsigned char Lcd1602_ReadData(){
unsigned char lcdData;
LCD_RS = 1;
LCD_RW = 1;
LCD_EN = 1;
soft_nop();
lcdData = LCDBUS;
LCD_EN = 0;
LCDBUS= 0xff;
return lcdData;
}
void Lcd1602_WriteCmd( unsigned char cmd ){//向Lcd1602写入命令
Lcd1602_CheckBusy( ); /* 检查Lcd1602是否忙 */
LCDBUS = cmd;
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 1;
soft_nop();
LCD_EN = 0;
LCDBUS = 0xff;
}
void Lcd1602_WriteData( unsigned char dat,unsigned char pos ){//向Lcd1602写入数据
unsigned char lcdData = dat,disPos = pos;
Lcd1602_CheckBusy( ); /* 检查Lcd1602是否忙 */
Lcd1602_MoveTo(disPos);
LCDBUS = lcdData;
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 1;
soft_nop();
LCD_EN = 0;
LCDBUS = 0xff;
}
void Lcd1602_WriteString( unsigned char *Str,unsigned char x){//向Lcd1602写入字符串
unsigned char ByteCnt = 0,pos = x;
while ( *Str != 0 )
{
Lcd1602_WriteData( *Str,pos++ ); /* 写入数据 */
Str++; /* 指向下一个要写的数据 */
}
}
void Lcd1602_Init(){//初始化Lcd1602
Lcd1602_WriteCmd( MODLE0 ); /*8位数据端口,16*2行显示,5*7字符 */
Lcd1602_WriteCmd( DISPLAY_SWITCH | DISPLAY_ON ); /* 开显示 */
Lcd1602_WriteCmd( INPUT_SET ); /* 读写数据后,移动光标,画面不动 */
Lcd1602_WriteCmd( SCREEN_CLEAR ); /* 清屏 */
}
void Lcd1602_MoveTo(unsigned char position){ //移动光标到指定位.0-31
unsigned char disPos;
while (position >=16)
position += 0x31;
disPos=DDRAM_AD_SET|position;
Lcd1602_WriteCmd(disPos);
}
什么错,不显示?显示乱码?还是什么?
直接没有显示,
直接没有显示,
直接没有显示.
查一下你的延时 看一下使用手册
你的检测忙指令有问题