Ferne214 发表于 2025-3-28 11:07:14

求指教!LCD1602模块的使用

<p>如题,我遇到的问题是这个模块在显示不等长字符的时候,第二行就会错位</p>
<pre><code class="language-c">#define STR1LEN 16
#define STR2LEN 11

bit is500ms = 0;
u8 flag   = 0x00;

// 这两个是不等长的
u8 code str1 = &quot;A test sentence&quot;;
u8 code str2 = &quot;Let's move!&quot;;

void ConfigT0();

void main()
{
    u8 i = 0;
    u8 j = 0;

    ConfigT0();
    // 设置lcd1602为 8bit的两行显示,不显示光标,光标向右移动,屏幕清零
    // 相当于`LcdInit(0x38, 0x0C, 0x06, 0x01);`
    LcdInit(SET_8BIT_2LINE_5X7, NO_CURSOR, CURSOR_RIGHT, CLR_SCREEN);
    while (1) {
      // 定时,每 0.5s 显示一个字符
      if (is500ms) {
            is500ms = 0;
            // 设置为在第一行显示
            LcdSetCursor(i, ROW_1);
            LcdWriteChar(str1);
            i++;
            // STR1LEN - 1 是为了不显示 '\0'
            if (i &gt; STR1LEN - 1) {
                i = 0;
                flag |= (1 &lt;&lt; 0);
            }

            // 设置为在第二行显示
            LcdSetCursor(j, ROW_2);
            LcdWriteChar(str2);
            j++;

            if (j &gt; STR2LEN - 1) {
                j = 0;
                flag |= (1 &lt;&lt; 1);
            }
            // 当两行都显示完之后清屏
            if (flag == 0x03) {
                flag = 0x00;
                LcdWriteCmd(CLR_SCREEN);
            }
      }
    }
}

void ConfigT0()
{
    EA = 1;
    TMOD &amp;= 0xF0;
    TMOD |= 0x01;
    // 10ms
    TH0 = 0xDC;
    TL0 = 0x00;
    TR0 = 1;
    ET0 = 1;
}

void InterruptT0() interrupt 1
{
    static u8 cnt = 0;
    TH0         = 0xDC;
    TL0         = 0x00;

    cnt++;
    if (cnt &gt;= 50) {
      cnt   = 0;
      is500ms = 1;
    }
}

</code></pre>
<p>首先这段代码在第一遍显示的时候没有问题,str1和str2都是从左往右显示的,但是到了第二遍就:</p>
<p><img src="data/attachment/forum/202503/28/110658yiy380exnj8widdy.png" alt="image.png" title="image.png" /></p>
<p>想问下各位大佬有啥比较好的解决方法</p>

Ferne214 发表于 2025-3-28 11:09:28

{:4_164:}不要在意str1和屏幕上显示的不一样,我修改了一下代码,但还没烧录,另外这个是普中的板子(89c52rc)

DebugLab 发表于 2025-3-28 12:26:33

可以用空格补齐
LCD-1602 ST7032例程:
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=16581&pid=155397


DebugLab 发表于 2025-3-28 12:32:10

