News:

Let's find out together what makes a PIC Tick!

Main Menu

ST7735 160 X 128 Graphic LCD Library

Started by LeonJ, Feb 21, 2021, 01:58 PM

Previous topic - Next topic

LeonJ

I've been using this great little color graphics display for a number of projects with my own library (single font) for a while now.
I was very pleasantly surprised when I discovered the library that Les published under Experimenters Notebook. It is much better than mine and is really easy to use.
Notably, it allows for many fonts/sizes to be imported.

I use the SPI hardware peripheral in a PIC18F27K42 at 64 MHz in a "write and forget" manner so that the Pic does not need to wait for transmissions to complete before continuing with foreground processes.

My Test results:
To fill the entire screen with any color takes approx. 67 mS. This means almost 15 screen fills per second!
To print 5 rows of 16 chars (14pt size) takes approx. 138 mS. This means more than 7 full text screen updates per second!
Of course to plot lines, circles etc. may take a bit longer due to the additional calculations needed but still, normal screen updates are lightning fast.

The compiler Print and Print At statements are "high-jacked" to work as normal, making it really convenient.
Because it was printing incorrect chars, I added one statement to Les' code as follows:

$define ST7735_PrintChar(pChar) '
    WREG = pChar                '
    _ST7735_PrintChar()

#ifSym __SYSCOM_GLCD_PRINT_REQ_                                    ' Has the compiler's Print command been used in the main program?
__Print_:
Sub _ST7735_PrintChar()

    ST_bSaveChar = WREG                                            ' Save the character value
    ST_wSaveTblPtr = ST_wTblPtr                                    ' Save the contents of TBLPTRL\H
'
' Locate the character's image data from flash memory tables
'
WREG = ST_bSaveChar ' Leonj added this. It now prints the correct characters.

    WREG = WREG - 32                                                ' Remove the ASCII offset
    WREG = WREG * 2                                                ' Offsets are 2 bytes each (words)

Once again, many thanks to Les for yet another great piece of very useful code!

Leon.

OG

#1
Les wrote the following note on this subject in the past.
(Note: Link is broken now. The page address may have been changed.
The new address should be below.
Using the Positron8 ST7735 128x160 Colour Graphic LCD library with an 18F PIC microcontroller. )


QuoteIf you only have a font creator that produces Y axis font data, rotate the window that is needed before the font is sent to the display and the pixels will move in the Y direction within it for every write of a pixels. Then send the command to rotate it back when the character is printed. This also helps if the whole display is rotated in use, because the font will always remain in the correct orientation to it. With a brief look at the ST7565R datasheet, it seems to be pixel writes instead of byte writes, so it should have a window mechanism.

See this article I created and it may give you some clues to creating a library for graphic LCDs. It also has a font generator link within it.

proton-experimenters-notebook/st7735-160x128-graphic-lcd-library

The problem with a lot of graphic LCD libraries is that they do not state, exactly, what Font Generator was used to create the bitmap images in flash memory of the characters, or the library code is quite old, so the font generator has long been removed from sites. This has been a problem from day one of graphic LCDs being available for users. :-) That is why I "never" trust the internet and whenever possible download full sites and store them on external drives, so even when the user who created items cannot be bothered to maintian and keep them, I still have them! This has come in very handy many times in the past. Just look at this site and there are so many files that have been removed or mishandled so they are now gone, which is such a shame. :-(

Teo

Hi all,
Is it possible to upload a BMP photo?
Thanks in advance,
Teo

keytapper

#3
There are plenty of converters. BMP is less practical. Sometimes may need several megabytes.
Probably I misunderstood the real question.
Ignorance comes with a cost

top204

#4
That was my fault Leon. I had forgotten about the 18FxxK42 devices that have their SFRs above the address 4095, so the compiler uses a smaller method of access to them instead of the Movffl mnemonic whenever possible, because Movffl takes more clock cyles and more flash memory usage. In the smaller RAM devices, the compiler uses the Movff mnemonic which does not disturb the WREG or any of the STATUS flags. However, the compiler's method to counter-act Movffl uses the WREG, so its contents will be over-written. i.e. volatile.

The TBLPTRL and TBLPTRH SFRs must be saved and restored when a character is printed so that when a flash memory string is being printed, the Print routine will not destroy the address of the flash string's memory.

Whenever possible I use the WREG SFR to carry a value or parameter because it takes less time and less flash memory, but WREG is very volatile, so it needs to be done carefully, but Microchip got the better of me, again, with this routine. I'll need to come up with a bit better solution for transfering WREG and keeping its contents safe.

If using only the 18FxxK42 device, you can use the Movffl mnemonics themselves to save TBLPTRL and TBLPTRH, but the extra memory required for them will probably be greater than the workaround you did. :-)

    Movffl TBLPTRL, ST_wSaveTblPtr       ' Save the contents of TBLPTRL
    Movffl TBLPTRH, ST_wSaveTblPtrH      ' Save the contents of TBLPTRH

BMP is only impractical for standard microcontrolles if using 24-bit colour in them, or greater.

Standard colour TFT or LCD displays are normally setup to use the 16-bit RGB565 format, so each pixel takes 16-bits. For a large display area this will take too much of the microcontroller's flash memory for storage. However, BMP files can also be converted to RGB332 format, which means each pixel only requires 8-bits but the colour resolution is not great so RGB332 is normally used for cartoon type images. Then as each pixel is placed on the display, it is converted to RGB565 format with a simple series of masks and shifts.

For larger images, they can be stored on a flash memory chip or an SD card attached to the microcontroller, and the .bmp file's header has all the information required to set the display size etc...

The good thing about .bmp files is that they are not compressed, so there is never any loss in them, and decompression is not required that also looses some of the image details etc... They are also more easy to manage and read and convert etc...

Teo

Hi Les,
Thanks for the reply.
Basically I want to place some icons on the surface of the display.
These icons do not have a high resolution. They are basically symbols.
Maybe I'm lucky and you help me with a piece of code.
Thanks in advance,
Teo

Pepe

I compiled the library for pic18f2550 and have the error in the ST_print statement. I have to add the ST_ in the variable bwidth in ST7735_Cls.Any have a st7735 whithout errors?

LeonJ

Quote from: top204 on Feb 22, 2021, 03:16 PMI had forgotten about the 18FxxK42 devices that have their SFRs above the address 4095, so the compiler uses a smaller method of access to them instead of the Movffl mnemonic whenever possible, because Movffl takes more clock cyles and more flash memory usage. In the smaller RAM devices, the compiler uses the Movff mnemonic which does not disturb the WREG or any of the STATUS flags. However, the compiler's method to counter-act Movffl uses the WREG, so its contents will be over-written. i.e. volatile.

Thanks Les, great explanation. Could this be the reason (or part of) why this produces wrong results?

MenuLine[textctr] = MenuArray[index] ' produces a wrong result

textchar = MenuArray[index] ' this workaround produces the correct result
MenuLine[textctr] = textchar

top204

#8
Many thanks for that Leon.

I have found some code generation functions within the Array generators that will cause issues on an PIC18FxxK42 device with small arrays that the compiler uses the PLUSW0 on.

They have now been corrected, and I have added a few comparisons to the code generator, so if it sees that it needs the WREG intact, it will use the Movffl mnemonic, regardless. I'll compile an update ASAP.

LeonJ

Les, thanks to you! The comment you made earlier about the Movffl and Movff mnemonics prompted the hunch.

The only 18FxxK42 devices in the "Currently Supported List" are the 18F24K42 and 18F25K42. I'm using larger ones and "expected" some issues.

Very thankful for the solution.