自己写了一个1602的程序,在Proteus上仿真没有问题,但在自己焊的板子上就出现无法初始化的问题,只能显示一行16个黑色方块。这是1602的程序,请各位高手指点一下。
/*-----------------------------------------------------------------
*名称:LCD1602.h
*日期:2013.7.29
*引脚定义:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
------------------------------------------------------------------*/
#include "1602.h"
//定义端口
sbit RS=P2^7; //LCD数据/命令端
sbit RW=P2^6; //LCD读/写端
sbit EN=P2^5; //LCD使能端
#define DataPort P0 //LCD数据端口
//宏定义
#define RS_CLR RS=0 //LCD指向命令寄存器
#define RS_SET RS=1 //LCD指向数据寄存器
#define RW_CLR RW=0 //LCD读操作
#define RW_SET RW=1 //LCD写操作
#define EN_CLR EN=0 //LCD关闭
#define EN_SET EN=1 //LCD使能
uchar flag; //LCD状态标志
uchar dis_buf[5]; //显示缓冲区
uchar code dis[]={"0123456789."}; //显示代码
/*****************************************************
5ms延时
*****************************************************/
void Delay5Ms(void)
{
uint i=5552;
while(i--);
}
/*****************************************************
10us延时
*****************************************************/
void Delay10us(n)
{
uint i;
for(i=0;i<n;i++)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
/******************************************************
LCD1602状态检测
******************************************************/
void Lcd_Check_Busy(void)
{
flag=0x80;
while(flag & 0x80)
{
DataPort=0xff;
RS_CLR;
RW_SET;
_nop_();
EN_SET;
_nop_();
flag=DataPort;
_nop_();_nop_();_nop_();
EN_CLR;
}
}
/*******************************************************
LCD1602写指令
*******************************************************/
void Write_Lcd_Command(uchar Com_Code,uchar Check_By)
{
if (Check_By)
Lcd_Check_Busy();
RS_CLR;
RW_CLR;
_nop_();
DataPort=Com_Code;
_nop_();
EN_SET;
_nop_();
_nop_();
_nop_();
_nop_();
EN_CLR;
}
/********************************************************
LCD1602写数据
********************************************************/
void Write_Lcd_Data(uchar dat)
{
Lcd_Check_Busy();
RS_SET;
RW_CLR;
_nop_();
DataPort=dat;
_nop_();
EN_SET;
_nop_();
_nop_();
_nop_();
_nop_();
EN_CLR;
}
/********************************************************
LCD1602初始化
********************************************************/
void Lcd_Init()
{
Delay5Ms(); Delay5Ms();Delay5Ms();Delay5Ms();
Write_Lcd_Command(0x38,0); //显示模式设置(不检测忙信号)
Delay5Ms();Delay5Ms();Delay5Ms();
Write_Lcd_Command(0x38,0);
Delay5Ms();Delay5Ms();Delay5Ms();
Write_Lcd_Command(0x38,1); //显示模式设置(检测忙信号)
Write_Lcd_Command(0x08,1); //显示关闭(检测忙信号)
Write_Lcd_Command(0x01,1); //显示清屏(检测忙信号)
Write_Lcd_Command(0x06,1); //输入模式设置(检测忙信号)
Write_Lcd_Command(0x0c,1); //显示及光标设置(检测忙信号)
}
/*********************************************************
LCD1602显示定位
*********************************************************/
void Lcd_Start(uchar start)
{
Write_Lcd_Command(start|0x80,1);
}
/*********************************************************
LCD1602数据调整
*********************************************************/
uchar Dat_Adj(uint dat)
{
uchar i;
dis_buf[0]=(uchar)(dat/1000%10);
dis_buf[1]=(uchar)((dat%1000)/100);
dis_buf[2]=(uchar)((dat%100)/10);
dis_buf[3]=10;
dis_buf[4]=(uchar)(dat%10);
for(i=0;i<2;i++)
{
if(dis_buf[i]!=0)
break;
}
return(i);
}
/*********************************************************
LCD1602显示字符
*********************************************************/
void Lcd_Disp_Char(uint dat,uchar loca)
{
uchar temp,j;
temp=Dat_Adj(dat);
Lcd_Start(loca+temp);
for(j=temp;j<5;j++)
Write_Lcd_Data(dis[dis_buf[j]]);
}
/**********************************************************
LCD1602显示字符串
**********************************************************/
void Lcd_Disp_Str(uchar *str)
{
while(*str!='\0')
{
Write_Lcd_Data(*str);
str++;
}
} |