a graphical user interface for the pic18f
TRANSCRIPT
-
8/6/2019 A Graphical User Interface for the PIC18F
1/10
A Graphical User Interface for the PIC18F
For a long time, I have wanted to give my PIC projects a decent user interface, something
beyond a few buttons and flashing LEDs. I recently discovered a very low cost color LCD
display available for $15 at www.sparkfun.com (part number LCD-00569) and for as little as
$10 on ebay.
Unlike the picture here, the display shows very crisp graphics
and colors.
The resolution is 130 x 130 pixels, each individually
addressable with 8 or 12 bit colors. The display is small,
having outside dimensions of 1.35" x 1.58". The size of the
screen is only 1.2" x 1.2", but it is large enough to display
menus, pictures and text messages.
This document describes the PIC user interface that I have created. I've made the source
code, along with the schematic / pcb layout open source. All of the files can be downloaded
below.
To see how the user interface looks and works, there is short movie on YouTube:
http://www.youtube.com/watch?v=TDNtWvRc730
Interfacing the LCD:
Connecting the display to a PIC is fairly straight forward, requiring a couple of voltage
regulators and a level shifter. The LCD has a built in LED backlight that runs on 7 volts. Thedisplay uses 3.3v logic and requires a 3.3v regulator to power it. I use PICs that run on 5
volts, so a chip that shifts the TTL logic levels down to 3.3v is needed.
In addition to the display, my user interface requires four buttons. Here is how the LCD and
buttons connect to the PIC:
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
2/10
The PIC is clocked with a 10Mhz crystal and configured internally with a 4x PLC, resulting in a
40Mhz clock rate.
Circuit Board:
Electrical connections are made to the LCD display via a tiny 10 pin connector. The mating
connector can be purchased from Sparkfun (part number LCD-00570) for $2.
Unfortunately this surface mount connector is also very small,
having just .5mm spacing between the leads. This type of
connector requires that it be soldered to a circuit board. I choose to
design my own PCB, but if you don't want to, you can buy a carrier
board from Sparkfun. The picture on the right is of a breakout
board from their website. It is a little more money, but it is
assembled and includes the display.
I designed my board using the free schematic and PCB layout tools from www.expresspcb.com.
After laying out the circuit, I order the bare boards directly from ExpressPCB, using their $51
MiniBoard service. The picture below shows my board after I assembled it. Mounted on theback of the board, behind the LCD, are 3.3 and 7 volt regulators, and the 74HC4050 level
shifter.
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
3/10
You will find a PDF schematic of this board here:
Schematic page 1Schematic page 2
Here are the schematic and circuit board files in the ExpressPCB format:
Schematic and PCB
To open the schematic and PCB files, you will need the software from ExpressPCB. It free from
their website:
http://www.expresspcb.com/ExpressPCBHtm/Download.htm
Developing the Software:
The software presented here was developed using Microchips MPLAB Integrated DevelopmentEnvironment. All of the code is written in C, using the free version of Microchips C18
compiler. To program the chip and debug, Microchips ICD2 was used.
The complete PIC source code for the user interface, including an example program can be
downloaded here:
PICUserInterface.zip
It is recommended that these files be unzipped into the directory c:\PICUserInterface. By
placing the files here, all of the path names in the project will be preserved.
Note: The MPLAB project is configured for: General / Diagnostics level: Errors only
General / Default storage class: Auto
General / Enabled integer promotions unchecked
Memory Model / Small code model (
-
8/6/2019 A Graphical User Interface for the PIC18F
4/10
It is possible to configure the LCD for different coordinate systems. I choose to mount the
display with its connector tab on the top. I setup the coordinate system with 0,0 in the upper
left corner, having X move down and Y move to the right. The display does not show the X=0
and X=131 columns, or the Y=0 and Y = 131 rows. This results in the useable coordinates
running from 1 to 130.
----------- Y ---------->___
_ _ _ _ _ _ _ _ _|_ _|_ _| |
(0,0) |-------------------------| (131,0)| | || | || | || | || | Nokia 6100 display |X | || | || | || | || | |\|/ | |
(0,131) ------------------------- (131,131)
At a low level, the easiest way to write to a graphics display is to specify the X and Y
coordinates of a pixel, then the pixel value, however this method is very inefficient. To make
writing to the screen faster, this LCD uses an auto increment and wrap feature. It works by
first setting the upper left coordinate, then the lower right. Next you send all of the pixels
values in that block, it automatically advances the coordinate with each pixel that you give it.
The display uses the RAMWR command to auto increment and wrap. My initial ization codeconfigures this command to write pixels in the Y direction, going from top to bottom, then
wrapping left to right. This choice was made to best support drawing fonts having variable
character widths. (Note: Because of this wrapping method, bitmap data should be stored in
arrays with the first byte representing the pixel in the upper left corner, then advancing
downward and to the right.)
This document does not go into detail explaining the low level communications of the Nokia
display. You can get a better understanding by reviewing the source code presented here. For
additional information, James Lynch has written a great tutorial. It is available at:
Nokia 6100 LCD Display Driver Tutorial
The datasheet for the Philips controller chip used in the display is also a helpful resource:
Philips PCF8833 Datasheet
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
5/10
The User Interface:
As mentioned earlier, this user interface is built around an LCD display and four push buttons.
Mounted on the right side of the display are the Up and Down buttons. Two more buttons are
mounted below. The intention of this user interface is to make adding menus, sub menus,
messages boxes and sliders easy to any PIC18F device.
The user interface divides the display into three sections, each section is the full width of thescreen.
Along the top is the TitleBar. It displays things like the name of the selected menu, or the
name of the application. The subroutine UIDrawTitleBar() is called to draw the TitleBar.
At the bottom of the screen is the ButtonBar. The function of the buttons mounted below the
LCD change, so the ButtonBar is used to label what they do. Typically the left button is labeled
Selectand the right Back. The routine UIDrawButtonBar() is called to draw the ButtonBar.
The middle of the screen is the DisplaySpace. This is where menus, message boxes,
configuration screens, along with the application's main displays are shown.
Here you can see examples of a menu, message box and a slider drawn in the DisplaySpace:
The code that supports the user interface (menus, messages boxes, ) is in the file
UserInterface.c and is built on top of the LCDDriver.c module.
Creating Menus:
Menus give a user interface a clean and consistent approach to supporting applications that
have numerous commands and configuration settings. These menus here can have up to 6
entries. Menus can also have sub menus, providing an easy way to group related commands.For example, the Main menu shown above includes a Settings entry. Selecting it will present a
sub menu of settings related commands.
Menus are constructed using a table of menu entries. Each entry includes the menu text,
along with what to do when the menu item is selected by the user. There are three types of
menu entries: Commands,Alternates, and Sub Menus.
Calling the function UISelectMenuDisplay() draws a menu in the DisplaySpace. This function is
called with a pointer to the table that defines the menu. A typical main menu table might look
like this:
MENU_ITEM MainMenu[] = {{MENU_ITEM_TYPE_MAIN_MENU_HEADER, "Main menu", SelectApplication},
{MENU_ITEM_TYPE_COMMAND, "About", ShowAboutCommand},
{MENU_ITEM_TYPE_ALTERNATE, "Enable sound", SetEnableSoundCallback},
{MENU_ITEM_TYPE_SUB_MENU, "Settings", SettingsMenu},
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
6/10
{MENU_ITEM_TYPE_END_OF_MENU, "", 0}};
The first line in the table always specifies what type of menu it is, either a Main Menu, or a Sub
Menu. The table's last line marks the end of the table. In between are the menu items. The
first and last lines are not displayed.
A MENU_ITEM_TYPE_COMMAND entry indicates that a function will be executed when this
menu item is selected. A pointer to the function is third field in the entry.
A MENU_ITEM_TYPE_ALTERNATE is used somewhat like a Radio Button in a dialog box. It
allows the user to select one of a fixed number of choices (such as On / Off, or High /
Medium / Low). Each time the user clicks on this type of menu item, it alternates the selection
(i.e. toggles between On and Off, or rotates between High, Medium and Low). The third field in
this entry points to a callback function that alternates the value.
A MENU_ITEM_TYPE_SUB_MENU entry is used to select a different menu. For example, a main
menu might reference a Settings sub menu. The third field in this entry points to the table that
defines the sub menu.
As described above, the first line in a menu table indicates the type of menu:
A MENU_ITEM_TYPE_MAIN_MENU_HEADER specifies the main menu. The second field is the
text displayed on the TitleBar when the menu is shown. The third field is a pointer to a
callback function executed when the user presses the Backbutton, indicating that they are
done with the menu. Typically this callback function would reselect the device's main
application. Note: If the third field is 0, then the Backbutton is not displayed.
A MENU_ITEM_TYPE_SUB_MENU_HEADER is used in the first line of a sub menu table. (Sub
menus that are menus that are called from a main menu, or another sub menu) The second
field is the sub menu's title (which is displayed on the TitleBar). The third field is a pointer
back to the parent menu table (typically this would be the main menu). This is used to reselect
the parent menu when the user presses the Backbutton, indicating that they are done with the
sub menu.
Messages Boxes and Sliders:
In addition to menus, there are a few other standard displays that can be shown in the
DisplaySpace.
A MessageDisplaypresents a text message. The function UISelectMessageDisplay() is called
with the string to show. The source string can be located in ROM or RAM, as indicated by the
StringType argument. If the string is too wide to fit on one line of the LCD, it will automatically
be broken into multiple lines. The string can also contain '\r' characters to break the line. The
Justifyargument specifies left, right or centered alignment. A pointer to a callback function
must be given in the CallbackFuncargument. The callback function is executed when the user
presses one of the two bottom buttons. The MessageType argument sets how the two buttons
are labeled. The choices are:
Back
Yes / No
OK / Cancel
A Sliderallows the users to input a numeric value (such as 0 to 255, or -1000 to 1000).
Sliders show a graphical representation of the value that moves as the users presses the Up
and Down buttons. Sliders are displayed by calling UISelectSliderDisplay(). The MinValue and
MaxValue arguments sets the range for the number. The Step argument indicates how much
the value is incremented / decremented each time the user pushes a button. The
StepAutoRepeatvalue is added several times per second while the user holds down a button.
If the arguments ShowMinMaxValuesFlg and ShowNumericValueFlg are set to TRUE, then the
numeric values are displayed in addition to the graphical slider.
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
7/10
Bitmaps and Fonts:
Pictures and fonts are compiled directly into the projects source code. A choice of five fonts
are in the file fonts.c. They all have a variable pitch (i.e. the icharacter is narrower than the
wcharacter). Variable pitch fonts have a much prettier appearance and print more compactly
than fixed pitch fonts.
The stock fonts are:Font_Small
Font_SmallBold
Font_Medium
Font_MediumBold
Font_LargeNumbers
The LargeNumbers font only includes the characters: 0 1 2 3 4 5 6 7 8 9 - + . % , :
and a space.
In the example project, the file images.ccontains two sample bitmaps, one is a picture of a
pretty woman, and the other is an hourglass icon. Bitmaps can be saved using two colorsystems: RGB8 bitmaps represent each pixel with an 8 bit value (rrrgggbb). RGB12 bitmaps
require 12 bits of storage per pixel but give a better representation of colors (rrrrggggbbbb).
Including many small graphics, such as an hourglass icon, can nicely dress up an application.
Unfortunately, large pictures should be used very sparingly because of the massive amount of
ROM space they require. An RGB12 picture the size of the screen (130 x 130 pixels) eats up
25K of ROM.
The source code for the hourglass bitmap looks like this:
//
// Image: Hourglass// Data is packed with 1 pixel in 1 byte, beginning with the upper left// pixel, the pixel order goes down, then to the right// Byte0 = Bitmap type: 1 = RGB12, 2 = RGB8// Byte1 = Image width (1 - 130)// Byte2 = Image height (1 - 130)// Byte3 = Byte count of image (low byte) (excluding this 5 byte header)// Byte4 = Byte count of image (high byte) (excluding this 5 byte header)// Byte5 = rrrgggbb pixel 1, (x = 0, y = 0)// Byte6 = rrrgggbb pixel 2, (x = 0, y = 1)// ... = remaining pixel data//rom byte Image_Hourglass[] = {
0x02, 0x0D, 0x12, 0xEA, 0x00,0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
8/10
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
The good news is that you do not need to understand the format of bitmaps and fonts in order
to use, or to create them. They are generated with a Windows application written to support
this user interface. The Windows program LCDBitmapAndFontCreator.exe is shown below.
The controls on the left side of the program are used to generate the data for pictures.
Pressing the Load image file button allows you to select a .BMP, .JPG or .GIF file. Here you can
see that a bitmap of an hourglass image has been loaded. The Copy image data to clipboard
button converts the image to textual data, then copies it to the Windows clipboard. Add this
data to your PIC project by opening a .C file in MPLAB, then selecting Paste from the Editmenu.
The fonts in the file fonts.cinclude a reasonable selection of type faces that are practical for
this LCD display. It is likely that you will not need any other fonts. However if you want to
make your own, you can. The controls on the right side of the LCDBitmapAndFontCreator.exe
program are used. Do so by first choosing a font. Then adjust the yellow band in the preview
window to select what is captured. Press the Up, Down, Tallerand Shorterbuttons to set the
top and bottom of the yellow band. Click the Leftand Rightbuttons to set the left edge of the
yellow band over the left edge of the first character. You can view different text in the preview
window by pressing the Sample Textbutton. For example, previewing lower case characters
will help you to insure that the yellow band includes the decenders of a lower case y. Do notworry about the right edge of the yellow band. All of the characters in the ASCII set are
automatically generated.
One should note that the fonts created with this method are likely owned and copyrighted by
Microsoft and should not be used in commercial applications.
The installation program for the LCDBitmapAndFontCreatorWindowsapplications is available
here:
LCDBitmapAndFontCreator.exe
The LCDs Built in Controller Chip:
One of the most appealing qualities of this display is its low cost. It is inexpensive because it is
an OEM part, used widely in Nokia cell phones. However, in the words of James Lynch: "The
major irritant in using this display is identifying the graphics controller; there are two
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
9/10
possibilities (Epson S1D15G00 or Philips PCF8833)".
According to Sparkfun, the controller chip used by the display can be identified as follows:
Philips PCF8833 compatible
controllers
Epson S1D15G10 compatible
controllers
Have a red tab on the protective cover
of the LCD
Marked with one of these:
UMSH-8118FD-1CS
U.R.T. 080109-0010
LM355C11-B
AT-A2-071227-F604-1
GE-12
Have a green tab on the protective
cover of the LCD
Marked with one of these:
EV-LG-0298
73-01824
GMP355C0 0403
C-SNB6C1504.50.21
GE-8
The source code presented here is written for the Nokia 6100 LCD displays having a Philips
controller. Unfortunately when ordering these displays, either from Sparkfun or ebay, it does
not seem possible to specify which controller you want. In my last Sparkfun order, I wanted a
display with the Phillips controller so I emailed them first. In my email I asked that they checktheir stock to tell me "the color of the tab on the LCDs protective cover". In their reply, they
indicated Red, so I placed my order. While Im not sure a red tab will always guarantee the
correct result, it has worked for me.
Looking at the datasheets for the Phillips and Epson controllers, you will find that they are very
similar, however there are differences. The software driving the display must know which
controller it is writing to. If your display uses the Epson controller, it is possible to modify this
software to support it. These are the functions that would need to be updated:
LCDDriverInitialize()
LCDSelectColorMode()LCDSetContrast()
WriteCommandToLCD()
WriteDataByteToLCD()
along with the RGB8ColorMap color table and the list of#defines for the controller's command
set. For a discussion of the differences between the Philips and Epson versions of this display,
see James Lynch's document: Nokia 6100 LCD Display Driver Tutorial
The Unexplained:
In developing the LCDDriver.c module, I found that my display adheres to the Philips datasheetin all ways except for the RGBSET command. I tested this code with two versions of the Nokia
6100 LCD, purchased from two different sources (Sparkfun and the Yallstore on ebay) and
found the same results with both. The problem relates to colors. Initially I could only display
washed out colors, not getting the full range of brightness.
My driver uses the LCD in two different color modes: 8 bit colors and 12 bit colors. The Philips
datasheet indicates that it is necessary to setup a color table (using the RGBSET command)
with the 8 bit color mode. I found that the documented method of programming this table did
not result in correct colors. Through experimentation, I discovered that a 48 byte table (rather
than the 20 byte table documented) was needed. I also found it necessary to setup a color
table for the 12 bit mode.
In LCDDriver.c, the color table is defined in the array RGB8ColorMap[]. You will find this array
is declared twice. One has the data that works correctly with my displays, the other one is
commented out. This table matches the requirements as documented in the Philips datasheet.
It may be necessary to use the commented out version for some LCD displays.
IC User Interface http://www.reifel.org/PICUserInterface/
10 11/11/2010 12:43
-
8/6/2019 A Graphical User Interface for the PIC18F
10/10
Acknowledgements:
In developing the LCDDriver.c module, James Lynch's document Nokia 6100 LCD Display Driver
Tutorialwas extremely helpful. The line and circle drawing routines were derived from the
1962 algorithms of the famous Jack Bresenham.
Last edited: 7/20/2009
IC User Interface http://www.reifel.org/PICUserInterface/