There are stacks and stacks of example code out on the net on talking to LCDs. Go wild, go crazy – if these routines don’t help you then feel free to grab something else. The nice thing about the picpack routines is that they work the same way as the others, and always protect you from read-before-write problems. The only area I think the LCD routines needs expanding is in the area of setting character generator ram (you can do this already, but it’s a bit clunky) and supporting 4 line 40 character displays. These are really just two 2 line by 40 character displays with an extra chip enable line to select between the two “displays”. I’ve got one of these beasties, so I’ll add support for it eventually.
Some notes on getting LCDs working from the electronics side. Most of them run at 5v. So if you are running your pic at 3.3v, you’ll need a separate 5v rail to run the LCD. Check the datasheet for your LCD (if it has one!), but you will probably be able to connect the data pins directly to the pin despite the expected level difference. Check your pic datasheet to ensure that it has 5v tolerant pins, and that the LCD thinks that a logic “1” is as low as 3.3v.
If you’re running your pic at 5v, this will not be a problem. Either way, you’ll need a resistor to reduce the current for the backlight if your display has one. You can’t just whack 5v in there – check the LCD datasheet, match the resistor to the current required (there are plenty of web sites on the net that will help you calculate the resistor value). Or, at least stick something in there, 330R would be a good start.
Lastly, a trap for new players is the contrast adjustment. You can get everything else right, but if you don’t have a variable contrast adjustment, then you’re not going to get anything visible on the LCD. A 10k variable resistor, tied between ground and Vdd allows you to connect the contrast input (normally labelled as Vee) to a value between 0 and 5v. You’ll need to play around with the adjustment once you get it connected up and something allegedly displayed.
Now, on to the software.
Have a look at the lcd_demo project in the lcd directory. Note that in the config.h, you’ll see not only settings for the serial connection (which we’ll use to control the LCD) and the platform settings (make sure you set your clock frequency correctly) but also port and pin settings for the LCD. LCDs can communicate using an “8bit” mode or a “4bit” mode. Either way, you still need three other pins (RS, RW and E) to communicate, so at a minimum you need 7 pins. Personally, I’d rather have more pins free to do something else. Sparkfun produces a serial backpack that allows connection to LCDs with only one pin – unfortunately, it uses asynchronous serial communication, which means you either have to give up your serial port for debugging, or bit-bang your own serial routines. One day I’ll get around to rewriting the backpack code to take a synchronous serial connection (ie, two pins). It looks like a fun little development platform in any case. In the mean time, you can connect to an LCD directly using 7 pins. Platforms like the Sure PicDem 2 board will also work with the pickpack LCD library, even though they’re wired for 8 bit connections. This will actually free 4 pins for other uses.
Have a look at the configure_system routine. Notice that they only new calls are to:
lcd_setup(); // Setup the pins (output / input)
lcd_init (); // Configure chip ready for display
You’ll find that most of the picpack libraries have a “setup” routine for the device they’re talking to. This always sets up the configured ports and pins for input or output as required. Note that they expect that all pins are digital pins, so you’ll need to call turn_analog_inputs_off() yourself. The “init” routines actually initialise the hardware ready for use. In this case, lcd_init configures the LCD for 4 bit operation, clears the display and puts the cursor in the top left corner.
LCD communication takes place in one of two ways. It accepts either commands (which do something) or data (which put data into either the screen buffer RAM or the character generator RAM). You can see examples of commands in the main() routine:
lcd_write_command(LCD_CLEAR_DISP); // clear the display
lcd_write_command(LCD_RETURN_HOME); // cursor back to the beginning
lcd_write_command(LCD_LINE1); // goto line 1
and sending data as well:
lcd_write_data_str("PicPack LCD demo"); // print welcome message
Note that the LCD_LINE1 is simply a command to choose the display RAM location – so you can position the cursor further along the line like this:
// goto line 1, 6th character
lcd_write_command(LCD_LINE1 + 5); position
If you get the example project onto a pic, you can issue commands in your terminal program to clear the display or return the cursor home by typing the letter c and
The program starts by putting a string on the first line of your display to confirm everything is working.
Neat! There’s not much more to it than that, but it does open the pic up to start making its own display and telling the world what’s going on.