chenxiujing 发表于 2008-7-28 13:56:58

我的1602四线驱动不知到为什么就是显示不出来?请各位大虾帮帮忙!

我搞1602四线驱动,调试了很久但就是显示不出来,请各位高手帮帮忙,谢谢!


程序如下(用Mega16做的):
#include<ioM16v.h>
#include <macros.h>

/*------宏定义------*/
#define uchar        unsigned char
#define uint        unsigned int


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();
}


//******************用这个驱动时只须修改下面端口设置*************************/
/*********************************************************************/
#defineLM_E   3             //pA3
#defineLM_RW2             //PA2
#defineLM_RS1             //pA1
#defineDATAPORT    PORTA    //数据口PA4/5/6/7
/*********************************************************************/

#defineSET_LM_E( )    (PORTA|=(1<<LM_E))      //E=1
#defineCLR_LM_E( )    (PORTA&=(~(1<<LM_E)))   //E=0
#defineSET_LM_RW( )   (PORTA|=(1<<LM_RW))       //RW=1
#defineCLR_LM_RW( )   (PORTA&=(~(1<<LM_RW )))   //RW=0
#defineSET_LM_RS( )   (PORTA|=(1<<LM_RS))       //RS=1
#defineCLR_LM_RS( )   (PORTA&=(~(1<<LM_RS)))    //RS=0
#defineSET_LM_DDR( )       DDRA|=0xf0;
#defineCLR_LM_DDR( )       DDRA&=0x0f;
#defineSET_LM_DataPORT( )PORTA|=0xf0;
#defineCLR_LM_DataPORT( )PORTA&=0x0f;

/*********************************************************************/

///////////////液晶驱动程序初始化/////////////////////////////////////
/////
const uchar NoDisp=0;//无显示
const uchar NoCur =1;//有显示无光标
const uchar CurNoFlash=2;//有光标但不闪
const uchar CurFlash=3;//有光标且闪烁

void LcdPos(uchar,uchar);//确定光标位置
void LcdWd (char);//写字符
void LcdWc (uchar);//送控制字(检测忙信号)
void LcdWcn (uchar);//送控制字(不检测忙信号)

void WaitIdle(void);//检测忙信号
void RstLcd( void);//复位
void ClrLcd( void);//清屏
void SetCur(uchar Para);//设置光标
void WriteChar(char c,uchar xPos,uchar yPos);//显示字符
void WriteString(char *s,uchar xPos,uchar yPos);//显示字符串

///////////////液晶驱动程序//////////////////////////////////////////////


void WriteChar(char c,uchar xPos,uchar yPos)
    //显示字符
{
LcdPos(xPos,yPos);
LcdWd(c);
}
//////////youwenti/////////////////////////////////////////////////////////
void WriteString(char *s,uchar xPos,uchar yPos)
    //显示字符串
{
uchar i =0;
if(*s=='\0')
return;
for(i=0;;i++)
{
if(*(s+i)=='\0')
break;
WriteChar(*(s+i),xPos,yPos);
xPos++;
if(xPos>15)
break;
}
}
////////////////////////////////////////////////////////////////////////////
void SetCur(uchar Para)
   //设置光标
{
delay_nms(10);
switch (Para)                                    
{
   case 0:
   {
   LcdWc(0x08);//关显示NoDisp
   break;
   }
   case 1:
   {
    LcdWc(0x0c);//开显示但无光标 NoCur
    break;
   }
   case 2:
   {
   LcdWc(0x0e);//开显示有光标但不闪烁CurNoFlash
   break;
   }
   case 3:
   {
   LcdWc(0x0f);//开显示有光标且闪烁CurFlash
   break;
   }
   default:break;
}
}
////////////////////////////////////////////////////////////////////
void ClrLcd(void)//清屏函数
{
LcdWc(0x01);
}
///////////////////////////////////////////////////////////?
void WaitIdle(void)//检测忙信号

