Library For Driving SSD1289 LCD Displays With Small Microcontrollers

[H. Smeitink] got his hands on a 320×240 color TFT LCD screen. He set out to drive it with a small PIC microcontroller but didn’t find a lot of help out there to get up and running quickly. This is surprising since it’s a really nice display for quite a low price (under $16 delivered on eBay at the time of writing). He decided to write his own library and support tools to help others.

The display includes an SPI touch screen, but since that works separately from the LCD controller, touch input is not supported in this package. The driver that he wrote is coming from a mikroC toolchain point of view, but it shouldn’t be too hard to port to your platform of choice. We took a quick look at the code and it seems all you need to do is tweak the defines to match your hardware registers, and implement your own delay_ms() function.

But he didn’t stop with the driver. You’ll also find a C# program which converts images to an array for easy use on the display. Incidentally, this is the same display which [Sprite_TM] got working with the Raspberry Pi.

20 thoughts on “Library For Driving SSD1289 LCD Displays With Small Microcontrollers

  1. Cool I am currently playing with controling two of these from a Cypress USB 2.0 controller CY7C68013A to make a simple VR display (what can I say I never got over how disapointing VR was first time round) (am using a wii controller as well for movement/position/etc..)
    So I think you may have just saved me ages.
    Thanks a lot.

  2. I have a whole bunch of LCDs lying around from various devices I’ve harvested for parts (old phones, camcorders, etc. The biggest problem I’ve encountered is that I can’t seem to find any white papers/datasheets on how to drive the LCDs. Once I knew the protocol or pinouts of the screens, programming them wouldn’t be a problem for me. It’s jst identifying the screen and how it’s controlled that escapes me. Thoughts?

  3. Looks good, but awfully slow.

    I’ve never used this LCD, but from a quick code examination I think the speed of most functions can be *greatly* improved.

    It appears this LCD has the ability to perform sequential writes in any rectangular region. Which makes it quite fast to write anything in that region, since you don’t have to send commands to change the address after each pixel, or even to move to the next row. The region is set up through the TFT_SetAddress function.

    TFT_Box takes full advantage of this. All it has to do to generate a filled box is call TFT_SetAddress once to set the region, set the color once, then toggle the TFT_WR line twice for each pixel. That’s fast and efficient. You can see how fast it is compared to other drawing functions in the demo video, when it is used to paint the entire screen green at 0:47.

    However, TFT_H_Line and TFT_V_Line do not. They call the TFT_Dot function to individually draw each pixel. TFT_Dot is slow because it works by setting the region to a new, 1×1 area for each pixel drawn; as well as setting the color for each pixel, regardless of whether it’s the same color as the last pixel. Which is very wasteful if you’re drawing a solid-colored rectangular region, and that’s exactly what 90° line is; just with either a width or height of one. I bet TFT_Box draws 90° lines much faster than the functions meant for it!

    The same goes for TFT_Image2 and TFT_Char, which also call the TFT_Dot function. While changing the color is necessary in this case, since they both draw in a rectangular region that only needs to be set once, needlessly resetting the region for each pixel just slows them down.

    The only time TFT_Dot should be called, either directly or indirectly, is when you actually need to draw a single pixel, or a diagonal line.

    The suggested optimizations will not obfuscate the code, nor will they significantly enlarge it (it may actually shrink).

    Additionally, TFT_Text and TFT_Char in particular could be refactored to obtain even more speed; but if taken to its logical end, that could make it harder for another person to understand how they work. So I leave that as an optional exercise. ;)

    1. You are absolutely right, I thought about the line improvements, but I must have forgotten to change the code. I will update the code (probably tomorrow).

      (accidently pressed report instead of reply first, sorry)

      1. Cool. Hope it provides as much speed as I think it will. If so, you will have greatly improved Dryden’s original code. :)

        And if you’re inclined, it would be interesting to see an “after” video to compare with the “before”.

      2. I have updated the code and its a lot faster now, I don’t really feel like making a movie, but it takes about 8 seconds to draw a 83*40 image 200 times (at 20mhz), which means it should take a bit less then a second to draw the whole screen. I also updated the circle function, the line functions, and the text function (the text function could be made a bit faster still, it sets the region per character now, it could be made to set it per line, but this would add code and it wouldn’t mean that much of a difference I think.)

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.