S3C2416裸机开发系列十四_GCC下UCGUI的移植(1)

发布者:WiseThinker最新更新时间:2016-12-12 来源: eefocus关键字:S3C2416  裸机开发  GCC  UCGUI  移植 手机看文章 扫描二维码
随时随地手机看文章

GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是可以通过窗口、菜单、按键等方式进行操作。在某些场合,设计一款人机界面丰富友好的嵌入式产品能赢得更多的用户。笔者此处就s3c2416基于UCGUI图形用户界面的使用作一个简单的介绍。

1. 代码准备

UCGUI 3.98源码,这个版本的UCGUI是开放源码的最高版本,之后版本只提供库文件,不再开源。笔者以UCGUI 3.98这个版本移植作为讲解,请读者自行下载UCGUI3.98的版本,其它版本文件命名有些不一致。关于UCGUI概述、使用、移植等详细内容,可以直接阅读UCGUI用户手册。

s3c2416启动代码工程,启动代码是s3c2416/50/51这系列arm9芯片在运行用户c代码main函数之前必须先运行的代码,启动代码支持sd、Nand启动,为用户设置系统时钟,初始化内存,自动识别启动设备并搬移代码到RAM,MMU映射,中断管理等,用户只需专注于用c开发其它功能函数即可。关于启动代码以及启动代码的实现过程,笔者前面章节有非常详细的介绍。此处以GCC下移植UCGUI为讲解,下载”GCC启动代码工程应用实例”中的启动代码源码即可。如果在MDK下开发,下载”MDK启动代码工程应用实例”中的启动代码源码,MDK下开发设置均比较简单,不再细分MDK下UCGUI的移植。

用户代码,用c开发的所有功能代码,其中,用户代码入口为main()函数,在这里实现LCD屏、触摸屏的模块驱动以支持UCGUI显示以及触控。

2. 工程搭建

在linux操作系统下任一路径下新建一个UCGUI的工程目录,下载UCGUI 3.98源码并解压,把Start目录下的GUI、Config这两个目录拷贝到UCGUI目录中,GUI目录下为UCGUI源码实现,Config目录下包括GUI、LCD、触摸屏的配置文件。再把Sample目录下GUIDemo这个目录拷贝到UCGUI目录中,GUIDemo为micrium公司编写的测试代码,用以告诉用户UCGUI可以怎样应用。拷贝Sample->GUI_X下GUI_X.c和GUI_X_Touch.c这两个代码文件到UCGUI目录下的GUI_X目录中,GUI_X.c为GUI与系统相关的扩展部分,如实现延时,不涉及到操作系统。GUI_X_Touch.c为GUI支持触屏实现的接口部分。

把启用代码目录start_code拷贝到UCGUI目录下,这部分代码无需任何的修改。并保留其中的Makefile这些文件。GCC启动代码下的工程管理Makefile提取自uboot,可以方便地增加源代码以及代码目录。

在UCGUI目录下新建apps目录,用来保存应用相关的源码。

最终的UCGUI目录内容如下:

图2-1 linux操作系统下UCGUI目录内容

3. 修改UCGUI

UCGUI要用到LCD以及触摸屏,需要根据我们实际的屏以及触摸屏进行配置以及接口调用。

3.1. Config目录

进入Config目录,打开GUIConf.h对GUI进行总体的配置,由于内存充足,可以设置较大的动态内存以及支持内存设备,此处并不支持操作系统以及鼠标。修改后的内容如下:

#ifndef GUICONF_H

#define GUICONF_H

 

#define GUI_OS                    (0)  /* 不支持多任务 */

#defineGUI_SUPPORT_TOUCH         (1)  /* Support a touch screen (req. win-manager)*/

#defineGUI_SUPPORT_MOUSE         (0)  /* 不支持鼠标 */

#defineGUI_SUPPORT_UNICODE       (1)  /* Support mixed ASCII/UNICODE strings */

 

#defineGUI_DEFAULT_FONT          &GUI_Font6x8