{
char temp,i=0;
CLR_LM_RS( );//RS=0
SET_LM_RW( );//RW=1
delay_nus(2);
CLR_LM_DDR( );//设置为输入
CLR_LM_DataPORT();//清高四位
SET_LM_E() ;//E=1
delay_nus(2);
for( ; ; )
{
delay_nus(3);
temp=PINA;
if(i==0)
{
temp &=0x80;
if(temp==0)
break;
i=1;
}
else
i=0;
}
SET_LM_DDR( );//置高四位为1
CLR_LM_E( ) ;//E=0
}

//////////////////////////////////////////////////////////////////////?
void LcdWd(char c)
            //写字符
{
WaitIdle();
SET_LM_RS();//RS=1
CLR_LM_RW();//RW=0
delay_nus(2);
CLR_LM_DataPORT( );//清高四位
DATAPORT|=c&0xf0; //写高四位
delay_nus(2);
SET_LM_E();//E=1
delay_nus(2);
CLR_LM_E() ;//E=0


c=c<<4;//低四位移到高四位
delay_nus(2);
CLR_LM_DataPORT( ) ;//清高四位
DATAPORT|=c&0xf0; //写低四位
delay_nus(2);
SET_LM_E();//E=1
delay_nus(2);
CLR_LM_E() ;//E=0
}
////////////////////////////////////////////////////////////////
void LcdWc(uchar c)//送控制字(检测忙信号)
{
WaitIdle();
LcdWcn(c);
}

void LcdWcn(uchar c)//送控制字(不检测忙信号)//////////?
{
CLR_LM_RS();//RS=0
CLR_LM_RW();//RW=0
delay_nus(2);
CLR_LM_DataPORT() ;//清高四位
DATAPORT|=c&0xf0; //写高四位
delay_nus(2);
SET_LM_E();//E=1
delay_nus(2);
CLR_LM_E() ;//E=0
delay_nus(1);


c=c<<4;//低四位移到高四位
delay_nus(2);
CLR_LM_DataPORT() ;//清高四位
DATAPORT|=c&0xf0; //写低四位
delay_nus(2);
SET_LM_E();//E=1
delay_nus(2);
CLR_LM_E() ;//E=0
delay_nus(1);   
}
/////////////////////////////////////////////////////////////////
void LcdPos(uchar xPos,uchar yPos)//确定光标位置
{
unsigned char tmp;
xPos &=0x0f;
yPos &=0x01;
if(yPos==0)
tmp=xPos;
else
tmp=xPos+0x40;
tmp|=0x80;
LcdWc(tmp);
   }
///////////////??????难点??????????////////////

void LcdPosCGRAM(uchar xPos)//CGRAM地址设置
{
LcdWc(xPos|0x40);
}

void WriteCharCGRAM(char a[],uchar xPos)
                                       //创建一个字符,
{
char i;
WaitIdle();
for(i=0;i<8;i++)
{
LcdPosCGRAM(xPos);
LcdWd(a);
xPos++;
}
}
/////////////////////??????难点???????????/////////
////////////////////////////////////////////////////////////////
void display09(char a,char x,char y)//显示0~9字符
{
switch(a)
   {
   case 0:SetCur(NoCur); delay_nus(2); WriteChar('0',x,y);break;
   case 1:SetCur(NoCur); delay_nus(2); WriteChar('1',x,y);break;
   case 2:SetCur(NoCur); delay_nus(2); WriteChar('2',x,y);break;
   case 3:SetCur(NoCur); delay_nus(2); WriteChar('3',x,y);break;
   case 4:SetCur(NoCur); delay_nus(2); WriteChar('4',x,y);break;
   case 5:SetCur(NoCur); delay_nus(2); WriteChar('5',x,y);break;
   case 6:SetCur(NoCur); delay_nus(2); WriteChar('6',x,y);break;
   case 7:SetCur(NoCur); delay_nus(2); WriteChar('7',x,y);break;
   case 8:SetCur(NoCur); delay_nus(2); WriteChar('8',x,y);break;
   case 9:SetCur(NoCur); delay_nus(2); WriteChar('9',x,y);break;
   default:break;
   }
}
/////////////////////////////////////
void RstLcd(void)//复位
{

LcdWc(0x28);//四位数据,显示两行,5*7
delay_nms(5);
LcdWc(0x08);//关显示
delay_nms(5);
LcdWc(0x01);//清屏
delay_nms(5);
LcdWc(0x06);//光标右移一格,AC加1
delay_nms(5);
LcdWc(0x0c);//开显示但无光标

}
///////////////////////液晶驱动程序///////////////////////////////////////////

