GUI (Graphical User Interface) greatly facilitates the use of non-professional users. Users do not need to remember a large number of commands. Instead, they can operate through windows, menus, buttons, etc. In some cases, designing an embedded product with a rich and friendly human-computer interface can win more users. Here, the author gives a brief introduction to the use of s3c2416 based on UCGUI graphical user interface.
1. Code preparation
UCGUI 3.98 source code, this version of UCGUI is the highest version of open source, and later versions only provide library files and are no longer open source. The author uses UCGUI 3.98 version porting as an explanation. Please download the UCGUI 3.98 version by yourself. The file names of other versions are slightly inconsistent. For detailed information about UCGUI overview, usage, porting, etc., you can directly read the UCGUI user manual.
s3c2416 startup code project, the startup code is the code that must be run before the s3c2416/50/51 series arm9 chips run the user c code main function. The startup code supports sd and Nand startup, sets the system clock for the user, initializes the memory, automatically identifies the startup device and moves the code to RAM, MMU mapping, interrupt management, etc. Users only need to focus on developing other functional functions with c. The author has a very detailed introduction to the startup code and the implementation process of the startup code in the previous chapter. Here, we will use the transplantation of UCGUI under GCC as an explanation. Download the startup code source code in "GCC startup code project application example". If you develop under MDK, download the startup code source code in "MDK startup code project application example". The development settings under MDK are relatively simple, and the transplantation of UCGUI under MDK will not be subdivided.
User code, all functional codes developed in C, where the user code entry is the main() function, where the module driver of the LCD screen and touch screen is implemented to support UCGUI display and touch.
2. Project construction
Create a new UCGUI project directory in any path under the Linux operating system, download and decompress the UCGUI 3.98 source code, and copy the GUI and Config directories under the Start directory to the UCGUI directory. The GUI directory contains the UCGUI source code implementation, and the Config directory contains the configuration files for the GUI, LCD, and touch screen. Then copy the GUIDemo directory under the Sample directory to the UCGUI directory. GUIDemo is a test code written by Micrium to tell users how to use UCGUI. Copy the two code files GUI_X.c and GUI_X_Touch.c under Sample->GUI_X to the GUI_X directory under the UCGUI directory. GUI_X.c is the extension part of the GUI related to the system, such as the delay implementation, which does not involve the operating system. GUI_X_Touch.c is the interface part of the GUI that supports touch screen implementation.
Copy the startup code directory start_code to the UCGUI directory. This part of the code does not need any modification. And keep the Makefile files. The project management Makefile under the GCC startup code is extracted from uboot, which can easily add source code and code directory.
Create a new apps directory under the UCGUI directory to store application-related source code.
The final UCGUI directory contents are as follows:
Figure 2-1 UCGUI directory contents under Linux operating system
3. Modify UCGUI
UCGUI uses LCD and touch screen, and needs to be configured and interface called according to our actual screen and touch screen.
3.1. Config Directory
Enter the Config directory, open GUIConf.h to configure the GUI overall. Since there is enough memory, you can set a larger dynamic memory and support memory devices. The operating system and mouse are not supported here. The modified content is as follows:
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_OS (0) /* Multitasking is not supported*/
#defineGUI_SUPPORT_TOUCH (1) /* Support a touch screen (req. win-manager)*/
#defineGUI_SUPPORT_MOUSE (0) /* Mouse is not supported */
#defineGUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */
#defineGUI_DEFAULT_FONT &GUI_Font6x8
#defineGUI_ALLOC_SIZE (1024*1024) /* Dynamic memory 1M*/
/****************************************************** *********************
*
* Configuration of available packages
*/
#defineGUI_WINSUPPORT 1 /* Window manager package available */
#defineGUI_SUPPORT_MEMDEV 1 /* Memory devices available */
#defineGUI_SUPPORT_AA 1 /* Anti aliasing available */
#endif /* Avoidmultiple inclusion */
Open LCDConf.h to configure the LCD. I use a 16-bit (R:5-G:6-B:5) RGB screen with a color depth of 800*480. Clear all contents in LCDConf.h because this is the configuration of other LCD screens and is completely inconsistent with the screen used. The modified content is as follows:
#ifndef LCDCONF_H
#define LCDCONF_H
/****************************************************** *********************
* General configuration of LCD
*************************************************** *********************
*/
#define LCD_XSIZE (800) /* Screen X horizontal pixels*/
#define LCD_YSIZE (480) /* Screen Y horizontal pixel*/
#define LCD_BITSPERPIXEL (16) /* 16-bit color depth*/
#define LCD_CONTROLLER (-1) /* Macro switch, use the template under LCDDriver*/
#define LCD_FIXEDPALETTE (565) /* R:5-G:6-B:5 */
#define LCD_SWAP_RB (1) /*RB color swap*/
#define LCD_SWAP_XY (0) /* Screen x, y directions do not swap*/
#define LCD_INIT_CONTROLLER() LCD_RGB_Init() /* Screen driver initialization interface*/
#endif /* LCDCONF_H */
Open GUITouchConf.h to configure the touch screen. The author uses a capacitive touch screen. The driver IC has processed the returned touch coordinate values and the screen pixel coordinates one by one. It can also be calibrated after transplantation.
#ifndefGUITOUCH_CONF_H
#defineGUITOUCH_CONF_H
#defineGUI_TOUCH_AD_LEFT 0 /* The touch screen can return the leftmost value*/
#defineGUI_TOUCH_AD_RIGHT 800 /* The touch screen can return the rightmost value*/
#defineGUI_TOUCH_AD_TOP 0 /* The touch screen can return the top value*/
#defineGUI_TOUCH_AD_BOTTOM 480 /* The touch screen can return the bottom value*/
#defineGUI_TOUCH_SWAP_XY 0 /* The x and y directions of the touch screen are not swapped */
#defineGUI_TOUCH_MIRROR_X 0 /* Touch screen x direction is not mirrored*/
#defineGUI_TOUCH_MIRROR_Y 0 /* Touch screen y direction is not mirrored*/
#endif /* GUITOUCH_CONF_H */
3.2. LCDDriver Directory
Enter the GUI->LCDDriver directory, and modify the underlying interface call of the actual LCD in UCGUI. Since we configure LCD_CONTROLLER to -1 in LCDConf.h, this macro switch will select the template file LCDTemplate.c for compilation, and other interface files will not be compiled. There is already relevant template code in LCDTemplate.c. You only need to add the implementation of LCD_L0_SetPixelIndex() and LCD_L0_GetPixelIndex(). LCD_L0_SetPixelIndex sets the pixel value of a certain coordinate of the LCD, and LCD_L0_GetPixelIndex reads the pixel value from a certain coordinate of the LCD, which correspond to the underlying functions LCD_SetPixel() and LCD_GetPixel() of the RGB screen driver module respectively. Just add the underlying functions in these two modules.
The modified code of LCD_L0_SetPixelIndex() is as follows:
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Write into hardware ... Adapt to your system */
{
LCD_SetPixel(x,y, (unsigned short)PixelIndex);
}
}
The modified code of LCD_L0_GetPixelIndex() is as follows:
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
LCD_PIXELINDEX PixelIndex;
GUI_USE_PARA(x);
GUI_USE_PARA(y);
/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y
int xPhys = LOG2PHYS_X(x, y);
int yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
/* Read from hardware ... Adapt to your system */
{
PixelIndex =(LCD_PIXELINDEX)(LCD_GetPixel(x, y));
}
return PixelIndex;
}
LCDTemplate.c is the bottom interface implementation of UCGUI, which will directly access the LCD. Therefore, these interface functions often need to be rewritten according to the characteristics of the LCD screen to achieve the best access speed. For example, LCD_L0_DrawVLine draw line function, LCD_L0_FillRect rectangle fill function, etc., the template implementation is to call LCD_L0_SetPixelIndex to write the screen point by point, which is fatal for the i80 interface LCD, because each point access needs to write the command, address first, and then the data, and the screen access speed will be very slow, so it should be rewritten to continuous write mode, that is, write continuous write commands and then send data continuously. In order to further improve the performance of UCGUI accessing LCD, by reducing the level of function nesting calls, reducing unnecessary bottom-level code, and even assembly implementation, etc. can be tried. Since the author uses an RGB screen, the screen display is in the main system memory area, and the access to the screen is actually the access to the video memory. The default implementation function of the template for other UCGUI interface functions will not cause a significant deterioration in performance, and other interface functions will not be rewritten and optimized.
Finally, add the module header file #include "lcd_rgb.h" for LCD driver interface access in LCDTemplate.c.
3.3. GUI_X Directory
The UCGUI extension is stored in the GUI_X directory. GUI_X.c does not need the support of the operating system, but only needs a variable time count of the system time OS_TimeMS. The delay functions of UCGUI, such as GUI_Delay(), are based on this timing as the standard, and the timer time count can be implemented in the user code. Before the GUI starts, there may be other hardware devices that need to be initialized in addition to the LCD. For example, UCGUI uses LCD and touch screen, so these devices should be initialized before the GUI is used. This is implemented in the GUI_X_Init() function as follows:
void GUI_X_Init(void)
{
#if GUI_SUPPORT_TOUCH
TP_Init(); // Initialize the touch screen when using UCGUI
#endif
}
At the same time, add the header file accessed by the TP interface module to this file #include "tp_ft5206.h"
GUI_X_Touch.c is the UCGUI touch screen access interface. It only needs to implement GUI_TOUCH_X_MeasureX() and GUI_TOUCH_X_MeasureY(). GUI_TOUCH_X_MeasureX requires that if there is a touch, the X position of the touch screen should be returned, otherwise an invalid position value (such as -1) is returned. GUI_TOUCH_X_MeasureY requires that if there is a touch, the Y position of the touch screen should be returned, otherwise an invalid position value (such as -1) is returned. These two functions correspond to the underlying functions TP_GetPoint1_X() and TP_GetPoint1_Y() of the capacitive screen module to obtain the x and y positions of the first touch point. Since UCGUI does not support multi-touch, it is sufficient to implement returning only the first touch point at any time in the capacitive screen driver module. Add the capacitive screen module access header file #include "tp_ft5206.h" to access the capacitive screen module interface. The modified content of GUI_X_Touch.c is as follows:
#include "GUI.h"
#include "GUI_X.h"
#include "tp_ft5206.h"
void GUI_TOUCH_X_ActivateX(void) {
}
void GUI_TOUCH_X_ActivateY(void) {
}
int GUI_TOUCH_X_MeasureX(void) {
return TP_GetPoint1_X();
}
int GUI_TOUCH_X_MeasureY(void) {
return TP_GetPoint1_Y();
}
4. Modify user code
4.1. LCD driver module implementation
The LCD driver module needs to provide the interface LCD_SetPixel() to set the pixel color at a certain coordinate and the interface LCD_GetPixel() to read the pixel color from a certain coordinate. The implementation of the RGB screen driver module used by the author has been introduced in detail in the previous chapter, so I will not go into details here. The lcd_rgb.c module is implemented as follows:
#include "s3c2416.h"
#include "lcd_rgb.h"
#define VBPD 15
#define VFPD 5
#define VSPW 5
#define HBPD 25
#define HFPD 88
#define HSPW 20
// The frame buffer data is transferred to the interface via LCD DMA. To ensure data consistency, the CPU should directly access the main memory each time it writes to the video memory.
// That is, when accessing video memory, you should close the cache or invalidate the data in the cache, allocate the no_cache segment cache and close it in the MMU
// The corresponding area memory cache is used for DMA transfer, such as LCD display memory, IIS audio DMA transfer, etc., declare the attribute section("No_Cache")
static unsigned shortFrameBuffer[HSize*VSize] __attribute__((section("No_Cache"),zero_init));
unsigned short*GetFrameBuffer()
{
return FrameBuffer;
}
void LCD_Enable(intEnable)
{
if (Enable) {
rVIDCON0 |= (0x03 << 0);
} else {
rVIDCON0 &= ~(0x03 << 0);
}
}
voidLCD_BackLight(int On)
{
rGPBCON &= ~(0x3 << 0);
rGPBCON |= (0x1 << 0);
if (On) {
rGPBDAT |= (0x1 << 0);
} else {
rGPBDAT &= ~(0x1 << 0);
}
}
void LCD_RGB_Init()
{
rGPCCON = 0xaaaa02aa; // GPC is configured as RGB data [7:0], control function
rGPDCON = 0xaaaaaaaa; // GPD is configured as RGB[23:8]
LCD_Enable(0);
// 16bpp (R5-G6-B5), the first pixel is at the low memory address, select buffer0
rWINCON0 = (5<<2) | (1<<16) |(0<<23);
rWINCON1 = (5<<2) | (1<<16) |(1<<6);
// Select HCLK=100M, divide by 3 to get VCLK=33.3M, RGB parallel port format (RGB), do not start the control logic for now
rVIDCON0 = (0<<22) |(0<<13) | (0<<12) | (2<<6) |
(1<<5) | (1<<4) | (0<<2) |(0<<0);
//VCLK falling edge latches data, horizontal and vertical synchronization signals are low active, and data enable is high effective
rVIDCON1 = (0<<7) |(1<<6) | (1<<5) | (0<<4);
// Set the timing control parameters
rVIDTCON0 =((VBPD-1)<<16) | ((VFPD-1)<<8) | ((VSPW-1)<<0);
rVIDTCON1 = ((HBPD-1)<<16)| ((HFPD-1)<<8) | ((HSPW-1)<<0);
// Set the screen pixel size
rVIDTCON2 =((VSize-1)<<11) | ((HSize-1)<<0);
// Set the OSD image to match the screen size
rVIDOSD0A = (0<<11) |(0<<0);
rVIDOSD0B =((HSize-1)<<11) | ((VSize-1)<<0);
rVIDOSD1A = (0<<11) | (0<0);
rVIDOSD1B = ((HSize-1)<<11) |((VSize-1)<<0);
// Alpha blending mode, fully transparent when the base color matches, and completely opaque when the unmatched part
rVIDOSD1C = 0xfff000;
// Set the address of the frame buffer
rVIDW00ADD0B0 = (unsigned int)FrameBuffer;
rVIDW00ADD1B0 = ((unsigned int)(FrameBuffer+ HSize*VSize) & 0xffffff);
// Do not use virtual screen
rVIDW00ADD2B0 = (00<<13) | ((HSize*2)<<0);
// Window 0 use
rWINCON0 |= (1 << 0);
LCD_Enable(1);
LCD_BackLight(1);
}
voidLCD_ClearScreen(unsigned short BackColor)
{
unsigned int i;
for (i=0; i FrameBuffer[i] = BackColor; } } voidLCD_SetPixel(unsigned int x, unsigned int y, unsigned short Color) { if ((x >= HSize) || (y >= VSize)) { return; } FrameBuffer[y*HSize+x] = Color; } unsignedshort LCD_GetPixel(unsigned int x, unsigned int y) { if ((x >= HSize) || (y >= VSize)) { return 0; } return FrameBuffer[y*HSize+x]; } The lcd_rgb.h module header file is as follows: #ifndef __LCD_RGB_H__ #define __LCD_RGB_H__ #ifdef__cplusplus extern "C" { #endif #define HSize 800 // horizontal row pixels #define VSize 480 // Vertical pixels extern voidLCD_BackLight(int On); extern voidLCD_Enable(int Enable); extern voidLCD_RGB_Init(void); extern voidLCD_ClearScreen(unsigned short BackColor); externunsigned short *GetFrameBuffer(void); externunsigned short LCD_GetPixel(unsigned intx, unsigned int y); extern voidLCD_SetPixel(unsigned int x, unsigned int y, unsigned short Color); #ifdef__cplusplus } #endif #endif When there is a touch, the touch screen driver module should return the X position and Y position of the touch point to UCGUI. If there is no touch, it can directly return -1. This can be achieved by obtaining the X position function of the first touch point TP_GetPoint1_X() and the Y position TP_GetPoint1_Y(). The driver of the capacitive screen has been introduced in detail in the previous chapter, so I will not go into details here. Since UCGUI only supports single-point touch, the interrupt output of the capacitive screen is configured in query mode, and the level state of the interrupt line is queried to determine whether there is a touch event. At the same time, capacitive screens are basically IIC interfaces, which require the support of the IIC driver module. The IIC driver implementation has been introduced in detail in the previous chapter, so I will not go into details here. The capacitive touch screen tp_ft5206.c module is implemented as follows: #include "s3c2416.h" #include "IIC.h" #include "tp_ft5206.h" static voidDelay_ms(unsigned int nCount) { //Delay 1ms, total delay nCount(R0) ms __asm__ __volatile__ ( "0:\n\t" "ldr r1, =100000\n\t" // Arm clock is 400M "1:\n\t" "subs r1, r1, #1\n\t" // an Arm clock "bne 1b\n\t" // Jump will clear the pipeline, 3 Armclock "subs %0, %0, #1\n\t" // The caller ensures that nCount is not 0 "bne 0b\n\t" : : "r"(nCount) : "r1" ); } void TP_Reset() { rGPFDAT &= ~ TP_RST; // Low reset line GPF5 Delay_ms(20); rGPFDAT |= TP_RST; Delay_ms(200); } int TP_GetPoint1_X() { unsigned char Point1_X[2]; if (!(rGPGDAT &TP_INT)) { // When the touch screen is pressed, INT is pulled low // Call IIC to read a certain address inside the capacitive screen continuously to obtain the 12-bit X-axis coordinate IIC_ReadBytes(TP_SlaveAddr, TOUCH1_XH, Point1_X, 2); if (!(rGPGDAT &TP_INT)) { //When getting AD, you should keep pressing it, otherwise the AD value may be inaccurate and should be discarded return((((int)(Point1_X[0]&0xf)) << 8) | Point1_X[1]); } } return -1; //Returns an invalid value, indicating that the key has not been pressed or released } int TP_GetPoint1_Y() { unsigned char Point1_Y[2]; if (!(rGPGDAT &TP_INT)) { // When the touch screen is pressed, INT is pulled low // Call IIC to read continuously a certain address inside the capacitive screen to obtain the 12-bit Y-axis coordinate IIC_ReadBytes(TP_SlaveAddr, TOUCH1_YH, Point1_Y, 2); if (!(rGPGDAT &TP_INT)) { //When getting AD, you should keep pressing it, otherwise the AD value may be inaccurate and should be discarded return((((int)(Point1_Y[0]&0xf)) << 8) | Point1_Y[1]); } } return -1; //Returns an invalid value, indicating that the key has not been pressed or released } int TP_WriteBytes(unsigned char WriteAddr, unsigned char *pData, int Length) { int Ret; // Call the IIC interface to write to a certain address inside the capacitive screen continuously Ret =IIC_WriteBytes(TP_SlaveAddr, WriteAddr, pData, Length); return Ret; } int TP_ReadBytes(unsignedchar ReadAddr, unsigned char *pData, int Length) { int Ret; // Call the IIC interface to read continuously a certain address inside the capacitive screen Ret =IIC_ReadBytes(TP_SlaveAddr, ReadAddr, pData, Length); return Ret; } void TP_Init() { unsigned char InterruptMode; rGPGUDP &= ~(0x3 << 8); rGPGUDP |= (0x2 << 8); // TP_INT GPG4 pull-up rGPGCON &= ~(0x3 << 8); rGPGCON |= (0x0 << 8); // GPG4 is configured as IO port input, and interrupt mode is not used rGPFUDP &= ~(0x3 << 10); rGPFUDP |= (0x2 << 10); // TP_RST GPF5 pull-up rGPFCON &=~(0x3 << 10); rGPFCON |= (0x1 << 10); // GPF5 is configured as output TP_Reset(); // When pressing TP, TP should not be reported multiple times (ucgui will think it is pressed multiple times continuously), it should be level triggered //TP is set to level trigger mode, multiple points cannot be recognized at this time, and ucgui can only recognize single points InterruptMode = 0; // The capacitive touch screen is set to level trigger, and one press generates an interrupt signal TP_WriteBytes(ID_G_MODE,&InterruptMode, 1); } The tp_ft5206.h module header file is implemented as follows: #ifndef __TP_FT5206_H__ #define __TP_FT5206_H__ #ifdef __cplusplus extern "C" { #endif // TP IIC 7-bit slave address #define TP_SlaveAddr 0x38 #define TP_INT (1<<4) // GPG4 #define TP_RST (1<<5) // GPF5 #define TOUCH1_XH 0x03 // Touch point 1 coordinate X high 4-bit register address #define TOUCH1_XL 0x04 // Touch point 1 coordinate X lower 8-bit register address #define TOUCH1_YH 0x05 // Touch point 1 coordinate Y high 4-bit register address #define TOUCH1_YL 0x06 // Touch point 1 coordinate Y lower 8-bit register address #define ID_G_MODE 0xA4 // Interrupt mode control register extern void TP_Reset(void); extern void TP_Init(void); extern int TP_GetPoint1_X(void); extern int TP_GetPoint1_Y(void); extern int TP_WriteBytes(unsigned char WriteAddr, unsigned char *pData, int Length); extern intTP_ReadBytes(unsigned char ReadAddr, unsigned char *pData, int Length); #ifdef__cplusplus } #endif #endif/*__TP_FT5206_H__*/ After the startup code sets up the necessary operating environment for the user, it will jump to main to execute the user's C code. All the test codes of UCGUI are in the GUIDemo directory. The main function then jumps to GUIDEMO_main() to start demonstrating all the routines under GUIDemo. As mentioned earlier, the delay implementation of UCGUI requires a timing standard. Here, we use the timer 4 interrupt of s3c2416 to generate 1ms SystemTick as timing in main.c. At the same time, it must ensure the periodic execution (about 100HZ) of GUI_TOUCH_Exec(), which UCGUI uses to obtain the user's touch screen input operation. The implementation of main.c is as follows: #include "s3c2416.h" #include "Exception.h" #include "GUI.h" #include "GUIDEMO.h" #include "IIC.h" static void Timer4_IRQ(void) { extern volatile intOS_TimeMS; static unsigned char TP_Period = 0; OS_TimeMS++; // 1ms count, defined in GUI_X.c, used for UCGUI delay count TP_Period++; if (TP_Period >= 10) { // Check touch screen input every 10ms TP_Period = 0; IRQ_Enable(); // Enable interrupt nesting GUI_TOUCH_Exec(); // Ensure 100HZ touch screen input check } rSRCPND1 |= (0x01 << INT_TIMER4); // write 1 to clear rINTPND1 |= (0x01 << INT_TIMER4); // write 1 to clear } void Timer4_Start() { rTCON |= (0x1 << 20); // Timer start } void Timer4_Stop() { rTCON &= ~(0x1 << 20); // Timer stop } void Timer4_Init() { // Timer 4 clock frequency is PCLK(66.66666M)/(0+1)/16=4.166MHZ rTCFG1 &= ~(0xf << 16); rTCFG1 |= (0x3 << 16); // Timer4 16 division rTCFG0 &= ~(0xff << 8); rTCFG0 |= (0 << 8); // PCLK pre-scaler is 1 rTCNTB4 = 4166; // System Tick is set to 1ms rTCON |= (0x1 << 21); // Update the count value rTCON &= ~(0x1 << 21); // clear rTCON |= (0x1 << 22); // Automatic reload IRQ_Register(INT_TIMER4, Timer4_IRQ); // Register Timer4 interrupt function rINTMOD1 &= ~(1 << INT_TIMER4); //Timer4 IRQ mode rINTMSK1 &= ~(1 << INT_TIMER4); //Timer4 turns on interrupt } int main() { Timer4_Init(); Timer4_Start(); IIC_Init(); // Capacitive screen uses IIC interface GUI_Init(); //When the GUI is initialized, the LCD screen and touch screen will be initialized at the same time while (1) { GUIDEMO_main(); // Call UCGUI DEMO } return 0; } After modifying and implementing all UCGUI porting interfaces, the last step is to add the source code to the project, set the header file search path, and other compilation options to generate output file settings. For visual integrated compilation environments such as MDK, the above settings are easy to operate. The author will not go into details about the MDK project settings. You can download the complete MDK project at the end of the article. MDK transplanted UCGUI effect diagram:4.2. Capacitive screen driver module implementation
4.3. main.c implementation
5. Set up the project
Previous article:S3C2416 bare metal development series 14_Transplantation of UCGUI under GCC (2)
Next article:S3C2416 bare metal development series 13_capacitive screen driver implementation
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Application of indoor navigation and positioning system in the IoT ecosystem
- Share MSP430 control LED and water lamp programming examples
- Precision control techniques and methods for PCB board milling
- MSP430FR6989IPZR Mixed-Signal Microprocessor MCU
- Can anyone help me see how to write the transfer function of the following type of op amp circuit?
- fault mask switching cycles?
- EEWORLD大学堂----Modern Robotics: Mechanics, Planning, and Control
- What makes supercapacitors “super”?
- Please help me, God!
- How to understand the pre-scaling of one stm32 timer as another timer