huangyiting1990 发表于 2014-8-11 23:11:23

STC驱动LCD1602无果,求助

自己写的驱动程序,连个LCD都点不亮呀。贴出来,做回伸手党!{:lol:}

#include<reg51.h>
#include<intrins.h>

sbit RSPIN = P2^6;
sbit RWPIN = P2^7;
sbit EPIN = P3^7;

unsigned char XPOS,YPOS;

void delay(unsigned int t)
{unsigned int i,j;
   for(i=0;i<t;i++)
      for(j=0;j<10;j++)
         ;
}

void lcdwaitidle(void)
{P0=0xff;
   RSPIN=0;
   RWPIN=1;
   EPIN=1;
   while((P0&0x80)==0x80);
   EPIN=0;
}

void lcdwcn(unsigned char c)
{RSPIN=0;
   RWPIN=0;
   P0=c;
   EPIN=1;
   _nop_();
   EPIN=0;
}

void lcdwc(unsigned char c)
{lcdwaitidle();
   lcdwcn(c);
}

void lcdwd(unsigned char d)
{lcdwaitidle();
   RSPIN=1;
   RWPIN=0;
   P0=d;
   EPIN=1;
   _nop_();
   EPIN=0;
}

void lcdpos(void)
{XPOS&=0x0f;
   YPOS&=0x03;
   if(YPOS==0x00)
      lcdwc(XPOS|0x80);
   else if(YPOS==0x01)
      lcdwc((XPOS+0x40)|0x80);
}

void lcdreset()
{delay(150); lcdwcn(0x38);
   delay(50); lcdwcn(0x38);
   delay(50); lcdwcn(0x38);
   lcdwc(0x38);
   lcdwc(0x08);
   lcdwc(0x01);
   lcdwc(0x06);
   lcdwc(0x0c);
}

void lcdfill(unsigned char n)
{
   for(YPOS=0;YPOS<2;YPOS++)
      for(XPOS=0;XPOS<16;XPOS++)
      {lcdpos();
         lcdwd(n);}
}

void lcdwda(unsigned char x,unsigned char y,unsigned char *s)
{YPOS=y;
   for(XPOS=x;XPOS<16;XPOS++)
   {lcdpos();
      lcdwd(*s);
      s++;
      delay(400);
   }
}