#defineGUI_ALLOC_SIZE           (1024*1024)  /* 动态内存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 */

打开LCDConf.h对LCD进行配置,笔者使用的是16位(R:5-G:6-B:5)色深800*480的RGB屏,清空LCDConf.h中的所有内容,因为这是其它LCD屏的配置,与所用屏完全不一致,修改后的内容如下:

#ifndef LCDCONF_H

#define LCDCONF_H

 

/*********************************************************************

*                   Generalconfiguration of LCD

**********************************************************************

*/

#define LCD_XSIZE          (800)      /* 屏X水平像素点 */

#define LCD_YSIZE          (480)      /* 屏Y水平像素点 */

#define LCD_BITSPERPIXEL   (16)     /* 16位色深*/

#define LCD_CONTROLLER     (-1)       /* 宏开关,使用LCDDriver下的模板 */

#define LCD_FIXEDPALETTE   (565)      /* R:5-G:6-B:5 */

#define LCD_SWAP_RB        (1)      /*RB颜色调换 */

#define LCD_SWAP_XY        (0)      /* 屏x,y方向不调换 */

#define LCD_INIT_CONTROLLER()  LCD_RGB_Init() /* 屏驱动初始化接口 */

 

#endif /* LCDCONF_H */

 

打开GUITouchConf.h对触摸屏进行配置,笔者使用的是电容屏,驱动IC已处理好返回的触摸坐标值与屏像素坐标一一对应,也可以在移植后进行校准。

#ifndefGUITOUCH_CONF_H

#defineGUITOUCH_CONF_H

 

#defineGUI_TOUCH_AD_LEFT    0    /* 触摸屏能返回最左边的值 */

#defineGUI_TOUCH_AD_RIGHT   800  /* 触摸屏能返回最右边的值 */

#defineGUI_TOUCH_AD_TOP     0    /* 触摸屏能返回最上面的值 */

#defineGUI_TOUCH_AD_BOTTOM  480  /* 触摸屏能返回最下面的值 */  

#defineGUI_TOUCH_SWAP_XY    0    /* 触摸屏x,y方向不调换  */

#defineGUI_TOUCH_MIRROR_X   0    /* 触摸屏x方向不镜像调换*/

#defineGUI_TOUCH_MIRROR_Y   0    /* 触摸屏y方向不镜像调换*/

 

#endif /* GUITOUCH_CONF_H */

 

3.2. LCDDriver目录

进入GUI->LCDDriver目录,需修改UCGUI关于实际LCD的底层接口调用。由于我们在LCDConf.h里配置LCD_CONTROLLER为-1,这个宏开关会选择LCDTemplate.c这个模板文件进行编译,其它的接口文件不会被编译。LCDTemplate.c里面已经有相关的模板代码,只需加入LCD_L0_SetPixelIndex()和LCD_L0_GetPixelIndex()的实现即可,LCD_L0_SetPixelIndex设置LCD某一坐标的像素值,LCD_L0_GetPixelIndex从LCD某一坐标读出像素值,分别对应RGB屏驱动模块底层函数LCD_SetPixel()和LCD_GetPixel()。加入这两个模块中的底层函数即可。

LCD_L0_SetPixelIndex()修改后代码如下:

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 toyour system */

  {

    LCD_SetPixel(x,y, (unsigned short)PixelIndex);

  }

}

LCD_L0_GetPixelIndex()修改后的代码如下:

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 toyour system */

  {

    PixelIndex =(LCD_PIXELINDEX)(LCD_GetPixel(x, y));

  }

  return PixelIndex;

}