<pre><code class="language-c">#include &lt;STC8.H&gt;
#include &lt;intrins.h&gt;
#define                LCD1602_RS                P32
#define                LCD1602_EN                P33
#define                LCD1602_D4                P34
#define                LCD1602_D5                P35
#define                LCD1602_D6                P36
#define                LCD1602_D7                P37
#define                Command                                                                0
#define                Data                                                                1
#define                Clear_Display                                                0x01        //Clear_Display
#define                Return_Home                                                        0x02        //Return_Home
#define                Entry_Mode_Cursor_Left                                0x04        //Entry_Mode_Set
#define                Entry_Mode_Entire_Right                                0x05        //Entry_Mode_Set
#define                Entry_Mode_Cursor_Right                                0x06        //Entry_Mode_Set
#define                Entry_Mode_Entire_Left                                0x07        //Entry_Mode_Set
#define                Display_Off                                                        0x08        //Display_ON/OFF
#define                Display_On                                                        0x0c        //Display_ON/OFF
#define                Display_On_Cursor_Off_Blink_On                0x0d        //Display_ON/OFF
#define                Display_On_Cursor_On_Blink_Off                0x0e        //Display_ON/OFF
#define                Display_On_Cursor_On_Blink_On                0x0f        //Display_ON/OFF
#define                Cursor_Move_Left                                        0x10        //Cursor_or_Display_Shift
#define                Cursor_Move_Right                                        0x14        //Cursor_or_Display_Shift
#define                Display_Move_Left                                        0x18        //Cursor_or_Display_Shift
#define                Display_Move_Right                                        0x1c        //Cursor_or_Display_Shift
#define                Setting_Basic_Instruction_Set                0x28        //Function_Set
#define                Setting_Extended_Instruction_Set        0x29        //Function_Set
#define                Function_Set                                                0x38        //Function_Set
#define                Contrast_Set                                                0x78        //Contrast_Set
#define                Internal_OSC                                                0x14        //Internal_OSC
#define                Power_ICON_Contrast                                        0x5e        //Power_ICON_Contrast
#define                Follower_Control                                        0x6a        //Follower_Control
#define                Power_ICON_Contrast                                        0x5e        //Power_ICON_Contrast
unsigned char code Display_Hex={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
unsigned char code Display_Data1=
{
        &quot;LCD_1602_Program&quot;        //0x80
        &quot;Conter:000000000&quot;        //0xc0
};

/*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
void Delay_10us(void)
{
        unsigned char i;
        i=35;
        while(--i);
}

/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
        while(x--)
                Delay_10us();
}

/*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
        unsigned char i,j;
        _nop_();
        _nop_();
        i=144;
        j=157;
        do
        {
                while(--j);
        }
        while(--i);
}

/*----------------------------延时x10ms----------------------------*/
void Delay_x10ms(unsigned char x)
{
        while(x--)
                Delay_10ms();
}

/*----------------------------LCD1602_Enable----------------------------*/
void LCD1602_Enable(void)
{
        LCD1602_EN=1;
        Delay_10us();
        LCD1602_EN=0;
        Delay_10us();
}

/*----------------------------写命令或数据,x=0传送命令,x=1传送数据----------------------------*/
void LCD1602_Write(unsigned char temp,bit x)
{
        LCD1602_RS=x;        //x=0传送命令,x=1传送数据
        LCD1602_D4=temp&amp;0x10;
        LCD1602_D5=temp&amp;0x20;
        LCD1602_D6=temp&amp;0x40;
        LCD1602_D7=temp&amp;0x80;
        LCD1602_Enable();
        LCD1602_D4=temp&amp;0x01;
        LCD1602_D5=temp&amp;0x02;
        LCD1602_D6=temp&amp;0x04;
        LCD1602_D7=temp&amp;0x08;
        LCD1602_Enable();
}

/*----------------------------整页显示字符----------------------------*/
void Display_Text(unsigned char code *addr)
{
        unsigned char i;
        LCD1602_Write(0x80,Command);        //设置DDRAM地址
        Delay_10us();
        for(i=0;i&lt;16;i++)
        {
                LCD1602_Write(*addr,Data);
                addr++;
        }
        LCD1602_Write(0xc0,Command);        //设置DDRAM地址
        Delay_10us();
        for(i=0;i&lt;16;i++)
        {
                LCD1602_Write(*addr,Data);
                addr++;
        }
}

/*----------------------------指定位置显示字符----------------------------*/
void Display_Data(unsigned char x,unsigned char y,unsigned char temp)
{
        switch(y)
        {
                case 0:
                        LCD1602_Write(0x80+x,Command);        //设置DDRAM地址
                        Delay_10us();
                        LCD1602_Write(temp,Data);
                        break;
                case 1:
                        LCD1602_Write(0xc0+x,Command);        //设置DDRAM地址
                        Delay_10us();
                        LCD1602_Write(temp,Data);
                        break;
        }
}

/*----------------------------初始化LCD1602----------------------------*/
void LCD12864_Init(void)
{
        Delay_10ms();
        Delay_10ms();
        Delay_10ms();
        Delay_10ms();                //延时40ms
//        LCD1602_Write(Function_Set,Command);                                                //Function_Set
//        Delay_x10us(200);        //延时2ms
//        LCD1602_Write(Function_Set,Command);                                                //Function_Set
//        Delay_x10us(3);                //延时3us
        LCD1602_Write(Function_Set,Command);                                                //Function_Set
        Delay_x10us(3);                //延时3us
        LCD1602_Write(Setting_Basic_Instruction_Set,Command);                //Setting_Basic_Instruction_Set
        Delay_x10us(3);                //延时3us
        LCD1602_Enable();
        LCD1602_Write(Setting_Extended_Instruction_Set,Command);        //Setting_Extended_Instruction_Set
        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Cursor_Move_Right,Command);                                        //Cursor_Move_Right
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Contrast_Set,Command);                                                //Contrast_Set
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Internal_OSC,Command);                                                //Internal_OSC
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Power_ICON_Contrast,Command);                                        //Power_ICON_Contrast
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Follower_Control,Command);                                        //Follower_Control
//        Delay_x10ms(20);        //延时200ms
        LCD1602_Write(Display_On,Command);                                                        //Display_On
        Delay_x10us(3);                //延时3us
        LCD1602_Write(Clear_Display,Command);                                                //Clear_Display
        Delay_x10us(200);        //延时2ms
//        LCD1602_Write(Entry_Mode_Cursor_Right,Command);                                //Entry_Mode_Cursor_Right
//        Delay_x10us(3);                //延时3us
}

void main(void)
{
        unsigned int a=0,b=0;
        LCD12864_Init();
        while(1)
        {
                Display_Text(Display_Data1);
                while(1)
                {
                        Display_Data(7,1,Display_Hex);
                        Display_Data(8,1,Display_Hex);
                        Display_Data(9,1,Display_Hex);
                        Display_Data(10,1,Display_Hex);
                        Display_Data(11,1,Display_Hex);
                        Display_Data(12,1,Display_Hex);
                        Display_Data(13,1,Display_Hex);
                        Display_Data(14,1,Display_Hex);
                        Display_Data(15,1,Display_Hex);
                        b++;
                        if(b&gt;=10000)
                        {
                                b=0;
                                a++;
                        }
                }
        }
}
</code></pre>

Ferne214 发表于 2025-3-28 15:23:58

DebugLab 发表于 2025-3-28 12:26
可以用空格补齐
LCD-1602 ST7032例程:
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&p ...

{:4_197:}我尝试过这个方案,确实可行,但我在想有没有不使用空格的方案。大佬你试过吗?

DebugLab 发表于 2025-3-28 15:49:09

Ferne214 发表于 2025-3-28 15:23
我尝试过这个方案,确实可行,但我在想有没有不使用空格的方案。大佬你试过吗? ...

先设置地址显示一行,再设置地址显示另一行,不要放在一个循环里

Ferne214 发表于 2025-3-28 16:06:47

DebugLab 发表于 2025-3-28 15:49
先设置地址显示一行,再设置地址显示另一行,不要放在一个循环里

{:4_183:}好的,我整整
页: [1]
查看完整版本: 求指教!LCD1602模块的使用