Jump to content

  • Log In with Google      Sign In   
  • Create Account

Photo

2 wire Nokia 5110 interface


  • Please log in to reply
8 replies to this topic

#1 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 811 posts
  • LocationMichigan, USA


Posted 27 November 2011 - 06:11 AM

This is a way to use the Nokia 5110 LCD with only 2 GPIO pins. Software SPI allows any 2 pins to be used. In some cases the data line may be shared with another external peripheral such as an output shift register or an other 5110.

The D/C and Reset lines are controlled by stretching the clock pulse. R/C values must be calculated for the specific clock frequency that the MSP430 will run at. A variety of Schmitt trigger gates could be used, such as MC14584, CD40106, 74HC14, 74HC132, etc...

Wiring...
nok2sch.png

The clock pulse for D0 is stretched when a command byte is sent. The PCD8544 controller latches the D/C line during the rising edge of the clock during the D0 period.
A reset pulse uses an even longer clock pulse.
nok2wire.jpg

Software SPI for 2 wire scheme
typedef enum {
    lcd_command = 0,        // Array of one or more commands
    lcd_data = 1,           // Array of one or more bytes of data
    lcd_data_repeat = 2     // One byte of data repeated
} lcd_cmd_type;

void lcd_send(const unsigned char *cmd, unsigned len, lcd_cmd_type type)
{
    register unsigned mask;
                                                            // CLK high upon entry and exit 
    do {                                                    // Send bits 7 to 1
        mask = 0x0080;                                      // msb first
        do {                                                //
            if(*cmd & mask) {                               // Test bit
                P1OUT |= LCD_DATA;                          // 1 bit, data high
                P1OUT &= ~LCD_CLK;                          // Clock low
            } else {                                        //
                P1OUT &= ~(LCD_CLK | LCD_DATA);             // 0 bit, data & clock low
            }                                               //
            P1OUT |= LCD_CLK;                               // Clock high
            mask >>= 1;                                     // Next bit
        } while(!(mask & 1));                               // Check if bit 0, loop if not
                                                            // Send bit 0
        if(*cmd & mask) {                                   // Test bit
            P1OUT |= LCD_DATA;                              // 1 bit, data high
            P1OUT &= ~LCD_CLK;                              // Clock low
        } else {                                            //
            P1OUT &= ~(LCD_CLK | LCD_DATA);                 // 0 bit, data & clock low
        }                                                   //
        if(!type) __delay_cycles(10);                       // Stretch clock if command - DC will go low                                                                
        P1OUT |= LCD_CLK;                                   // Clock high
        if(!(type & 2)) ++cmd;                              // Inc buf pointer if not repeat
    } while(--len);                                         // Decrement byte count, next byte if not zero...
}

void lcd_reset(void)
{
    P1OUT &= ~LCD_CLK;
    __delay_cycles(10000);
    P1OUT |= LCD_CLK;
    __delay_cycles(10000);
}

  • bluehash, RobG, Rickta59 and 3 others like this
Sent from a bunker in an undisclosed location deep beneath a mountain.

#2 RobG

RobG

    Level 5

  • Members
  • 2,691 posts
  • LocationCary, NC, US


Posted 27 November 2011 - 03:45 PM

This is very nice. You could also (or should) use hardware SPI and just change to slower speed when sending command, for example 4MHz data, 1MHz command. You would then avoid any problems when using interrupts.
I would also suggest using little/tiny logic like 2G14 (plus 1G14 if reset is needed.) At one point, I wanted to do something similar for my serial LCD pack, use missing pulse detector to trigger enable pin, but I figured that inflexibility (and extra parts) is not worth it. Any ideas?
  • roadrunner84 likes this

#3 timotet

timotet

    Level 1

  • Members
  • 140 posts
  • LocationBend , Oregon

Posted 27 November 2011 - 06:44 PM

great job opossum
so this is how EE's do it? :)

#4 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 811 posts
  • LocationMichigan, USA


Posted 01 December 2011 - 05:01 PM

I chose to use software SPI so the code could work with any MSP430 and any two pins (of the same port). Interrupts can be disabled at the bit, byte or function level as appropriate. Hardware SPI is obviously much faster, but chip and pin selection is limited and there are 2 different hardware SPI peripherals that need to be supported.

Software control of the 5110 reset is essential to allow debugging and also improves reliability in a finished product. I would not recommend removing this feature - use a 74LVC3G14. Explicit reset and initialization of all peripherals is generally good design and coding practice.

Many ways to detect absence of clock. I think this will work...

Attached Thumbnails

  • mpd.png

Sent from a bunker in an undisclosed location deep beneath a mountain.

#5 RobG

RobG

    Level 5

  • Members
  • 2,691 posts
  • LocationCary, NC, US


Posted 01 December 2011 - 07:54 PM

Software control of the 5110 reset is essential to allow debugging and also improves reliability in a finished product. I would not recommend removing this feature - use a 74LVC3G14. Explicit reset and initialization of all peripherals is generally good design and coding practice.

I agree, though I prefer hardware reset with a simple RC (shared or separate in cases when in-circuit debugging is required.)

Many ways to detect absence of clock. I think this will work...

Thanks! That put me on the right track, I was looking at a more complex solution.
I think this simple one, which uses LVC3G17, will do the trick for me.

mpd.png

#6 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 811 posts
  • LocationMichigan, USA


Posted 02 December 2011 - 12:04 AM

I assumed the HD44780 latches on rising edge (like the shift register), but it latches on falling edge. So I think you could eliminate the last stage of your circuit or flip the diode in the circuit I posted.
mpd2.png

Data has to be valid for 80 ns before (tDSW) and 10 ns after (tH) the falling clock edge. Outside of those times the data lines may change.
HD44780_write_timing.png
Sent from a bunker in an undisclosed location deep beneath a mountain.

#7 KatjaD

KatjaD

    Noob Class

  • Members
  • 1 posts
  • LocationKamchatka

Posted 21 March 2013 - 08:32 PM

hello, oPossum. i've got most of the things i need to hook up this nokia LCD screen to just two pins. it's quite awesome. but there's only one thing i don't understand. with the lcd_send funtion in your code.. namely, this:

 

void lcd_send(const unsigned char *cmd, unsigned len, lcd_cmd_type type)

 

how would i send a command like

 

display.setTextSize(1);

display.setTextColor(BLACK);
display.setCursor((display.width()/2)-25,(display.height()/2)-3);

display.print("hello, world");

 

to the LCD screen?

 

if it helps any, to know what library i'm using for this

 

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(9, 8, 7, 6, 5);

 

it's the adafruit nokia screen library



#8 JeffersonJHunt

JeffersonJHunt

    Noob Class

  • Members
  • 2 posts
  • LocationSTL

Posted 17 April 2013 - 03:25 AM

Thanks for the post oPossum!

 

I've been struggling with this just a bit. I picked up a MC14584 and opted for R1/C1 at 10ohm and 100nf (calculated for ~8mhz) and substituted a 1k and 100nf for R2/C2. According to my MSO i'm only signaling for about 5us and your trace shows about 20us. I assume my scaling of R1/C1 and or R2/C2 is off. Any help greatly appreciated.

 

Thanks!



#9 oPossum

oPossum

    Poke me with a Stick

  • Members
  • 811 posts
  • LocationMichigan, USA


Posted 17 April 2013 - 03:57 AM

The resistance should be at least several hundred ohms - 1k to 10k is a good range to stay within. The MSP430 can only supply limited current on outputs pins, and low value resistors make the circuit require more than what can be supplied to work properly (have expected timing).


Sent from a bunker in an undisclosed location deep beneath a mountain.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users