LCDTemplate.c是UCGUI最底层的接口实现,将直接访问LCD,因此这些接口函数往往需要根据LCD屏的特点重新改写,以达到最好的访问速度。例如LCD_L0_DrawVLine画坚线函数、LCD_L0_FillRect矩形填充函数等,模板的实现是调用LCD_L0_SetPixelIndex一个点一个点地写屏,这对于i80接口的LCD是致命的,因为每个点的访问都是需要先写命令、地址,最后才是数据,屏访问速度会非常慢,因此应改写为连续写方式,即写入连续写命令后再连续送出数据。为进一步提高UCGUI访问LCD的性能,通过减小函数嵌套调用的层次,减小不必要的底层代码,甚至汇编实现等都可以尝试。由于笔者采用的是RGB屏,屏显存在主系统内存区,对屏的访问实际是对显存的访问,UCGUI其它接口函数采用模板默认的实现函数也不会造成性能的明显变差,其它接口函数不再改写优化。

最后在LCDTemplate.c中加入LCD驱动接口访问的模块头文件#include “lcd_rgb.h”即可。

3.3. GUI_X目录

GUI_X目录下保存了UCGUI扩展部分,GUI_X.c无需操作系统的支持,只需要系统时间OS_TimeMS一个变化的时间计数即可,UCGUI的延时函数如GUI_Delay()等都是以这个计时为标准的,可在用户代码中实现定时器时间计数。GUI启动前,除了LCD可能还有其它需初始化的硬件设备,例如UCGUI要用到LCD以及触摸屏,那么在GUI使用前就应先初始化这些设备,在GUI_X_Init()函数中实现如下:

void GUI_X_Init(void)

{

#if GUI_SUPPORT_TOUCH

  TP_Init();// 使用UCGUI时先初始化触摸屏

#endif

}

同时在此文件中加入TP接口模块访问的头文件#include"tp_ft5206.h"

GUI_X_Touch.c为UCGUI触摸屏访问接口,只要实现GUI_TOUCH_X_MeasureX()和GUI_TOUCH_X_MeasureY()即可。GUI_TOUCH_X_MeasureX要求如果有触按,应返回触摸屏X位置,否则返回无效的位置值(如-1)。GUI_TOUCH_X_MeasureY要求如果有触按,应返回触摸屏Y位置,否则返回无效的位置值(如-1)。这两个函数分别与电容屏模块获得第一个触摸点x,y位置的底层函数TP_GetPoint1_X()与TP_GetPoint1_Y()对应。由于UCGUI不支持多点触摸,因此在电容屏驱动模块中实现任何时候只返回第一个触摸的点即可。加入电容屏模块访问头文件#include “tp_ft5206.h”即可访问电容屏模块接口。GUI_X_Touch.c修改后的内容如下:

#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. 修改用户代码

4.1. LCD驱动模块实现

LCD驱动模块需提供设置某一坐标像素颜色接口LCD_SetPixel()和从某一坐标读出像素颜色接口LCD_GetPixel()。笔者用的RGB屏驱动模块实现在前面章节有详细的介绍,此处不再详述。lcd_rgb.c模块实现如下:

#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

 

// 帧缓存数据通过LCD DMA传输到接口,为保证数据的一致性,cpu每次写显存应直接访问主存,

// 即访问显存时应关cache或无效cache中的数据,分配no_cache段缓存并在MMU中关闭

// 对应区域内存的cache,以作DMA传输用,如LCD显存,IIS 音频DMA传输等,声明属性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配置为RGB数据[7:0]、控制功能   

    rGPDCON = 0xaaaaaaaa; // GPD配置为RGB[23:8]

    LCD_Enable(0);

 

    // 16bpp (R5-G6-B5),第一像素在内存低地址,选择buffer0

    rWINCON0 = (5<<2) | (1<<16) |(0<<23);

    rWINCON1 = (5<<2) | (1<<16) |(1<<6);  

    // 选择HCLK=100M,3分频得到VCLK=33.3M,RGB并口格式(RGB),暂不启动控制逻辑

    rVIDCON0 = (0<<22) |(0<<13) | (0<<12) | (2<<6) |

               (1<<5) | (1<<4) | (0<<2) |(0<<0);

    // VCLK下降沿锁存数据,行场同步信号低激活,数据使能高有效

    rVIDCON1 = (0<<7) |(1<<6) | (1<<5) | (0<<4);

    // 设置时序控制参数

    rVIDTCON0 =((VBPD-1)<<16) | ((VFPD-1)<<8) | ((VSPW-1)<<0);

    rVIDTCON1 = ((HBPD-1)<<16)| ((HFPD-1)<<8) | ((HSPW-1)<<0);

    // 设置屏幕像素尺寸

    rVIDTCON2 =((VSize-1)<<11) | ((HSize-1)<<0);

    // 设置OSD图像与屏幕尺寸一致

    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混合方式,基色匹配时全透明,未匹配部分完全不透明

    rVIDOSD1C = 0xfff000;

    // 设置帧缓存的地址

    rVIDW00ADD0B0 = (unsigned int)FrameBuffer;

    rVIDW00ADD1B0 = ((unsigned int)(FrameBuffer+ HSize*VSize) & 0xffffff);

    // 不使用虚拟屏幕

    rVIDW00ADD2B0 = (00<<13) | ((HSize*2)<<0);

    // 窗口0使用

    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];

}

 

 lcd_rgb.h模块头文件如下:

