S3C2416 bare metal development series 14_Transplantation of UCGUI under GCC (1)

Publisher:WiseThinkerLatest update time:2016-12-12 Source: eefocusKeywords:S3C2416 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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

4.2. Capacitive screen driver module implementation

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__*/

 

4.3. main.c implementation

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;

}

 

5. Set up the project

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:



Keywords:S3C2416 Reference address:S3C2416 bare metal development series 14_Transplantation of UCGUI under GCC (1)

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

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号