//端口初始化
void port_init(void)
{
PORTA = 0xff;
DDRA= 0xff;
}
//初始化函数
void init_devices(void)
{
CLI( ); //禁止所有中断
port_init();
SEI( );//开全局中断
}
///字库数组
char temp[]={0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00};//创建“日”字

//主函数
void main(void)
{
init_devices( );
RstLcd( );
delay_nus(5);
ClrLcd( );
SetCur(1);
delay_nus(5);
WriteChar('J',0,1);//显示字符
WriteString("xie xie ",1,1);//显示字符串
WriteCharCGRAM(temp,0);//创建一个字符
//在这继续添加你的代码
WriteChar(0,0,0);//显示自创字符时,char c用0~7数字代替
while(1)
{
;
}
}

macchange 发表于 2008-7-30 17:11:17

楼主搞定了麽、?我也搞了好久没出结果啊。。
哎!!!

sjzd 发表于 2008-7-30 18:24:03

论坛里搜

chenxiujing 发表于 2008-8-3 14:00:58

还没搞好啊!

yunlongAVR 发表于 2009-6-6 21:30:14

LZ搞好没有啊?我也没搞好。
论坛里关于4线驱动的我几乎都看过了,有的用软件仿真,有的直接硬件运行,有的算数左移,有的算术右移,管脚也对不上,看了半天没什么收获,郁闷啊。

lq20434 发表于 2009-6-6 21:45:56

试过,对比度的问题没有?

yunlongAVR 发表于 2009-6-6 22:17:55

对比度就是调那颗电阻而矣啊。

AAVVRR 发表于 2009-6-6 22:53:39

1602使用时首先要初始化,例如:
void LCD_init(void)
{
      LCD_DDR=0xfe;         //设7654321为输出,0 as rxd in
      (PORTx&=(~(1<<RW)))   //设为W状态
      _delay_ms(100);
      write_command(0x38);
      _delay_ms(40);          //AT 1MHZ 30;NOW 2MHZ ,40
      write_command(0x38);
      _delay_ms(40);
        write_command(0x38);

      write_command(0x28);
        write_command(0x08);
        write_command(0x0c);//显示开--对应开关显示控制指令
      write_command(0x01);//清屏--对应清屏指令
        write_command(0x0C);
        write_command(0x80);
      _delay_ms(20);         //delay
}
其中   write_command(0x38);
      _delay_ms(40);          //AT 1MHZ 30;NOW 2MHZ ,40
      write_command(0x38);
      _delay_ms(40);
        write_command(0x38);
不可或缺,延时时间按照主频调整,1M30即可,2M要加到40,这个完全是个人经验摸索了好几次的,初始化不对就出现黑快。我现在也是4线的MEGA8,PD7..4数据线,本来PD2..0做控制线即可,但因为串口占用,不得已就用PC2..0做控制线。

lycreturn 发表于 2012-11-1 22:17:45

初始化 write_command(2); 就可以了 也可以write_command(0x12); write_command(0x32); 0x42~0xf2都是可以的

www1519 发表于 2012-11-1 22:21:44

http://www.amobbs.com/thread-5503804-1-1.html
页: [1]
查看完整版本: 我的1602四线驱动不知到为什么就是显示不出来?请各位大虾帮帮忙!