lcd display stm32 quotation
This display uses the I2C protocol to communicate to the microcontroller. So here you need only 2 pins i.e. SDA and SCL from the microcontroller and the VCC and GND.
I searched a lot for the libraries but all I could find were that of arduino. Than at last I found one by Alexander Lutsai, and I modified it so that it can be used with the STM32 CubeMx
You can see the functions available in the functions tab under ssd1306.c or in the ssd1306.h file. I am going toinitialize the display and print “Hello World !!”…
The STM32 LTDC has a peripheral called LTDC LCD TFT Display Controllerwhichprovides a digital parallel interface(DPI) for a variety of LCD and TFT panels. It sends RGB data in parallel to the display and generates signals for horizontal and vertical synchronization (HSYNC, VSYNC), as well as pixel clock (PCLK) and not data enable (DE) signals:
Horizontal timing signal widths are in units of pixel clocks, while vertical timing signal widths are in units of horizontal scan lines. The HSYNC, VSYNC, pixel clock and not data enable signal polarities can be configured to active high or active low in the LTDC_GCR Global Control Register(not data enable signal must be configured invertedwith respect to the data enable signal in the display datasheet). The datasheet of the panel generally provides the timing parameters for the display:
The LTDC has two layers which can be configured, enabled and disabled independently, each with its own FIFO buffer. Layer order is fixed and layer2 is alway on top of layer1. Layer can be enabled writing the LEN Layer Enable bit in the LTDC_LxCR Layer x Control Register. Each layer gets its data from a framebuffer in memory and the start address is written in LTDC_LxCFBAR Layer x Color Frame Buffer Address Register. The frame buffer contains the display frame data in one of eight configurable pixel format: LTDC_LxPFCR Layer x Pixel Format Configuration Registeris configured to choose the pixel format used to store data into the frame buffer. The available pixel formats are:
Line length parameter is the number of bytes in a line plus three (so the total line length is number of pixels * bits per pixel + 3). These parameters, together with the layer windowing settings, are useful if we want to display part of an image contained in the frame buffer, as I’ll show later.
Some configuration registers are shadowed, meaning their programmed values are stored into shadow registers (not accessible to the programmer) and reloaded into the actual configuration registers based on the configuration of the LTDC_SRCR Shadow Reload Configuration Register: if this register is written with the IMR Immediate Reload bit the registers are reloaded immediately (as soon as the IMR bit is set the registers are reloaded), if the Vertical Blanking Reload bit is written the registers are reloaded with the new values during the vertical blanking period (at the beginning of the first line after the active display area). These bits are set in software and cleared by hardware when shadow registers are reloaded:
In this example I use the display on the STM32F429-Discovery board, which is driven by the ILI9341 display controller. The ILI9341 can drive a QVGA (Quarter VGA) 240×320 262,144 colors LCD display. The controller can be configured via SPI (or parallel interface, depending on the panel settings) to use a digital parallel 18 bit RGB interface (since only 6 lines per color channel are wired on the board to the LTDC). Since the display pixel format is less than 8 bit per channel (RGB666 in this case), the RGB display data lines are connected to the most significant bits of the LTDC controller RGB data lines:
Before enabling the LTDC we must configure the clock system. The LTDC uses a specific clock LCD_CLOCK to generate the pixel clock signal and it must be configured and enabled during the system initialization phase:
To display an image we must convert an image file to an array (possibly a const one, so it can be stored in flash memory) of bytes. To do this I used LCD image converter, a simple but powerful application that can convert a file to a variety of different pixel formats:
Once the image is converted to a byte array the generated header file is included and the array address can be used as the frame buffer starting address in the LTDC_LxCFBAR register. Layer window parameters are configured according to the image size (240 x 320, I rotated the image to fit the display in portrait mode).
The second layer can be enabled as well and its contents drawn on top of layer 1. LTDC can manage transparency using the values in the LTDC_LxCACR Layer x Constant Alpha Configuration Register and LTDC_LxBFCR Layer x Blending Factor Configuration Register: here I used a constant alpha of 255 to obtain a 100% opacity (the value in the constant alpha register is divided by 255 by hardware so for example a value of 128 represents an alpha value of 0.5). Since the layer window is smaller than the display area the default layer background color is set to a transparent black (otherwise the default layer background color is used if the layer window is smaller than the display). The image is 110 x 110 pixels and the pixel format is ARGB8888 (the alpha channel is used to draw transparent pixels). Note that the LTDC_LxCBLR and LTDC_LxCBLNR registers are configured according to the image size: the LTDC always starts fetching data from the address defined in the LTDC_LxCFBAR register. I added the following lines of code to the LTDC_init() function to configure and enable layer 2:
Shadow configuration registers are reloaded each vertical blanking period (after the last line has been drawn) and the code waits for the next frame by polling the VSYNCS flag of the LTDC_CDSR Current Display Status Register, whose bits contain the state of the synchronization signals (high if they’re asserted, no matter the polarity configured). Running the code we get a nice smooth animation:
Double buffer is used when we want the code to write on a frame buffer while another buffer is being read by the LTDC. This avoids corrupting the data being displayed on the screen. The buffers are switched during the vertical blanking period using polling or interrupts.
In this example the framebuffers have a RGB888 color depth and for a 240×320 display that makes 225 KiB of memory for each buffer (3 bytes per pixel x 240 x 320 pixels) so they must be stored in external SRAM (the STM32F429I-DISCOVERY has a 64Mbit external SRAM so we’re good). The FMC Flexible Memory Controller has to be initialized and the address of the two frame buffers has to be configured. Drawing on the framebuffer is a matter of writing the right bytes in order to change the color. Once all pixels are drawn (bytes are written) the buffers are switched and the code can draw the next frame:
Now as soon as a frame is done with, calling LTDC_switch_framebuffer() waits for the vertical synchronization period and swaps the buffers. If the code is faster than the display refresh rate (70Hz in our case) it waits for the LTDC to complete drawing the frame.
While some display controllers cause flicker any time they are written, this particular controller shouldn"t have that problem. I would guess you are having flicker because on each update you are writing parts of the display with one value and then rewriting them with another. To avoid flicker, don"t do that. Figure out what the correct value should be for each pixel before you write it. If your display consists of various non-overlapping rectangles that could move around, and if you"re presently erasing the whole screen and then drawing your rectangular objects, you may be able to improve both performance and appearance by only erasing regions where no objects are supposed to appear; depending upon the application, you may be able to improve performance further by only erasing regions where objects used to exist but have just "disappeared".
Looking at the supplied picture, what is happening is that the display pixels are being written to in one direction (I would guess top-to-bottom), and the display is scanning in another direction (I would guess left to right). This has the effect that the amount of screen data that has been written when the hardware starts scanning a frame is much less than the amount which has been written by the time the hardware scan reaches the right edge. Consequently, the lines which are drawn near the right edge of the screen will have more data drawn on them than the lines near the left.
If you draw data onto the screen in a direction perpendicular to the display scan, you will get the type of diagonal lines you observe here. If you draw data linearly in a direction which is parallel to the display scan at a rate which is slower than the scan rate, there will be an observable "tear" each time the display scan overtakes your drawing. If you draw data at a rate which is faster than the scan rate, and do so in a fashion which is synchronized with the display scan, you can avoid having any kind of display artifacting, but I have not observed any color LCDs (and very few monochrome ones) with a CPU interface which would allow a connected CPU to synchronize updates with the display scanning. That"s too bad, because such an ability would allow cleaner display updates than are possible otherwise. A nice easy technique which was used in many arcade games designed by Eugene Jarvis in the early 1980"s was to have the display scanning process interrupt the processor when the scan hits the middle of the screen and again when it hits the bottom. When the scan hits the middle of the screen, everything above the current scan line may be safely updated without flicker provided the updates happen before the scan reaches the bottom. When the scan hits the bottom, everything below the middle may be updated without flicker, provided the updates happen before the scan reaches the middle. It looks as though this controller chip does provide a function to output a pulse when the scan reaches a specified point ("tearing effect line") but I would conjecture that the output is probably not wired to a pin on the display"s connector.
I don"t know exactly what you"re trying to display, but I would suggest that you either work to ensure that any time a pixel is written at all it"s written with its "final" color or, failing that, minimize the amount of time between the first and last write to each pixel. For example, if you don"t have enough memory to buffer anything externally, you might clear 32 rows of pixels, and then draw everything which should appear in those 32 rows, then clear the next 32 rows, draw everything which should appear there, etc.
If you have a 16-bit data bus which connects to both the display and the SRAM, and if you have at least one address bit coming out of the CPU that doesn"t connect to the RAM (e.g. A18), a useful technique would be to connect that extra address bit with some logic so that any read or write access will be handled by the SRAM as normal, but if that bit is "1" it will also hit the "write data" strobe on the display. If you do that, reading a word of RAM at its normal address will behave as it normally would, but adding 0x00040000 (assuming you use A18) to the address and then performing the read would cause that word of data to be sent directly from RAM to the display (the processor would also read the data, but it wouldn"t have to do anything with it). If you don"t have an extra address bit available, there are other techniques you could use instead, but I"d have to know more about your hardware to know what to recommend.