LCD 8-bit mode to 4-bit mode

允我心安 提交于 2019-12-12 16:35:04

问题


We have a character LCD (www.cloverlcd.com/pdf/S6A0069.pdf) that we got to work in 8 bit mode. However, now we are trying to get it to work in 4 bit mode but it doesn't seem to be displaying anything. I think the function set instruction isn't been written. Can somebody please check if I am approaching this the right way? I'll post my 8 bit code (which is working) and my 4 bit code (which I'm trying to get to work)

     //8 bit working
    COMPortC(0x3C);     //function set                                          
    Delay1KTCYx(10);
    COMPortC(0x0F);     //Turn on display and configure cursor settings         
    Delay1KTCYx(10);
    COMPortC(0x01);     //clear display
    Delay1KTCYx(10);
    COMPortC(0x06);     //increment mode and increment direction (entry mode set)
    Delay1KTCYx(10);
    COMPortC(0x02);     //Return Home

       //4 bit
    COMPortC(0x20);     //function set                                          
    Delay1KTCYx(10);
    COMPortC(0x20);     //function set                                          
    Delay1KTCYx(10);
    COMPortC(0x80);     //function set                                          
    Delay1KTCYx(10);

    COMPortC(0x00);     //Turn on display and configure cursor settings         
    Delay1KTCYx(10);
    COMPortC(0xF0);     //Turn on display and configure cursor settings         
    Delay1KTCYx(10);

回答1:


It looks okay up to a point but I wonder about a couple of things:

1/ Why do you output 0x20 twice to set the CGRAM address in the 4-bit section? Surely this is needed only once.

2/ The other two writes (0x00 and 0xf0), I don't understand from the docs. Can you fix up the comments to indicate what they're meant to be doing?

3/ Once you switch to 4-bit mode, do you need to redo the other instructions (the increment and return home)? It may be that switching modes resets all the data.

4/ One thing I did notice is that the busy flag indicates the system cannot yet receive another instruction. It may be that you're passing them in too fast. What happens when you increase the delays from 10 to 100.

Just some things to try - let us know the outcomes.

=====

RESPONSE:

Thanks for the reply

1 and 2) I am writing these values based on page 29 of the datasheet (www.cloverlcd.com/pdf/S6A0069.pdf).

3) You are right, I do need to do the other instructions as well but for now, I am just trying to get the cursor to blink in 4 bit mode (so the first two instructions are sufficient)

4) I just tried the 100 delays, it didn't work.

Sorry for the bad comments, I'll try to post better code next time.

Thanks

=====

EDIT:

I see how it works now. In 4-bit mode, it only uses d7,d6,d5,d4 but every instruction is 2 writes (to make a 8-bit instruction). So it uses a trick to write the instruction 20 (in 8-bit mode) or 22 (2020 in 4-bit mode) both of which set the mode to 4-bit. Very clever, Samsung, I'm impressed.

Try to go through the entire init sequence. It may be that the display doesn't fully start until initialization is complete.

So you need to output (hex) 20,20,80,00,f0,00,10,00,60,00,20. The bold ones are the ones you need to add.

Also, I need to ask two more questions (please reply as a comment to this answer rather than posting another answer)

1/ Does COMPortC() actually check the busy signal before outputting data?

2/ The delay of 10, what unit is it in, millisecs, microsecs, etc?




回答2:


I'm not sure how your 4 bits are hooked up, but my guess is.... Since you are sending the bits on the upper nibble (0x*0 - where the star is), that you likely want to use the lower or least significant nibble which would be 0x0*.

COMPortCWithoutBusy(0x02);      //function set first nibble                                     
Delay1KTCYx(10);
COMPortCWithoutBusy(0x02);      //function set second nibble                                    
Delay1KTCYx(10);
BusyEnable();
Delay1KTCYx(10);
...



回答3:


Here is a better commented piece of code for the 4 bit mode

    COMPortC(0x20);     //function set first nibble                                     
    Delay1KTCYx(10);
    COMPortC(0x20);     //function set second nibble                                    
    Delay1KTCYx(10);
    COMPortC(0x80);     //function set  third nibble                                        
    Delay1KTCYx(10);

    COMPortC(0x00);     //Turn on display and configure cursor settings first nibble
    Delay1KTCYx(10);
    COMPortC(0xF0);     //Turn on display and configure cursor settings second nibble
    Delay1KTCYx(10);

I still don't know what's wrong. Also, on page 18 of the datasheet, it shows a timing diagram that is almost identical to the timing diagram of the 8 bit mode, except that there is an AC3. What does that AC3 mean?




回答4:


void LCDInitialization(void)
{

    COMPortCWithoutBusy(0x20);      //function set first nibble                                     
    Delay1KTCYx(10);
    COMPortCWithoutBusy(0x20);      //function set second nibble                                    
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);

    COMPortCWithoutBusy(0x80);      //function set  third nibble                                        
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);

    COMPortCWithoutBusy(0x00);      //Turn on display and configure cursor settings first nibble
    Delay1KTCYx(10);
    COMPortCWithoutBusy(0xF0);      //Turn on display and configure cursor settings second nibble
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);

    COMPortCWithoutBusy(0x00);      //disp clear first nibble                                       
    Delay1KTCYx(10);
    COMPortCWithoutBusy(0x10);      //disp clear second nibble                                  
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);

    COMPortCWithoutBusy(0x00);      //entry mode set first nibble                                       
    Delay1KTCYx(10);
    COMPortCWithoutBusy(0x60);      //entry mode set second nibble                                  
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);

    COMPortCWithoutBusy(0x20);      //20 first nibble                                       
    Delay1KTCYx(10);
    BusyEnable();
    Delay1KTCYx(10);
}



回答5:


This is just another variant of the HD44780 LCD driver, and as such it should work fine with the following initialization routine:

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

You'll need to define your own write4, write8, and delayms functions, but they are relatively easy. Make sure you have the register select (RS) set to command mode. write4 sends one 4 bit command, while write 8 sends two four bit commands in a row, high nibble first, then low nibble:

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
}

The code I wrote is meant for the PIC microcontroller, using the free version of the cc5x compiler. Should be understandable and portable to other languages.

The initialization routine has borrowed heavily from many others through many years of LCD initialization - finding and overcoming the various quirks of the HD44780 and variants. It should work well for most similar LCDs.




回答6:


1 and 2) I am writing these values based on page 29 of the datasheet (www.cloverlcd.com/pdf/S6A0069.pdf).

3) You are right, I do need to do the other instructions as well but for now, I am just trying to get the cursor to blink in 4 bit mode (so the first two instructions are sufficient)

4) I just tried the 100 delays, it didn't work.



来源:https://stackoverflow.com/questions/248949/lcd-8-bit-mode-to-4-bit-mode

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!