程序时自己写的 ,但是液晶不显示字符,请高手指点
/************************************************************
* 公司名称:
* 创 建 人:匡 伟 创建日期:2009-8-25
* 修 改 人: 修改日期:
* 模 块 名: 开发板型号:
* 芯片型号:STC89c52
* 函 数 名:
* 功能描述:液晶显示程序
* 其他说明:
* stc80c52的晶振频率为12MHz
************************************************************/
#include"stc89.h"
#include"mDelay.h"
#include"intrins.h"
#define uchar unsigned char
#define DPORT P0
sbit RS = P3^7 ; //P3_7
sbit RW = P3^6 ;
sbit E = P3^5 ; //p3_5 WR P3_6
#define NODISP 0
#define NOCUR 1
#define CURNOFLASH 2
#define CURFLASH 3
#define CLEARSCREEN 0x01 //清屏控制字
uchar Xpos,Ypos;
//#define NOP _nop_
/**************Lcd驱动部分函数声明**************************/
void SetCur(uchar c);
void ClearLcd(void);
void ReadStatus(void);
void LcdWriteData(uchar c);
void LcdWriteCommand(uchar c,uchar Busy);
//void LcdPos();
void LcdInit( );
void DispOneChar(uchar x, uchar y,uchar Data);
void DispListChar(uchar x, uchar y,uchar code *Data);
/**************光标(cur)设置命令***************************/
void SetCur( uchar cur )
{
switch( cur )
{
case 0x00:
{
LcdWriteCommand(0x08,1); //LCD关显示
break;
}
case 0x01:
{
LcdWriteCommand(0x0c,1); //LCD开显示但是无光标
break;
}
case 0x02:
{
LcdWriteCommand(0x0e,1); //LCD显示有光标但光标不闪烁
break;
}
case 0x03:
{
LcdWriteCommand(0x0f,1); //LCD开显示光标闪烁
break;
}
default:break;
}
}
/************************************************************/
/**************清屏命令**************************************/
void ClearLcd()
{
LcdWriteCommand(CLEARSCREEN,1);
}
/************************************************************/
/************正常读写前检测LCD控制器处于忙状态?*************/
void ReadStatus()
{
uchar temp;
DPORT=0xff;
RS=0;
RW=1;
/**/
E=0;
E=0;
/**/ //读状态
E=1;
_nop_();
for(;;)
{
temp=DPORT; //读状态控制字
temp&=0x80; //if the station of control word--DPORT^7=0;enable;
if(temp==0)
break;
}
E=0;
}
/************************************************************/
/**************不带忙检测的写字符(数据)子程序****************/
void LcdWriteData(uchar c)
{
DPORT=c;
RS=1; //写数据
RW=0;
E=0; //下降沿表示enable端有效
_nop_();
E=1;
_nop_();
E=0;
}
/************************************************************/
/**************不带忙检测的送控制字子程序********************/
void LcdWriteCommand(uchar c, uchar Busy)
{
if(Busy)
{
ReadStatus();
}
DPORT=c;
RS=0; //写数据
RW=0;
E=0; //下降沿表示enable端有效
_nop_();
E=1;
_nop_();
E=0;
}
/************************************************************/
/**************LcdPos************************************
void LcdPos()
{
uchar temp;
Xpos&=0x0f;
Ypos&=0x01;
temp=Xpos;
if(Ypos==1)
{
temp+=0x40;
}
temp|=0x80; //80h+地址码(2-27h 或者40-67h)
LcdWriteCommand(temp,1); //读写操作
}
************************************************************/
/*************Lcd复位程序************************************/
void LcdInit()
{
mDelay(15);
LcdWriteCommand(0x38,0);
mDelay(5);
LcdWriteCommand(0x38,0);
mDelay(5);
LcdWriteCommand(0x38,0);
LcdWriteCommand(0x38,1);
LcdWriteCommand(0x08,1);
LcdWriteCommand(0x01,1);
LcdWriteCommand(0x06,1);
LcdWriteCommand(0x0c,1);
}
/************************************************************/
/**************LcdDispOneChar(在制定的行和列*******************/
void DispOneChar(uchar x, uchar y, uchar Data)
{
x&=0x0f;
y&=0x01;
if(y==0x01)
{
x|=0x40;
}
x|=0x80; //80h+地址码(2-27h 或者40-67h)
LcdWriteCommand(x,0); //忽略忙信号检测 读写操作
LcdWriteData(Data);
}
/************************************************************/
/**************DispOneChar***********************************/
voidDispListChar(uchar x, uchar y,uchar code *Data)
{
uchar ListLength=0;
x&=0x0f;
y&=0x01;
while(x<16)
{
if(Data[ListLength]==0)
{
break;
}
DispOneChar(x,y,Data[ListLength]);
ListLength++;
x++;
}
}
/************************************************************/
/**************main函数**************************************/
void main(void)
{
uchar code s1[]={"hello world"};
// uchar m;
P2=0x00;
P2=P2|0x60;
mDelay(500);
LcdInit();
ClearLcd();
SetCur(CURFLASH);
while(1)
{
DispListChar(1,0,s1);
}
}
/************************************************************/
各位大侠如果用到液晶屏,我可以给大家提供一套比较好的方案,不用编写底层程序,并且稳定安全。可以 dwin99@live.cn
1602的使用很成熟了
你先确定硬件连接是否正常,
检查时序是否过快。
你这程序太长了...弄个简单的先测试好了在写完整的。
这是我验证过的,可以参考下啊
#include
#include
#define nop _nop_()
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned int uint16;
typedef signed int int16;
typedef unsigned long uint32;
typedef signed long int32;
sbit a0 = ACC^0;
sbit a1 = ACC^1;
sbit a2 = ACC^2;
sbit a3 = ACC^3;
sbit a4 = ACC^4;
sbit a5 = ACC^5;
sbit a6 = ACC^6;
sbit a7 = ACC^7;
#define LCD1602_DATA P0 //8位数据并行口
#define LCD1602_RS P2_0 //指令OR数据寄存器选择
#define LCD1602_RW P2_1 //读写控制
#define LCD1602_EN P2_5 //使能控制
#define LCD1602_CLR 0x01 //清屏
#define LCD1602_MODE 0x38 //8位数据,双列显示,5*7字形
#define LCD1602_ON 0x0c //开显示,关光标,光标不闪烁
#define LCD1602_ADDR_MODE 0x06 //地址递增
uint8 code self_table1[]={
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,// 年
0x1f,0x11,0x1f,0x11,0x1f,0x11,0x15,0x17,//月
0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00,// 日
0x01,0x0c,0x17,0x14,0x17,0x0c,0x01,0x00,//闹钟标志
0x10,0x18,0x1c,0x1e,0x1f,0x1c,0x18,0x10 };//三角形符号
/**********************************************************
蜂鸣器
************************************************************/
void delay_ms(uint16 count) // 延时时间count*1ms
{ uint16 i;
for(;count>0;count--)
{
for(i=0;i<110;i++)
{
nop;
}
}
}
/***********************************************************
忙检测
************************************************************/
void LCD1602_check_busy(void)
{
LCD1602_DATA = 0xff;
LCD1602_RS = 0 ;
LCD1602_RW = 1 ;
LCD1602_EN = 1 ;
while(LCD1602_DATA & 0x80) ;
LCD1602_EN = 0 ;
}
/**********************************************************
写指令
************************************************************/
void LCD1602_write_cmd(uint8 cmd)
{
LCD1602_check_busy();
LCD1602_RS = 0 ;
LCD1602_RW = 0 ;
LCD1602_DATA = cmd ;
LCD1602_EN = 1 ;
LCD1602_EN = 0 ;
}
/***********************************************************
写数据
*************************************************************/
void LCD1602_write_data(uint8 dat)
{
LCD1602_check_busy();
LCD1602_RS = 1 ;
LCD1602_RW = 0 ;
LCD1602_DATA = dat ;
LCD1602_EN = 1 ;
LCD1602_EN = 0 ;
}
/***********************************************************
1602初始化
************************************************************/
void LCD1602_init(void)
{
uint8 i ;
LCD1602_write_cmd(0x40);//CGRAM起始地址
for(i=0;i<40;i++)
LCD1602_write_data(self_table1);//写入自定义字符
LCD1602_write_cmd(LCD1602_MODE) ;
LCD1602_write_cmd(LCD1602_ON) ;
LCD1602_write_cmd(LCD1602_ADDR_MODE) ;
LCD1602_write_cmd(LCD1602_CLR) ;
}
/************************************************************
设置显示坐标
************************************************************/
void LCD1602_set_postion(uint8 x , uint8 y)
{
if(y<2)
{
y &= 0x01 ; //y值限定在0~1之间
x &= 0x0f ; //x值限定在0~15之间
if(y == 0)
x |= 0x40 ; //如果显示是在第二行,则x的值加0x40
x |= 0x80 ; //获得x的值
LCD1602_write_cmd(x) ;//写入坐标值到LCD
}
}
/************************************************************
指定位置写字符
*************************************************************/
void LCD1602_write_char(uint8 x , uint8 y , uint8 chardata)
{
LCD1602_set_postion(x,y) ;
LCD1602_write_data(chardata) ;
}
/************************************************************
指定位置写字符串
*************************************************************/
void LCD1602_write_string(uint8 x , uint8 y , uint8 *string)
{
LCD1602_set_postion(x,y) ;
while((*string) != '\0')
{
LCD1602_write_data(*string) ;
string++ ;
}
}
main()
{LCD1602_init(); //初始化
LCD1602_write_string(0,0,"hello"); //在第一行第一列显示hello
LCD1602_write_char(1,1,'f');//在第二行第二列显示f
}
我用的的是一个开发板,电路该没有问题的,而且我自己也看了很多电路,举得硬件问题不是很大,1602液晶的型号是ym1602,时序是按照手册上写的,但是不知道是不是不同型号的1602有不同的时序??
还有我的程序时参照1602的手册写的,不知道哪里出毛病了
自己参照时序图写的难免有错的,你先拿我那段程序试试看,把相应的口线定义改了就行
谢谢大家,我现在已经调试好了,谢谢大家的帮助和支持
#include
#include
#define uchar unsigned char
#define DPORT P0
sbit RS = P3^7 ; //P3_7
sbit RW = P3^6 ;
sbit E = P3^5 ; //p3_5 WR P3_6
#define NODISP 0
#define NOCUR 1
#define CURNOFLASH 2
#define CURFLASH 3
#define CLEARSCREEN 0x01 //清屏控制字
uchar Xpos,Ypos;i;j;
//#define NOP _nop_
/**************Lcd驱动部分函数声明**************************/
void SetCur(uchar c);
void ClearLcd(void);
void ReadStatus(void);
void LcdWriteData(uchar c);
void LcdWriteCommand(uchar c,uchar Busy);
//void LcdPos();
void LcdInit( );
void DispOneChar(uchar x, uchar y,uchar Data);
void DispListChar(uchar x, uchar y,uchar code *Data);
/**************光标(cur)设置命令***************************/
void delay(uchar z)
{
for (i=0;i
for(j=110;j>0;j--);
}
void SetCur( uchar cur )
{
switch( cur )
{
case 0x00:
{
LcdWriteCommand(0x08,1); //LCD关显示
break;
}
case 0x01:
{
LcdWriteCommand(0x0c,1); //LCD开显示但是无光标
break;
}
case 0x02:
{
LcdWriteCommand(0x0e,1); //LCD显示有光标但光标不闪烁
break;
}
case 0x03:
{
LcdWriteCommand(0x0f,1); //LCD开显示光标闪烁
break;
}
default:break;
}
}
/************************************************************/
/**************清屏命令**************************************/
void ClearLcd()
{
LcdWriteCommand(CLEARSCREEN,1);
}
/************************************************************/
/************正常读写前检测LCD控制器处于忙状态?*************/
void ReadStatus()
{
uchar temp;
DPORT=0xff;
RS=0;
RW=1;
/**/
E=0;
E=0;
/**/ //读状态
E=1;
_nop_();
for(;;)
{
temp=DPORT; //读状态控制字
temp&=0x80; //if the station of control word--DPORT^7=0;enable;
if(temp==0)
break;
}
E=0;
}
/************************************************************/
/**************不带忙检测的写字符(数据)子程序****************/
void LcdWriteData(uchar c)
{
DPORT=c;
RS=1; //写数据
RW=0;
E=0; //下降沿表示enable端有效
_nop_();
E=1;
_nop_();
E=0;
}
/************************************************************/
/**************不带忙检测的送控制字子程序********************/
void LcdWriteCommand(uchar c, uchar Busy)
{
if(Busy)
{
ReadStatus();
}
DPORT=c;
RS=0; //写数据
RW=0;
E=0; //下降沿表示enable端有效
_nop_();
E=1;
_nop_();
E=0;
}
/************************************************************/
/**************LcdPos************************************
void LcdPos()
{
uchar temp;
Xpos&=0x0f;
Ypos&=0x01;
temp=Xpos;
if(Ypos==1)
{
temp+=0x40;
}
temp|=0x80; //80h+地址码(2-27h 或者40-67h)
LcdWriteCommand(temp,1); //读写操作
}
************************************************************/
/*************Lcd复位程序************************************/
void LcdInit()
{
delay(15);
LcdWriteCommand(0x38,0);
delay(5);
LcdWriteCommand(0x38,0);
delay(5);
LcdWriteCommand(0x38,0);
LcdWriteCommand(0x38,1);
LcdWriteCommand(0x08,1);
LcdWriteCommand(0x01,1);
LcdWriteCommand(0x06,1);
LcdWriteCommand(0x0c,1);
}
/************************************************************/
/**************LcdDispOneChar(在制定的行和列*******************/
void DispOneChar(uchar x, uchar y, uchar Data)
{
x&=0x0f;
y&=0x01;
if(y==0x01)
{
x|=0x40;
}
x|=0x80; //80h+地址码(2-27h 或者40-67h)
LcdWriteCommand(x,0); //忽略忙信号检测 读写操作
LcdWriteData(Data);
}
/************************************************************/
/**************DispOneChar***********************************/
voidDispListChar(uchar x, uchar y,uchar code *Data)
{
uchar ListLength=0;
x&=0x0f;
y&=0x01;
while(x<16)
{
if(Data[ListLength]==0)
{
break;
}
DispOneChar(x,y,Data[ListLength]);
ListLength++;
x++;
}
}
/************************************************************/
/**************main函数**************************************/
void main(void)
{
uchar code s1[]={"hello world"};
// uchar m;
P2=0x00;
P2=P2|0x60;
delay(500);
LcdInit();
ClearLcd();
SetCur(CURFLASH);
while(1)
{
DispListChar(1,0,s1);
}
}