2

我们有一个字符 LCD (www.cloverlcd.com/pdf/S6A0069.pdf),我们必须在 8 位模式下工作。然而,现在我们正试图让它在 4 位模式下工作,但它似乎没有显示任何内容。我认为没有编写功能集指令。有人可以检查我是否以正确的方式接近这个?我将发布我的 8 位代码(正在工作)和我的 4 位代码(我正在尝试开始工作)

     //8位工作
    COMPortC(0x3C); //函数集                                          
    延迟1KTCYx(10);
    COMPortC(0x0F);//开启显示并配置光标设置         
    延迟1KTCYx(10);
    COMPortC(0x01); //清除显示
    延迟1KTCYx(10);
    COMPortC(0x06); //增量模式和增量方向(入口模式设置)
    延迟1KTCYx(10);
    COMPortC(0x02); //回家

       //4位
    COMPortC(0x20); //函数集                                          
    延迟1KTCYx(10);
    COMPortC(0x20); //函数集                                          
    延迟1KTCYx(10);
    COMPortC(0x80); //函数集                                          
    延迟1KTCYx(10);

    COMPortC(0x00); //开启显示并配置光标设置         
    延迟1KTCYx(10);
    COMPortC(0xF0); //开启显示并配置光标设置         
    延迟1KTCYx(10);
4

6 回答 6

1

我不确定你的 4 位是如何连接的,但我的猜测是......因为你在上半字节(0x*0 - 星星所在的位置)发送位,你可能想要使用较低的或最低有效半字节,即 0x0*。

COMPortCWithoutBusy(0x02);      //function set first nibble                                     
Delay1KTCYx(10);
COMPortCWithoutBusy(0x02);      //function set second nibble                                    
Delay1KTCYx(10);
BusyEnable();
Delay1KTCYx(10);
...
于 2008-10-30T08:08:28.980 回答
1

在某种程度上它看起来不错,但我想知道几件事:

1/ 为什么要输出两次 0x20 来设置 4-bit 部分的 CGRAM 地址?当然,这只需要一次。

2/其他两个写入(0x00 和 0xf0),我从文档中不明白。你能修正评论以表明它们的意图吗?

3/ 一旦切换到 4 位模式,是否需要重做其他指令(递增和返回原点)?切换模式可能会重置所有数据。

4/ 我注意到的一件事是忙标志表明系统还不能接收另一条指令。可能是您传递它们的速度太快了。当您将延迟从 10 增加到 100 时会发生什么。

只是一些事情要尝试 - 让我们知道结果。

=====

回复:

谢谢回复

1 和 2) 我正在根据数据表 (www.cloverlcd.com/pdf/S6A0069.pdf) 的第 29 页编写这些值。

3)你是对的,我确实需要做其他指令,但现在,我只是想让光标在 4 位模式下闪烁(所以前两条指令就足够了)

4)我刚试了100次延迟,没用。

很抱歉评论不好,下次我会尝试发布更好的代码。

谢谢

=====

编辑:

我现在看到它是如何工作的。在 4 位模式下,它只使用 d7,d6,d5,d4 但每条指令都是 2 次写入(形成一条 8 位指令)。因此,它使用一种技巧来编写指令 20(8 位模式)或 22(4 位模式下的 2020),这两个指令都将模式设置为 4 位。很聪明,三星,让我印象深刻。

尝试遍历整个初始化序列。可能是在初始化完成之前显示器没有完全启动。

所以你需要输出(十六进制) 20,20,80,00,f0, 00,10,00,60,00,20。粗体是您需要添加的。

另外,我需要再问两个问题(请作为对此答案的评论回复,而不是发布另一个答案)

1/ COMPortC() 在输出数据之前是否真的检查忙信号?

2/ 10 的延迟,它是什么单位,毫秒、微秒等?

于 2008-10-30T01:12:45.217 回答
0
无效液晶显示器初始化(无效)
{

    COMPortCWithoutBusy(0x20); //函数设置第一个半字节                                     
    延迟1KTCYx(10);
    COMPortCWithoutBusy(0x20); //函数设置第二个半字节                                    
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);

    COMPortCWithoutBusy(0x80); //函数设置第三个半字节                                        
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);

    COMPortCWithoutBusy(0x00); //开启显示并配置光标设置第一个半字节
    延迟1KTCYx(10);
    COMPortCWithoutBusy(0xF0); //开启显示并配置光标设置第二个半字节
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);

    COMPortCWithoutBusy(0x00); //disp 清除第一个半字节                                       
    延迟1KTCYx(10);
    COMPortCWithoutBusy(0x10); //disp 清除第二个半字节                                  
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);

    COMPortCWithoutBusy(0x00); //进入模式设置第一个半字节                                       
    延迟1KTCYx(10);
    COMPortCWithoutBusy(0x60); //进入模式设置第二个半字节                                  
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);

    COMPortCWithoutBusy(0x20); //20 第一个半字节                                       
    延迟1KTCYx(10);
    BusyEnable();
    延迟1KTCYx(10);
}
于 2008-10-30T04:33:14.077 回答
0

这是 4 位模式的一段更好的注释代码

    COMPortC(0x20); //函数设置第一个半字节                                     
    延迟1KTCYx(10);
    COMPortC(0x20); //函数设置第二个半字节                                    
    延迟1KTCYx(10);
    COMPortC(0x80); //函数设置第三个半字节                                        
    延迟1KTCYx(10);

    COMPortC(0x00); //开启显示并配置光标设置第一个半字节
    延迟1KTCYx(10);
    COMPortC(0xF0); //开启显示并配置光标设置第二个半字节
    延迟1KTCYx(10);

我仍然不知道出了什么问题。此外,在数据表的第 18 页上,它显示了与 8 位模式的时序图几乎相同的时序图,只是有一个 AC3。AC3是什么意思?

于 2008-10-30T01:43:07.743 回答
0

这只是 HD44780 LCD 驱动程序的另一种变体,因此它应该可以与以下初始化例程一起正常工作:

void initlcd(void)
{
    delayms(20);    // Wait for LCD to power up ( >15ms )
    RS=0;       // Set RS low for instruction 
    write4(3);  // Set interface to 8 bits 
    delayms(5); // Wait for LCD execute instruction ( >4.1ms )
    write4(3);  // Set interface to 8 bits 
    delayms(1); // Wait for LCD execute instruction ( >100us )
    write4(3);  // Set interface to 8 bits 
    delayms(5);     // Wait for LCD execute instruction (At this point 
            // we could actually start using the busy flag) 
    write4(2);  // Set the display to 4 bit interface 
    delayms(5); // Wait for LCD execute instruction 
    write8(0x28);   // Set the display to two line and ???
    delayms(5); // Wait for LCD execute instruction 
    write8(6);  // ???
    delayms(5); // Wait for LCD execute instruction 
    write8(1);  // Clear the LCD
    delayms(5); // Wait for LCD execute instruction
    write8(0xf);    // ???
    delayms(5); // Wait for LCD execute instruction
    return;
}

您需要定义自己的 write4、write8 和 delayms 函数,但它们相对容易。确保将寄存器选择 (RS) 设置为命令模式。write4 发送一个 4 位命令,而 write 8 连续发送两个 4 位命令,先是高半字节,然后是低半字节:

void write8(uns8 byte)
{
    uns8 nibble;
    nibble = (byte & 0xf0) >> 4;    // Rotate the high 4 bits (7-4) of byte into bits (3-0) of nibble
    write4(nibble);         // Write the high 4 bits to the LCD
    nibble = byte & 0xf;        // Copy the low four bits of byte into the low four bits of nibble
    write4(nibble);         // Write the low 4 bits to the LCD
}

我编写的代码适用于 PIC 微控制器,使用免费版本的 cc5x 编译器。应该可以理解并移植到其他语言。

通过多年的 LCD 初始化,初始化例程大量借鉴了许多其他例程 - 发现并克服了 HD44780 和变体的各种怪癖。它应该适用于大多数类似的 LCD。

于 2009-04-28T18:52:22.850 回答
-1

1 和 2) 我正在根据数据表 (www.cloverlcd.com/pdf/S6A0069.pdf) 的第 29 页编写这些值。

3)你是对的,我确实需要做其他指令,但现在,我只是想让光标在 4 位模式下闪烁(所以前两条指令就足够了)

4)我刚试了100次延迟,没用。

于 2008-10-30T01:18:33.830 回答