#ifndef __LCD_RGB_H__

#define __LCD_RGB_H__

 

#ifdef__cplusplus

extern"C" {

#endif

 

#define HSize   800// 水平行像素点

#define     VSize   480 // 垂直像素点

 

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. 电容屏驱动模块实现

触摸屏驱动模块在有触摸时,应返回触摸点的X位置以及触摸点的Y位置给UCGUI,如果没有触摸,可直接返回-1。这可通过获取第一个触摸点X位置函数TP_GetPoint1_X()和Y位置TP_GetPoint1_Y()实现。电容屏的驱动笔者在前面章节有详细的介绍,此处不再详述。由于UCGUI只支持单点触摸,电容屏中断输出配置成查询方式,通过查询中断线的电平状态来确定有无触摸事件。同时,电容屏基本都是IIC接口的,需要IIC驱动模块的支持,IIC驱动实现在前面章节有详细的介绍,此处不再详述。

电容屏tp_ft5206.c模块实现如下:

#include"s3c2416.h"

#include"IIC.h"

#include"tp_ft5206.h"

 

static voidDelay_ms(unsigned int nCount)

{

//延时1ms,共延时nCount(R0) ms

    __asm__ __volatile__ (

        "0:\n\t"   

        "ldr  r1, =100000\n\t"  // Arm clock为400M     

        "1:\n\t"

        "subs r1, r1, #1\n\t"  // 一个Arm clock

        "bne  1b\n\t"      // 跳转会清流水线,3个Armclock

        "subs %0, %0, #1\n\t" // 调用者确保nCount不为0

        "bne  0b\n\t"

        : : "r"(nCount) :"r1"

    );

}

 

voidTP_Reset()

{

    rGPFDAT &= ~ TP_RST; //位低复位线GPF5

    Delay_ms(20);

    rGPFDAT |= TP_RST;

    Delay_ms(200);

}

 

int TP_GetPoint1_X()

{

    unsigned char Point1_X[2];

    if (!(rGPGDAT &TP_INT)) { // 触屏按下时,INT拉低      

        // 调用IIC读,对电容屏内部某一地址进行连续读,获得12位X轴坐标

        IIC_ReadBytes(TP_SlaveAddr, TOUCH1_XH, Point1_X, 2);   

        if (!(rGPGDAT &TP_INT)) {

        //获得AD时应保持按下,不然AD值可能不准确,应丢弃

            return((((int)(Point1_X[0]&0xf)) << 8) | Point1_X[1]);

        }  

    }  

    return -1; //返回无效值,表未按下或释放了

}

 

int TP_GetPoint1_Y()

{

    unsigned char Point1_Y[2];

    if (!(rGPGDAT &TP_INT)) { // 触屏按下时,INT拉低      

        // 调用IIC读,对电容屏内部某一地址进行连续读,获得12位Y轴坐标

        IIC_ReadBytes(TP_SlaveAddr, TOUCH1_YH, Point1_Y, 2);   

        if (!(rGPGDAT &TP_INT)) {

        //获得AD时应保持按下,不然AD值可能不准确,应丢弃

            return((((int)(Point1_Y[0]&0xf)) << 8) | Point1_Y[1]);

        }  

    }  

    return -1; //返回无效值,表未按下或释放了

}

 

int TP_WriteBytes(unsigned char WriteAddr,unsigned char *pData,int Length)

{  

    int Ret;

    // 调用IIC接口写,对电容屏内部某一地址进行连续写

    Ret =IIC_WriteBytes(TP_SlaveAddr, WriteAddr, pData, Length);

    return Ret;

}

 

int TP_ReadBytes(unsignedchar ReadAddr, unsigned char *pData, int Length)

{

    int Ret;

    // 调用IIC接口读,对电容屏内部某一地址进行连续读

    Ret =IIC_ReadBytes(TP_SlaveAddr, ReadAddr, pData, Length);

    return Ret;

}

 

voidTP_Init()

{

    unsigned char InterruptMode;

    rGPGUDP &= ~(0x3 << 8);

    rGPGUDP |= (0x2 << 8); // TP_INT GPG4上拉  

    rGPGCON &= ~(0x3 << 8);

    rGPGCON |= (0x0 << 8); // GPG4配置成IO口输入,不使用中断方式

   

    rGPFUDP &= ~(0x3 << 10);

    rGPFUDP |= (0x2 << 10); // TP_RST GPF5上拉 

    rGPFCON &=~(0x3 << 10);

    rGPFCON |= (0x1 << 10);// GPF5配置成输出

   

    TP_Reset();

    // 按住TP时,TP不应多点上报(ucgui会认为连续多点按下),应电平触发 

    // TP设置成电平触发模式,此时不能多点识别,ucgui也只能单点

    InterruptMode = 0;

    // 电容屏设置成电平触发,一次按下产生一个中断信号

    TP_WriteBytes(ID_G_MODE,&InterruptMode, 1);

}

 

tp_ft5206.h模块头文件实现如下:

#ifndef __TP_FT5206_H__

#define __TP_FT5206_H__

 

#ifdef __cplusplus

extern"C" {

#endif

 

// TP IIC的7位从机地址

#define TP_SlaveAddr    0x38

#define TP_INT      (1<<4) // GPG4

#define TP_RST      (1<<5) // GPF5

   

#define TOUCH1_XH       0x03 // 触摸点1坐标X高4位寄存器地址

#define TOUCH1_XL       0x04 // 触摸点1坐标X低8位寄存器地址

#define TOUCH1_YH       0x05 // 触摸点1坐标Y高4位寄存器地址

#define TOUCH1_YL       0x06 // 触摸点1坐标Y低8位寄存器地址

#define ID_G_MODE       0xA4 // 中断模式控制寄存器

 

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实现

启动代码为用户设置了必要的运行环境后,就会跳转到main执行用户的c代码,UCGUI所有的测试代码在GUIDemo目录中,main函数再跳转到GUIDEMO_main()即可开始演示GUIDemo下所有的例程。在前面提到UCGUI延时实现需要一个计时标准,这里,我们在main.c中使用s3c2416的定时器4中断产生1ms的SystemTick为计时。同时,必须保证周期性(约100HZ)执行GUI_TOUCH_Exec(),UCGUI用来获得用户的触摸屏输入操作。

main.c的实现如下:

#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计数,在GUI_X.c中定义,用来UCGUI延时计数

    TP_Period++;

    if (TP_Period >= 10) { // 每隔10ms检查触摸屏输入

        TP_Period = 0;

        IRQ_Enable(); // 开启中断嵌套

        GUI_TOUCH_Exec();// 保证100HZ的触摸屏输入检查

    }

    rSRCPND1 |= (0x01 << INT_TIMER4);       // write 1 to clear

    rINTPND1 |= (0x01 << INT_TIMER4);       // write 1 to clear

}

 

void Timer4_Start()

{

    rTCON |= (0x1 << 20); // 定时器开启

}

 

void Timer4_Stop()

{

    rTCON &= ~(0x1 << 20); // 定时器停止

}

 

void Timer4_Init()

{

// 定时器4时钟频率为PCLK(66.66666M)/(0+1)/16=4.166MHZ

    rTCFG1 &= ~(0xf << 16);

    rTCFG1 |= (0x3 << 16);  // Timer4 16分频

    rTCFG0 &= ~(0xff << 8);

    rTCFG0 |= (0 << 8); // PCLK预分频为1

    rTCNTB4 = 4166; // System Tick设1ms

    rTCON |= (0x1 << 21); // 更新计数值

    rTCON &= ~(0x1 << 21); // 清除

    rTCON |= (0x1 << 22); // 自动重装载

   

    IRQ_Register(INT_TIMER4, Timer4_IRQ); // 注册Timer4中断函数

    rINTMOD1 &= ~(1 << INT_TIMER4); //Timer4 IRQ 模式

    rINTMSK1 &= ~(1 << INT_TIMER4); //Timer4开中断

}

 

int main()

{

    Timer4_Init();

    Timer4_Start();

    IIC_Init();// 电容屏用到IIC接口

    GUI_Init();// GUI初始化时会同时会初始化LCD屏和触摸屏

    while (1) {

        GUIDEMO_main(); // 调用UCGUI DEMO

    }

    return 0;

}

 

5. 设置工程

修改实现所有UCGUI移植接口后,最后就是加入工程中的源码,进行头文件搜索路径的设置,以及其它编译选择,生成输出文件的设置。对于MDK等可视化集成编译环境来说,以上设置都很容易操作,笔者不再细说MDK的工程设置,可以在文章末尾链接下载完整的MDK工程。

MDK移植UCGUI效果图:



关键字:S3C2416  裸机开发  GCC  UCGUI  移植 引用地址:S3C2416裸机开发系列十四_GCC下UCGUI的移植(1)

上一篇:S3C2416裸机开发系列十四_GCC下UCGUI的移植(2)
下一篇:S3C2416裸机开发系列十三_电容屏驱动实现

推荐阅读最新更新时间:2024-03-16 15:24

Linux-2.6.14内核在S3C2410上的移植
2.4内核由于本身并不支持2410,移植起来较为烦琐,所以直接上2.6的版本. 1.准备工作 下载解压交叉编译工具,2.6的内核编译要用3.4.1版本的(arm-linux-gcc-3.4.1)ftp://ftp.handhelds.org/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2 下载解压2.6.14.1内核 ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ . 之前文章已经说明不再赘述. 2.Flash分区管理 启动开发板,进入vivi,查看vivi的分区信息. 分区信息如下所示: 分区 起始地址 分区大小
[单片机]
3D打印肝脏“补丁”可延长移植患者寿命一两年
  在短短三年内,等待肝移植的患者可能能够捐赠健康细胞,并将它们通过 3D打印 机复制成可以延长其寿命的美元大小的组织。下面就随医疗电子小编一起来了解一下相关内容吧。 3D打印肝脏“补丁”可延长移植患者寿命一两年   位于圣地亚哥的生物打印公司Organovo已经表明,其 3D打印 的肝组织贴片在植入小鼠时继续发挥作用。那么下一步的研究将是人类。   据悉,这家开发生物打印过程的公司有着10年的历史,可以定制生产多种形式的组织,包括微型人体肝组织和肾组织。   Organovo的 3D打印 组织已被用于加速临床前药物测试。传统的测试和开发使用动物或放置在培养皿中的小细胞样品,平均花费12亿美元,需要十几年的时间。成本很高,部
[医疗电子]
Android平台移植应该做两步工作
    Android系统的移植工作的目的是为了在特定的硬件上运行Android系统。在移植的过程中,把握关键要点,减少工作量是一个重要的方面。从工作的角度,通常的方法为,首先要熟悉硬件抽象层的接口,其次要集成和复用已有的驱动程序,主要的工作量在硬件抽象层的实现中。为了更好地理解和调试系统,也应该适当地了解上层对硬件抽象层的调用情况。     移植方面主要的工作有两个部分:     Linux驱动     Android系统硬件抽象层     Linux中的驱动工作在内核空间,Android系统硬件抽象层工作在用户空间,有了这两个部分的结合,就可以让庞大的Android系统运行在特定的硬件平台上。     Androi
[嵌入式]
51上移植ucosii的心得
  自嵌进式系统开发以来,很长时间都采用前后台系统软件设计模式:主程序为一个无穷循环,单任务顺序执行。通过设置一个或多个中断来处理异步事件。   这种系统对于简单的应用是可以的,但对于实时性要求比较高的、处理任务较多的应用,就会暴露出实时性差、系统可靠性低、稳定性差等缺点。    μC/OS-II 是一种基于优先级的抢占式多 任务实时操纵系统,包含了实时内核、任务治理、时间治理、任务间通讯同步(信号量,邮箱,消息队列)和内存治理等功能。它可以使各个任务独立工作,互不干 涉,很轻易实现准时而且无误执行,使实时应用程序的设计和扩展变得轻易,使应用程序的设计过程大为减化。而且它内核源代码公然,可移植性强,为编程职员提 供了很好的一
[单片机]
带全速USB接口的PIC18F4550应用设计
引 言 随着USB(Universal Serial Bus)技术的发展,特别是高速(480 Mbps)USB2.0协议的出现,几乎所有的PC外设都可以移植到USB上,所以USB的PC外设的发展空间是巨大的,甚至在不久的将来,USB将完全取代异步串口和打印机并口,PC机厂商将不会再生产机箱上带异步串口和打印机并口的PC机了,机箱上也不会再有那么多的连线了。 USB是一种快速的、双向同步传输的、廉价并可以进行热插拔的串行接口。利用USB总线技术,开发适用于科学研究和工业牛产的各种仪器仪表设备,借以取代传统计算机测控系统中采用串行RS232或并行接口的仪器仪表设备,使计算机测控系统更加高效实时,方便灵活。 利用USB总线的数据采
[单片机]
OpenCV2.0.0移植到ARM9(五)(JZ2440----S3c2440)
Linux系统:Ubuntu9.10 交叉编译器:arm-linux-gcc-4.3.2(已安装) Qt:qt-x11-opensource-src-4.5.3.tar.gz qt-embedded-linux-opensource-src-4.5.3.tar.gz 1、安装Qt Qt下载地址:https://www.qt.io/download-open-source/ 这里下载的安装包为:qt-embedded-linux-opensource-src-4.5.3.tar.gz(大小123MB) 2、安装Qt-x11 将qt-x11-opensource-src-4.5.3.tar.gz包放到U
[单片机]
OpenCV2.0.0<font color='red'>移植</font>到ARM9(五)(JZ2440----S3c2440)
ARM裸机开发笔记1(指令简介)
1.非常简单的ARM程序: arm.s文件内容 AREA Example,CODE,READONLY ;声明代码段 AREA:定义代码段 Example是代码段名称CODE:代码段关键字READONLY:只读关键字 ENTRY ;相当于C程序中的main函数,标识程序的入口 CODE32 ;使用32位指令集 START MOV R0,#1 ;具体的汇编指令 MOV R0,#0
[单片机]
stm32+ucos+ucgui 中edit框读取AD值以十进制显示
初始化 case WM_INIT_DIALOG: hEdit0 = WM_GetDialogItem(hDlg, GUI_ID_EDIT0); //创建Dialog hRadio = WM_GetDialogItem(hDlg, GUI_ID_RADIO0); //创建Dialog //EDIT_SetDecMode(hEdit0, 0, 0, 5000, 0, 0); /* Select decimal mode */ EDIT_SetMaxLen(hEdit0,4); //此句要进行设置edit 默认显示3位数 //WM_DisableWindow(hItem); RADIO_SetVa
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved