【求助】单片机 LCD1602 不显示

2019-07-15 17:20发布

弄了一天写的程序,但LCD不能显示,想请大神帮我看看,问题出在哪里,真的让我特糟心,求解答,感谢;程序里面有1个警告,但总体来说不影响运行;

#include<reg51.h>
sbit RS=P2^5;
sbit RW=P2^6;
sbit E=P2^7;
sbit D0=P0^0; //教程中没有定义P0口的关系,需要验证;
sbit D1=P0^1;
sbit D2=P0^2;
sbit D3=P0^3;
sbit D4=P0^4;
sbit D5=P0^5;
sbit D6=P0^6;
sbit D7=P0^7;
//延时函数;
void LCD1602_delay(unsigned int n)
{
unsigned int m;
for(m=0;m<n;m++);
}
//写数据函数;
void write_data(unsigned char data_input)
{
RS=1;
RW=0;
P0=data_input;
E=1;
E=0; //一次高脉冲结束;
}
//写指令函数;
void write_request(unsigned char request_input)
{
RS=0;
RW=0;
P0=request_input;
E=1;
E=0;
}
//读状态函数;
void read_state(void)
{
RS=0;
RW=1;
P0=0xff;
E=1;
while(P0^7==1);
E=0;
}
//尝试读数据函数;


//包含状态监测的写指令函数;
void write_request_busy(unsigned char request_input)
{
read_state(); //如果P0_7=1则表示忙,则一直循环,直到P0_7=0;
RS=0;
RW=0;
P0=request_input;
E=1;
E=0;
}
//包含状态监测的写数据函数;
void write_data_busy(unsigned char data_input)
{
read_state();
RS=1;
RW=0;
P0=data_input;
E=1;
E=0; //一次高脉冲结束;
}
//调用地址码函数;
void LCD1602_adddress(unsigned char x, unsigned char y)
{
if(y==0)
write_request_busy(0x80+x);
else
write_request_busy(0x80+0x40+x);
}
//显示数据函数;
void LCD1602_printf(unsigned char x, unsigned char y, unsigned char data_input) //把unsigned char data_input 更换为unsigned int data_input后看是否会有影响;
{
LCD1602_adddress(x,y);
write_data_busy(data_input);
}

//初始化函数;
void LCD1602_init(void)
{
LCD1602_delay(15000);
write_request(0x38);
LCD1602_delay(5000);
write_request(0x38);
LCD1602_delay(5000);
write_request(0x38);
write_request_busy(0x38);
write_request_busy(0x08);
write_request_busy(0x01);
write_request_busy(0x06);
write_request_busy(0x0c);
}
void main(void)
{
LCD1602_init();
LCD1602_printf(0,0,'1');
while(1)
{
}
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
a410670107
2019-07-16 04:40
我这有个能运行的例子:
#include<reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit RS=P2^5;
sbit RW=P2^6;
sbit EN=P2^7;
sbit BUSY=P0^7;
code uint8 word1[]={"  Welcome to    "};
code uint8 word2[]={"  MCU world     "};

void delay(uint16 del)
{
        uint16 i,j;
        for(i=0;i<del;i++)
        for(j=0;j<=148;j++);
}

/******等待繁忙标志********/
void wait()
{
        P0=0xff;
        do
        {
                RS=0;
                RW=1;
                EN=0;
                EN=1;
        }while(BUSY==1);
        EN=0;
}
/*****写数据*******/
void w_dat(uint8 dat)
{
        wait();
        EN=0;
        P0=dat;
        RS=1;
        RW=0;
        EN=1;
        EN=0;
}                                          
/***********写命令************/
void w_cmd(uint8 cmd)
{
        wait();
        EN=0;
        P0=cmd;
        RS=0;
        RW=0;
        EN=1;
        EN=0;
}

/********************************************************************
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
                 L1602_sign(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_sign(uint8 hang,uint8 lie,char sign)
{
        uint8 a;
        if(hang == 1) a = 0x80;
        if(hang == 2) a = 0xc0;
        a = a + lie - 1;
        w_cmd(a);
        w_dat(sign);
}

/********发送字符到LCD**********/
void w_string(uint8 addr_start,uint8 *p)
{
        w_cmd(addr_start);
        while(*p!='')
        {
                w_dat(*p++);
        }
}
/**********1602初始化*********/
void init_lcd1602()
{
        w_cmd(0x38);
        w_cmd(0x08);
        w_cmd(0x0c);
        w_cmd(0x04);
        w_cmd(0x01);
}                          

main()
{
        uint8 *a,*b,i,j;
        init_lcd1602();
        while(1)
        {
                a=word1;
                b=word2;
                for(i=0;i<17;i++)
                {
                        for(j=0;j<i;j++)
                        {
                                L1602_sign(1,17-i+j,*(a+j));
                                L1602_sign(2,17-i+j,*(b+j));       
                        }
                        delay(200);
                }
                delay(2000);
                w_cmd(0x01);
        }
}

一周热门 更多>