📜 ⬆️ ⬇️

Connecting a color LCD touch screen to a microcontroller

Good afternoon, Habr. Today I would like to share some experiences regarding the connection of color LCD-indicators to the microcontroller. This topic has already been raised on Habré ( http://habrahabr.ru/post/139384/ ), so this post can be considered as a supplement to the one already written by my distinguished colleagues.


In the post, which is a link at the beginning, are considered LCD-indicators connected via the SPI interface. This method of connection is simple, but not the only one. Many indicators have “on board” only a simplified controller that does not have a memory for storing an image, and therefore, requires continuous updating of the image. Such indicators are used everywhere in electronic gadgets, and their operation requires a special LCD controller built into the microcontroller. An example of such an indicator is MI0350CT-3 manufactured by Multi-Inno Technology. This is a fairly typical representative of color LCD, having a resolution of 320 * 240 and a resistive sensor.
So, we have some problem. Suppose each pixel is represented in memory by a 32-bit value (of which only 24 are used, but the data is aligned on 4-byte boundaries). So, for one video page, we need 320 * 240 * 4 = 307200 bytes = 300 KB of RAM. Not every microcontroller has this amount of memory. Therefore, as a rule, for the LCD to work, external memory is needed, and hence the external memory controller on the microcontroller chip.
To be fair, it should be noted that memory requirements can be reduced if you use not 24-bits per pixel, but less color depth, but, on the other hand, we may want to place several video pages in the system's memory in order to be able to quickly switch between them . We will return to this topic later.
For example, consider connecting an LCD to an LPC2478 microcontroller. This is a slightly outdated representative of NXP microcontrollers (on the ARM7 core, and not on the modern Cortex M3), but for our purposes this is not essential. This microcontroller contains everything you need: an external memory controller (with the ability to connect both SRAM and SDRAM), and an LCD controller with the possibility of very flexible configuration.
For the experiments, I used the SK-MLPC2478 board, which had, in addition to the LPC2478 microcontroller, a static memory chip (CMOS SRAM) K6R4008V1D-TI10 of 512Kx8 bit. The above-mentioned indicator MI0350CT-3 is connected to the board.
There is another underwater stone: this indicator requires a source with an output current of 20 mA at a voltage of about 20 V to power the backlight. For example, a pulsed boost converter that is powered by an input voltage of + 5V and feeds the load with a stabilized current 20 can be used as such a source. mA If the load is not connected, the converter operates in the stabilization mode of the output voltage (U out = 20 V). The converter circuit is shown in Fig. 1. The principle of operation and the calculation of the boost converter will not be considered here; those interested in this topic can refer to the documentation for the MC34063A chip.



Fig. 1. Voltage converter.
')
Consider briefly the connection and operation of this type of LCD. The LCD uses 24 signals for color information, CLK for pixel sync, HSINK and VSINC for horizontal and vertical sync pulses. In addition, the indicator has an SPI interface for setting the auxiliary registers, the #RESET signal and the DEN signal (data enable). The SPI interface in this case is not intended to transmit the image to the display controller, but to configure auxiliary registers. These registers allow you to select the mode of the indicator, adjust the brightness, contrast and other parameters. However, the default control registers of the indicator are set to the state we need, and if we are not going to change them, the SPI signals can simply be ignored. The #RESET signal can simply be set to the inactive (single) state. In the future, we will not need it.
So, the main signals necessary for the operation of this type of indicator are: data signals that carry information about the current pixel color in the RGB format, a clock signal CLK, vertical and horizontal synchronization signals, and a data resolution signal. Consider timing charts.



Fig. 2. Timing diagram of data transfer in LCD.

In fig. Figure 2 shows the most "large-scale" timeline of data transfer, depicting the transfer of data of one line of the image. Transmission occurs on the front of the CLK signal, and is accompanied by a high level of DEN data resolution signal. The transfer takes place in the RGB format, while the Data0 - Data7 bits correspond to blue, Data8 - Data15 - to green, Data16-Data23 - to red.
Before sending data to the line and after transferring data, “empty” CLK pulses are inserted, which do not carry information. The transmission line is preceded by a horizontal synchronization pulse HSYNC (LCD_LP).
The clock frequency of the indicator is 6.4 MHz (it can be reduced, but then the flickering of frames becomes noticeable).



Fig. 3. Timing diagram of frame transmission in LCD

The timing diagram of the full frame transmission in the LCD is shown in Fig. 3. The frame transmission begins with 13 “empty” lines, followed by 240 lines with an image, followed by “empty” lines again. Frame transmission begins with a vertical synchronization pulse.
Also connect to the microcontroller resistive sensor. A description of this connection will be given below.
I will not give a complete diagram of connecting the indicator to the microcontroller, because of its obviousness, I will give only a table of correspondence between the indicator and the controller pins.

Table 1. Correspondence between LCD signals and controller pins

SignalSK-MLPC2478 (connector X6)LCD pinMicrocontroller portNote
GNDone53, 54land
+ 5V2-not used
DATA6318data
+3.3 Vfour41, 42nutrition
LCD CLK INfive-not used
DATA 76nineteendata
DATA 19731data
DATA 18eightthirtydata
DATA 22934data
DATA 23ten35data
DATA 20eleven32data
DATA 211233data
DATA 141326data
DATA 151427data
DATA 121524data
DATA 13sixteen25data
DATA 111723data
DATA 101822data
DATA 1nineteen13data
DATA 02012data
DATA 92121data
DATA 82220data
DATA 172329data
DATA 162428data
LCD LE25-not used
LCD PWR26-not used
LCD FP2737Vertical sync
LCD CLK2838Clock indicator
LCD LP2936Horizontal sync
LCD ENABthirty52Data resolution
DATA 53117data
DATA 432sixteendata
DATA 33315data
DATA 23414data
SPENA3543P0.20SPI interface, serial port data enable
-36-Not used
#RESET376P0.19reset
-38-Not used
SPCK3949P0.17SPI interface, serial port clock
SPDA4050P0.18SPI interface, serial data
YuConnector X7.15eightAD0 / P0.23Resistive sensor
XRConnector X7.139AD1 / P0.24Resistive sensor
YDConnector X7.10tenP0.26Resistive sensor
XLConnector X7.12elevenP0.25Resistive sensor

We assemble the device layout (fig. 4 - 6):



Fig. 4. Layouts of the device layout



Fig. 5. Layout of the device (partially assembled)



Fig. 6. Layout device assembly

Now that everything is connected, you can start writing the code. The first thing to do is configure and test external SRAM memory:

// Init SDRAM controller // Enable EMC clock PCONP_bit.PCEMC = 1; EMCSTATICWAITRD0 = 0x00000001; EMCSTATICWAITPG0 = 0x00000000; EMCSTATICWAITWR0 = 0x00000000; EMCSTATICWAITTURN0 = 0x00000000; EMCCONTROL = 1; // enable EMC 

SRAM test:
 char SRAM_Test(void) { // 32 bits access for (Int32U i = 0; i < 0x80000; i+=sizeof(Int32U)) { *(Int32U*)(((Int32U)SRAM_BASE_ADDR)+i) = i; } for (Int32U i = 0; i < 0x80000; i+=sizeof(Int32U)) { if (*(Int32U*)(((Int32U)SRAM_BASE_ADDR)+i) != i) { printf("Verification error on address : 0x%x\n",(Int32U)SRAM_BASE_ADDR+i); return(FALSE); } } return TRUE; } 

It should be understood that the speed of external memory is an important factor. In fact, the data stream in our case is Fclk * N, where Fclk is the clock frequency of the indicator, N is the number of bytes in memory allocated for 1 pixel. Total we get 6.4 * 10 ^ 6 * 4 = 25.6 MB / s. For memory with an 8-bit interface, this means a maximum allowed access time of 39 ns. Memory speed requirements can be reduced by using memory with a 16 or 32-bit interface and / or reducing the color depth used.
Configuring the LCD in, setting the duration of the signals in accordance with the documentation of the indicator:
 // Init GLCD cotroller PCONP_bit.PCLCD = 1; // enable LCD controller clock CRSR_CTRL_bit.CrsrOn = 0; // Disable cursor LCD_CTRL_bit.LcdEn = 0; // disable GLCD controller LCD_CTRL_bit.LcdBpp= 5; //2bpp // 24 bpp LCD_CTRL_bit.LcdTFT= 1; // TFT panel LCD_CTRL_bit.LcdDual=0; // single panel LCD_CTRL_bit.BGR = 0; // normal output LCD_CTRL_bit.BEBO = 0; // little endian byte order LCD_CTRL_bit.BEPO = 0; // little endian pix order LCD_CTRL_bit.LcdPwr= 0; // disable power // init pixel clock LCD_CFG_bit.CLKDIV = SYS_GetFsclk() / (Int32U)C_GLCD_PIX_CLK; LCD_POL_bit.BCD = 1; // bypass inrenal clk divider LCD_POL_bit.CLKSEL = 0; // clock source for the LCD block is HCLK LCD_POL_bit.IVS = 1; // LCDFP pin is active LOW and inactive HIGH LCD_POL_bit.IHS = 1; // LCDLP pin is active LOW and inactive HIGH // LCD_POL_bit.IPC = 1; // data is driven out into the LCD on the falling edge LCD_POL_bit.IPC = 0; // data is driven out into the LCD on the rising edge LCD_POL_bit.PCD_HI = 0; // // LCD_POL_bit.PCD_LO = 0; // LCD_POL_bit.IOE = 0; // active high LCD_POL_bit.CPL = C_GLCD_H_SIZE-1; // init Horizontal Timing LCD_TIMH_bit.HBP = C_GLCD_H_BACK_PORCH - 1; LCD_TIMH_bit.HFP = C_GLCD_H_FRONT_PORCH - 1; LCD_TIMH_bit.HSW = C_GLCD_H_PULSE - 1; LCD_TIMH_bit.PPL = (C_GLCD_H_SIZE/16) - 1; // init Vertical Timing LCD_TIMV_bit.VBP = C_GLCD_V_BACK_PORCH; LCD_TIMV_bit.VFP = C_GLCD_V_FRONT_PORCH; LCD_TIMV_bit.VSW = C_GLCD_V_PULSE; LCD_TIMV_bit.LPP = C_GLCD_V_SIZE - 1; // Frame Base Address doubleword aligned LCD_UPBASE = (Int32U)GetVramAddr() & ~7UL; 

Now we write a test picture in ROM and copy it into RAM:



Figure 7. Test picture

The picture is recorded as an array of unsigned int [240] [320], and copied to the base address of external memory (0x80000000).
The operation of the LCD support mechanism built into the microcontroller is that the data is read from the RAM by the DMA controller and fed to the LCD controller, where the cursor image is superimposed and the data is fed to the LCD input. The LCD controller can also provide support for palettes for modes from 1 to 8 bits per pixel. The palette is implemented in the microcontroller as 256 16-bit registers and, thus, provides the display of 8-bit color to 16-bit (5 bits / color + 1 bit of total intensity).
The cursor has a separate palette of two 32-bit registers; it provides the display of a monochrome image of the cursor in a 24-bit color space. The cursor can be 64x64 pixels or 32x32 pixels in size, and contains both the cursor image itself and the image inversion mask.
Now you can run a test program and look at the result.



Fig. 8. The result of the work.

Resistive Sensor Connection


The principle of operation of a resistive sensor is widely known (those to whom it is unknown can familiarize themselves with it, for example, here http://ru.wikipedia.org/wiki/Touch screen ). Therefore, we proceed immediately to the description of the connection of the sensor to the microcontroller. This device uses a sensor with a four-wire connection scheme. Connection diagram is shown in Fig. 9.


Fig. 9. Connection diagram of the resistive sensor to the microcontroller.

The idea behind this connection is as follows. Each output of the microcontroller can be in one of the following states: output with a logical 0, output with a log. 1, an input (i.e., in fact, an unconnected output), and an input pulled to the supply voltage through a resistor. Conclusions YU and XL can also serve as inputs to the ADC.
The whole procedure of determining the coordinates of pressing can be divided into three phases. In the first phase, the outputs to which the sensor is connected are in the following state: (Fig. 10).



Fig. 10. Determination of coordinates. Phase 1.

With the closure of the sensor film to the input of the microcontroller, the signal log. 0, and the program proceeds to phase 2, determining the x-coordinate of the pressure (Fig. 11). Then comes phase 3, the definition of the y-coordinate. (Fig. 12).



Fig. 11. Determination of x-coordinates of clicking.



Fig. 12. Determine the y-coordinate of the click.

Of course, the algorithm for calculating the coordinates of pressing should include the suppression of the bounce of "contacts" (sensor films).
With a single measurement, the accuracy of determining the coordinates will be too low, the measurement noise will cause the cursor to oscillate strongly in the vicinity of the tangency point. Therefore, it is highly desirable to use any filtering algorithm, such as a median filter ( http://ru.wikipedia.org/wiki/Median_Filter ).
After receiving the result in ADC codes, it is recalculated to the coordinates of the screen using conventional linear transformations (ax + b), where the coefficients a and b must be found by calibrating the sensor and stored in the nonvolatile memory of the controller. In fig. 13. shows an example of a calibration screen.



Fig. 13. Screen calibration.



Fig. 14. Calibration screen on LCD.

It is also possible to connect the touch screen using an external controller, for example, XPT2046.
The complete source code for the sample program can be downloaded from here: https://bitbucket.org/arktur04/lcd-demo (IAR development environment).

Links to the documentation mentioned in the post:
1.Display Multi-Inno MI0350CT-3 http://www.displayfuture.com/engineering/specs/TFT/MI0350CT-3.pdf
2. MC34063A Pulse Voltage Converter http://www.fairchildsemi.com/ds/MC/MC33063A.pdf
3. Microcontroller LPC2478 http://www.ru.nxp.com/products/microcontrollers/arm7/lpc2400/LPC2478.html
4. XPT2046 Resistive Sensor Controller http://www.dzsc.com/uploadfile/company/785710/20111014212155973.pdf

Source: https://habr.com/ru/post/140415/


All Articles