main()
{unsigned char i;
   EPIN=0;
   while(1)
   {lcdreset();
      for(i=0x30;i<=0x3a;i++)
      {lcdfill(i);
         delay(3500);
      }
      lcdfill(' ');
      delay(2000);
      lcdwda(0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
      //lcdwda(0,1,"ZYXWVUTSRQPONMLKJIHGFEDCBA");
      delay(2000);
   }
}

liangd123654 发表于 2014-8-11 23:24:17

看样子像是对比度不大对。

ackk 发表于 2014-8-11 23:28:08

调一下对比度

饭桶 发表于 2014-8-11 23:35:24

对比度电位器用两个10K代替不行,还不如1个1K接地呢。另外你芯片是哪个,89系列的P0需要上拉电阻的。如果是你现在那个LE型号,液晶不一定在3V下驱动起来,一般都是5V的,仅供参考。

i7gly 发表于 2014-8-11 23:38:34

搞屁啊,你单片机根本没P0,你愣是在程序上写了P0,,,IO都不对应怎么显示?

huangyiting1990 发表于 2014-8-11 23:39:57

饭桶 发表于 2014-8-11 23:35
对比度电位器用两个10K代替不行,还不如1个1K接地呢。另外你芯片是哪个,89系列的P0需要上拉电阻的。如果是 ...

芯片用的是STC12C5628AD对比度没调好?换成1K接地?{:lol:}

电子喵星人 发表于 2014-8-11 23:44:37

“自己写的驱动程序,连个LCD都点不亮呀”


"代码是坛子里下载的"

huangyiting1990 发表于 2014-8-11 23:51:11

i7gly 发表于 2014-8-11 23:38
搞屁啊,你单片机根本没P0,你愣是在程序上写了P0,,,IO都不对应怎么显示?

复制坛子上的代码忘了改了,但是写的时候该成了P1 现象就是这样{:lol:}

huangyiting1990 发表于 2014-8-11 23:52:05

电子喵星人 发表于 2014-8-11 23:44
“自己写的驱动程序,连个LCD都点不亮呀”




之前是自己写的,驱动不了。现在用坛子里下载的修改了 还是驱动部了{:lol:}

lxa0 发表于 2014-8-11 23:53:24

楼主的这个现象我碰到过
是因为rs,r/w,e的时序不对造成的

i7gly 发表于 2014-8-11 23:53:36

huangyiting1990 发表于 2014-8-11 23:51
复制坛子上的代码忘了改了,但是写的时候该成了P1 现象就是这样

#include <iostm8s208mb.h>
#include "lcd1602.h"
#include "main.h"

/************IO映射***********
RW-> PG6
RS-> PG7
E   -> PG5
DATA -> PI
*****************************/

#define LCD_DATA PI_ODR
#define SET_RW    PG_ODR |= BIT6
#define RESET_RWPG_ODR &= ~BIT6
#define SET_RS    PG_ODR |= BIT7
#define RESET_RSPG_ODR &= ~BIT7
#define SET_EN    PG_ODR |= BIT5
#define RESET_ENPG_ODR &= ~BIT5


const unsigned char num_table[]="0123456789ABCDEF";

/***********底层控制函数**************/

void LCD_Delay(unsigned char x)
{
while(x--);
}

void Write_Com(unsigned char wcom)
{
SET_EN;
RESET_RS;
RESET_RW;
LCD_DATA = wcom;
LCD_Delay(50);
RESET_EN;
}

void Write_Data(unsigned char wdata)
{   
SET_EN;
SET_RS;
RESET_RW;
LCD_DATA = wdata;
LCD_Delay(50);
RESET_EN;
}


//LCD初始化函数
void Lcd1602_Init(void)
{
/************IO Init**************/
PG_DDR|= (BIT5 + BIT6 + BIT7);
PG_CR1|= (BIT5 + BIT6 + BIT7);
PG_CR2|= ~(BIT5 + BIT6 + BIT7);
PI_DDR= 0xff;
PI_CR1= 0xff;
PI_CR2= 0x00;

//Write_Com(0x01);
Write_Com(0x06);//
Write_Com(0x0c);//开显示屏
Write_Com(0x38);//8位传送数据 2行显示
}

//显示字符串
//起始位置x,y对应屏幕字符位置,字符串由指针带入
//y=0 or 1,大于则舍去,x>15则舍去
//自动换行,多出字符舍去
void Display_Char(unsigned char x , unsigned char y , unsigned char* pchar)
{
if(y>1 || x>15)return;      //超出显示区域
if(y==1)x += 0x40;          //计算换行地址
x += 0x80;                  //加上首地址
Write_Com(x);               //写入地址
while(*pchar != '\0')       //写入字符串
{
    if((x > 0x8F) && (y != 1))            //0x8F = 0x80+15,也就是第一行最后一位
    {
      x= 0x80 + 0x40;         //地址重新指向第二行
      Write_Com(x);         //写入第二行地址,显示从第二行重新开始
      y=1;                  //已经显示到第二行了,防止重复判断
    }
    if(x > 0xCF)break;      //0xCF = 0x80 + 0x40 + 15 第二行最后一位,超出后就退出了.
   
    Write_Data(*pchar);       //写入字符
    pchar++;                  //指针递增
    x++;                      //地址+1,用于计算自动换行或超长退出操作
}
}

//十进制显示1Byte的数字,占用3个字符位,想占用两位的去找Display_Hex_8bit()
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Number_8bit(unsigned char x , unsigned char y , unsigned char num)
{
    if(y>1 || x>15)return;      //超出显示区域
    if(y==1)x += 0x40;          //计算换行地址
    Write_Com(0x80 + x);      //写入地址
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
}

//十进制显示2Byte的数字,占用5个字符位,想占用4位的去找Display_Hex_16bit()
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Number_16bit(unsigned char x , unsigned char y , unsigned int num)
{
    if(y>1 || x>15)return;      //超出显示区域
    if(y==1)x += 0x40;          //计算换行地址
    Write_Com(0x80 + x);      //写入地址
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
}

//十六进制显示1Byte的数字,占用2个字符位置
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Hex_8bit(unsigned char x , unsigned char y , unsigned char num)
{
    if(y>1 || x>15)return;      //超出显示区域
    if(y==1)x += 0x40;          //计算换行地址
    Write_Com(0x80 + x);      //写入地址
    Write_Data(num_table);
    Write_Data(num_table);
}

//十六进制显示2Byte的数字,占用4个字符位置
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Hex_16bit(unsigned char x , unsigned char y , unsigned int num)
{
    if(y>1 || x>15)return;      //超出显示区域
    if(y==1)x += 0x40;          //计算换行地址
    Write_Com(0x80 + x);      //写入地址
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
    Write_Data(num_table);
}

//清除显示域
void LCD_Clear(void)
{
unsigned char x;
Write_Com(0x80);
for(x=0;x<16;x++)
    Write_Data (' ');
Write_Com(0x80+0x40);
for(x=0;x<16;x++)
    Write_Data (' ');
}


给你一份我写的,修改头文件,修改管脚宏定义,修改Init函数里面的管脚初始化就能用了

i7gly 发表于 2014-8-11 23:55:08

    Display_Char(0,0,"Midy Studio !!!");
    Display_Hex_8bit(0,0,temp);
    Display_Number_8bit(0,1,temp);
    Display_Hex_16bit(4,0,num);
    Display_Number_16bit(4,1,num);

这样调用

huangyiting1990 发表于 2014-8-11 23:57:07

i7gly 发表于 2014-8-11 23:55
这样调用

{:lol:} 行,我再试试

电子喵星人 发表于 2014-8-11 23:57:58

论坛上代码是12t速度单片机 你这个是1t速度单片机延时要调试

huangyiting1990 发表于 2014-8-11 23:58:01

lxa0 发表于 2014-8-11 23:53
楼主的这个现象我碰到过
是因为rs,r/w,e的时序不对造成的

明天再用逻辑分析抓波试试{:lol:}

饭桶 发表于 2014-8-12 00:01:44

对比度的问题,最好用电位器调。

huangyiting1990 发表于 2014-8-12 00:02:18

饭桶 发表于 2014-8-12 00:01
对比度的问题,最好用电位器调。

10K电位器?

lcl 发表于 2014-8-12 00:07:05

huangyiting1990 发表于 2014-8-11 23:58
明天再用逻辑分析抓波试试

我勒个去    还抓波    贴你个源代码

lcl 发表于 2014-8-12 00:08:05

本帖最后由 lcl 于 2014-8-12 00:31 编辑

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0;
sbit rw=P1^1;
sbit lcden=P2^5;



uchar table1[]="NI DA YE DE MAO";
uchar table2[]="WWW.BAIDU.COM";


void delay(uint x)
{
        uint a,b;
        for(a=x;a>0;a--)
                for(b=10;b>0;b--);
}



void delay1(uint x)
{
        uint a,b;
        for(a=x;a>0;a--)
                for(b=100;b>0;b--);
}



void write_com(uchar com)
{
        P0=com;
        rs=0;
        lcden=0;
        delay(10);
        lcden=1;
        delay(10);
        lcden=0;
       
}



void write_date(uchar date)
{
        P0=date;
        rs=1;
        lcden=0;
        delay(10);
        lcden=1;
        delay(10);
        lcden=0;
       
}



void init()
{
      
      rw=0;
        dula=0;
        wela=0;
        write_com(0x38);   //显示模式设置:16×2显示,5×7点阵,8位数据接口
        delay(20);
        write_com(0x0f);   //显示模式设置
        delay(20);
        write_com(0x06);   //显示模式设置:光标右移,字符不移
        delay(20);
        write_com(0x01);   //清屏幕指令,将以前的显示内容清除
        delay(20);       
}



void main()
{
      
        uchar a;
        init();
        write_com(0x80+17);       //将第一个字符写在向右偏移17个字符处,为后面的由右向左划入做准备。
        delay(20);
        for(a=0;a<13;a++)
        {
        write_date(table1);
        delay(20);               
        }

        write_com(0xc0+17);
        delay(50);
        for(a=0;a<13;a++)
        {
        write_date(table2);
        delay(40);               
        }

        for(a=0;a<16;a++)
        {
                write_com(0x18); //左移
                delay1(600);
        }

        while(1);
}

rain73 发表于 2014-8-12 00:47:08

估计就是1T与12T的问题...

二师兄 发表于 2014-8-12 10:28:53

正准备搞这个,先来看看

honeybear 发表于 2014-8-12 11:25:51

用示波器抓一下信号,信号没有给对就是这个现象

deiwgah 发表于 2014-8-12 11:54:48

对比度引脚悬空试试,我经常悬空,就是会比较暗,但是能看到字符
页: [1]
查看完整版本: STC驱动LCD1602无果,求助