前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【第3版emWin教程】第54章 emWin6.x的按钮Button控件显示位图和流位图(QSPI Flash存储)

【第3版emWin教程】第54章 emWin6.x的按钮Button控件显示位图和流位图(QSPI Flash存储)

作者头像
Simon223
发布2022-03-10 13:05:55
6120
发布2022-03-10 13:05:55
举报

第54章 emWin6.x的按钮Button控件显示位图和流位图(QSPI Flash存储)

本章节为大家讲解按钮控件显示位图和流位图的方法,之所以做这章节是因为太多初学者问这方面的问题,所以专门做一下。

学习本章节前,务必保证已经学习了第15章和第17章。

54.1 初学者重要提示

54.2 按钮控件显示位图的方法

54.3 按钮控件显示流位图的方法

54.4 官方WIDGET_PhoneButton.c实例讲解

54.5 实验例程说明(RTOS)

54.6 实验例程说明(裸机)

54.7 总结

54.1 初学者重要提示

  1. 按钮控件上面显示位图或者流位图,显示速度是最快的,因为与BMP,JPEG,PNG,GIF格式的图片不同,流位图和位图已经是原始的图片数据,不需要进行解码就可以立即进行显示。实战性还是很强的。
  2. 按钮控件的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数位置:

下图是英文版手册里面API函数的位置:

54.2 下载算法存放位置(操作前必看)

(注:例子下载地址 http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

编译例子:V7-060_QSPI Flash的MDK下载算法制作,生成的算法文件位于此路径下:

生成算法文件后,需要大家将其存到到MDK安装目录,有两个位置可以存放,任选其一,推荐第2种:

  • 第1种:存放到MDK的STM32H7软包安装目录里面:\Keil\STM32H7xx_DFP\2.6.0\CMSIS\Flash(软包版本不同,数值2.6.0不同)。
  • 第2种:MDK的安装目录 \ARM\Flash里面。

54.3 按钮控件显示位图的方法

C文件格式的位图生成方法已经在第15章详细进行了讲解:

代码语言:javascript
复制
#include "DIALOG.h"


/*
*********************************************************************************************************
*                                         图片位图数据
*********************************************************************************************************
*/
static GUI_CONST_STORAGE unsigned long _acpic1[] = {
  0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        /* 后面的数据未列出 */
};

GUI_CONST_STORAGE GUI_BITMAP bmpic1 = {  //--------------(1)
  64, // xSize
  64, // ySize
  256, // BytesPerLine
  32, // BitsPerPixel
  (unsigned char *)_acpic1,  // Pointer to picture data
  NULL,  // Pointer to palette
  GUI_DRAW_BMP8888
}

/*
*********************************************************************************************************
*                                         宏定义
*********************************************************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0   (GUI_ID_USER + 0x01)


/*
*********************************************************************************************************
*                           GUI_WIDGET_CREATE_INFO类型数组
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 
{
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  { BUTTON_CreateIndirect,   "",         ID_BUTTON_0, 30, 30, 100, 100, 0, 0x0, 0 },  //--------------(2)
};

/*
*********************************************************************************************************
*    函 数 名: _cbDialog
*    功能说明: 对话框回调函数        
*    形    参: pMsg  回调参数 
*    返 回 值: 无
*********************************************************************************************************
*/
static void _cbDialog(WM_MESSAGE * pMsg) 
{
    WM_HWIN hItem;
    int     NCode;
    int     Id;

    switch (pMsg->MsgId) 
    {
        case WM_INIT_DIALOG:
            //
            // 初始化框架窗口
            //
            hItem = pMsg->hWin;
            FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
            FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
            FRAMEWIN_SetText(hItem, "armfly");
            
            //
            // 初始化按钮控件
            //
            hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); //--------------(3)
            BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); //--------------(4)
            BUTTON_SetBitmapEx(hItem, BUTTON_BI_UNPRESSED, &bmpic1, 18, 18); //--------------(5)
            break;

        case WM_NOTIFY_PARENT:
            Id    = WM_GetId(pMsg->hWinSrc);
            NCode = pMsg->Data.v;
            switch(Id) 
            {
                case ID_BUTTON_0: 
                    switch(NCode) 
                    {
                        case WM_NOTIFICATION_CLICKED:
                            break;

                        case WM_NOTIFICATION_RELEASED:
                            break;
                    }
                    break;
            }
            break;

        default:
        WM_DefaultProc(pMsg);
        break;
    }
}

/*
*********************************************************************************************************
*    函 数 名: CreateFramewin
*    功能说明: 创建对话框        
*    形    参: 无
*    返 回 值: 返回对话框句柄
*********************************************************************************************************
*/
WM_HWIN CreateFramewin(void) {
  WM_HWIN hWin;

  hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  return hWin;
}

/*
*********************************************************************************************************
*    函 数 名: MainTask
*    功能说明: GUI主函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void) 
{
     /* 初始化 */
    GUI_Init();

    /* 窗口自动使用存储设备 */
    WM_SetCreateFlags(WM_CF_MEMDEV);

    /* 创建对话框,使用GUIBulder生成的对话框创建函数 */
    CreateFramewin();

    while(1)
    {
        GUI_Delay(10);
    }
}

本例子实现的功能相对比较简单,主要实现了在对话框上面创建一个按钮控件,并在按钮控件上面显示一个位图。

  1. 使用小软件BmpCvt生成的C文件格式位图数据,分辨率64*64,位图格式ARGB8888。
  2. 在对话框的资源列表中创建一个按钮控件。
  3. 通过函数WM_GetDialogItem获得对话框上ID为ID_BUTTON_0的按钮控件句柄。
  4. 通过函数BUTTON_SetFont设置按钮控件ID_BUTTON_0的字体。
  5. 通过函数BUTTON_SetBitmapEx设置按钮控件未被按下时显示的位图。通过此函数的第二个参数可以设置按钮在按下(BUTTON_BI_PRESSED),未按下(BUTTON_BI_UNPRESSED)和禁止状态(BUTTON_BI_DISABLED)显示的位图。最后两个参数是用来设置位图在按钮中的显示位置,坐标位置是相对按钮的坐标位置。emWin手册中还有一个位图显示函数BUTTON_SetBitmap,比函数BUTTON_SetBitmapEx少了最后两个坐标位置的参数。

实际显示效果如下,分辨率800*480:

54.4 按钮控件显示流位图的方法

实际项目中使用流位图还是非常有优势的,因为我们可以将流位图存储到任何外部存储器中,但在使用的时候建议将流位图加载到SDRAM或者SRAM中,这样将大大加速流位图的绘制,实际项目中也推荐大家这样做。

流位图位图生成方法已经在第17章详细进行了讲解,这里不再赘述。将加载到emWin动态内存的流位图显示到按钮控件。这里是将流位图转换成位图进行显示:

方法1:GUI_CreateBitmapFromStream(&Bitmap, &Palette, _acBuffer);

BUTTON_SetBitmapEx(hItem, BUTTON_CI_UNPRESSED, &Bitmap, 10, 10);

方法2:GUI_CreateBitmapFromStream(&Bitmap, &Palette, _acBuffer);

BUTTON_SetBitmap(hItem, BUTTON_CI_UNPRESSED, &Bitmap);

函数BUTTON_SetBitmapEx和函数BUTTON_SetBitmap是一样的,只是多了两个位图在按钮中显示位置的参数。

结合第1步的函数,在按钮中显示位图的代码如下:

代码语言:javascript
复制
#include "MainTask.h"
#include "includes.h"

/*
*********************************************************************************************************
*                                         变量
*********************************************************************************************************
*/
GUI_HMEM hMemButtonStreamBitmap;
GUI_BITMAP Bitmap;


/*
*********************************************************************************************************
*                                         宏定义
*********************************************************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0   (GUI_ID_USER + 0x01)


/*
*********************************************************************************************************
*                           GUI_WIDGET_CREATE_INFO类型数组
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 
{
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  { BUTTON_CreateIndirect, "", ID_BUTTON_0, 30, 30, 100, 100, 0, 0x0, 0 },  //--------------(1)
};

/*
*********************************************************************************************************
*    函 数 名: _cbDialog
*    功能说明: 对话框回调函数        
*    形    参: pMsg  回调参数 
*    返 回 值: 无
*********************************************************************************************************
*/
static void _cbDialog(WM_MESSAGE * pMsg) 
{
    WM_HWIN hItem;
    int     NCode;
    int     Id;
    char *_acBuffer;
    GUI_LOGPALETTE Palette;


    switch (pMsg->MsgId) 
    {
        case WM_INIT_DIALOG:
            
            //
            // 初始化框架窗口
            //
            hItem = pMsg->hWin;
            FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
            FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
            FRAMEWIN_SetText(hItem, "armfly");
        
            //
            // 初始化按钮控件
            //
            hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);               //--------------(1)
            GUI_CreateBitmapFromStream(&Bitmap, &Palette, _ _acpic1);         //--------------(2)
            BUTTON_SetBitmapEx(hItem, BUTTON_CI_UNPRESSED, &Bitmap, 18, 18); //--------------(3)
            break;
        
        case WM_NOTIFY_PARENT:
            Id    = WM_GetId(pMsg->hWinSrc);
            NCode = pMsg->Data.v;
            switch(Id) 
            {
                case ID_BUTTON_0:
                    switch(NCode) 
                    {
                        /* 点击此按钮后,LED2点亮 */
                        case WM_NOTIFICATION_CLICKED:
                            bsp_LedOn(2);
                            break;
                        
                        /* 松手后,LED2熄灭 */                        
                        case WM_NOTIFICATION_RELEASED:
                            bsp_LedOff(2);
                            break;
                    }
                    break;
                
            }
            break;
            
        default:
            WM_DefaultProc(pMsg);
            break;
    }
}

/*
*********************************************************************************************************
*    函 数 名: CreateFramewin
*    功能说明: 创建对话框        
*    形    参: 无
*    返 回 值: 返回对话框句柄
*********************************************************************************************************
*/
WM_HWIN CreateFramewin(void) 
{
    WM_HWIN hWin;

    hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);

    return hWin;
}

/*
*********************************************************************************************************
*    函 数 名: MainTask
*    功能说明: GUI主函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void) 
{
    
    /* 初始化 */
    GUI_Init();
    
    /*
     关于多缓冲和窗口内存设备的设置说明
       1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
          WM_MULTIBUF_Enable(1);
       2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
       3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
          STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
          感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
       4. 所有emWin例子默认是开启三缓冲。
    */
    WM_MULTIBUF_Enable(1);
    
    /*
       触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
       此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
    */
    //TOUCH_Calibration();
    
    
    /* 创建对话框 */
    CreateFramewin();
    
        
    while(1) 
    {
        GUI_Delay(10);
    }
}

这里讲解的显示方法也是本章节配套例子使用的方法,下面把几个重要的地方跟大家解释下。

  1. 在对话框的资源列表中创建一个按钮控件。
  2. 通过函数WM_GetDialogItem获得对话框上ID为ID_BUTTON_0的按钮控件句柄。
  3. 通过函数GUI_CreateBitmapFromStream将流位图转换成位图,使用这个函数特别注意要将变量GUI_BITMAP Bitmap设置成全局变量,因为这个变量要在按钮的操作过程一直调用,如果设置成局部变量的话,退出函数后此变量的内存空间就被释放了。
  4. 通过函数BUTTON_SetBitmapEx设置按钮控件未被按下时显示的位图。通过此函数的第二个参数可以设置按钮在按下(BUTTON_BI_PRESSED),未按下(BUTTON_BI_UNPRESSED)和禁止状态(BUTTON_BI_DISABLED)显示的位图。最后两个参数是用来设置位图在按钮中的显示位置,坐标位置是相对按钮的坐标位置。emWin手册中还有一个位图显示函数BUTTON_SetBitmap,比函数BUTTON_SetBitmapEx少了最后两个坐标位置的参数。

54.5 内部Flash和QSPI Flash程序调试下载配置(重要必看)

将下面两个地方配置后,就可以像使用内部Flash一样使用QSPI Flash进行调试了。并且这种方式可以方便的调试程序,内部Flash和外部Flash都做调试。

54.5.1 将字库文件转换为C数组格式文件

为了方便将bin文件添加到MDK工程中,我们这里使用小软件B2C.exe将其转换为C格式文件(此软件已经放到本章配套例子V7-572_emWin6.x实验_Button按钮控件显示流位图(QSPI Flash RTOS)的Doc文件里面。

转换后生成的文件命名为pic1.c:

代码语言:javascript
复制
const unsigned char _acpic1[16400UL + 1] = {
  0x42, 0x4D, 0x10, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
  0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
  0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,  
  省略未写

}

54.5.2 设置字库文件到外部QSPI Flash。

下面将流位图文件下载到QSPI Flash,需要大家先在这里添加QSPI Flash地址范围:

然后设置资源文件到外部QSPI Flash:鼠标右击文件分组GUI/PIC,选择Options。

54.5.3 下载配置

注意这里一定要够大,否则会提示算法文件无法加载:

我们这里是将其加到DTCM中,即首地址为0x20000000,大家也可以存储到任意其它RAM地址,只要空间还够加载算法文件即可。推荐使用AXI SRAM(地址0x24000000),因为这块RAM空间足够大。

如果要下载程序到内部Flash和外部QSPI Flash里面,需要做如下配置,两个下载算法都要添加进来:

54.6 官方WIDGET_PhoneButton实例讲解

这个DEMO在模拟器中的位置:

主要功能介绍:

这个例子主要是在按钮上面显示图片,演示一种简单的来电话情景,重点还是按钮位图显示函数BUTTON_SetBitmapEx的使用。

程序代码如下:

代码语言:javascript
复制
#include "GUI.h"
#include "BUTTON.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Recommended memory to run the sample with adequate performance
//
#define RECOMMENDED_MEMORY (1024L * 5)

/*******************************************************************
*
*       static variables
*
********************************************************************
*/
/*******************************************************************
*
*       Bitmap data, 3 phone logos
*/
static const GUI_COLOR Colors[] = { 0x000000, 0xFFFFFF }; 

static const GUI_LOGPALETTE Palette = { 2, 1, Colors };

static const unsigned char acPhone0[] = {
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  ________, ________, ________, ________,
  _____XXX, XXXXXXXX, XXXXXXXX, XXX_____,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  __XXXXXX, XXXXXXXX, XXXXXXXX, XXXXXX__,
  _XXXXXXX, X_______, _______X, XXXXXXX_,
  _XXXXXXX, X__XX___, ___XX__X, XXXXXXX_,
  _XXXXXXX, X__XX___, ___XX__X, XXXXXXX_,
  _XXXXXXX, X__XX___, ___XX__X, XXXXXXX_,
  ________, ___XX___, ___XX___, ________,
  _______X, XXXXXXXX, XXXXXXXX, X_______,
  ______XX, XXXXXXXX, XXXXXXXX, XX______,
  _____XXX, XXXX__X_, _X__XXXX, XXX_____,
  ____XXXX, XXXX__X_, _X__XXXX, XXXX____,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___
};

static const unsigned char acPhone1[] = {
  ________, ________, ________, ________,
  ______XX, X_______, ________, ________,
  ____XXXX, XXXXX___, ________, ________,
  ____XXXX, XXXXXXX_, ________, ________,
  ___XXXXX, XXXXXXXX, X_______, ________,
  ___XXXXX, XXXXXXXX, XXX_____, ________,
  _____XXX, XXXX_XXX, XXXXX___, ________,
  _______X, XXXX___X, XXXXXXX_, ________,
  ________, _XX_____, _XXXXXXX, X_______,
  ________, ________, ___XXXXX, XXX_____,
  ________, ________, _____XXX, XXXXX___,
  ________, ________, _______X, XXXXXX__,
  ________, ________, ________, XXXXXXX_,
  ________, ________, ________, XXXXXXX_,
  ________, ________, _______X, XXXXXXXX,
  ________, ___XX___, ___XX__X, XXXXXXXX,
  ________, ___XX___, ___XX___, _XXXXXXX,
  ________, ___XX___, ___XX___, ___XXXX_,
  ________, ___XX___, ___XX___, _____XX_,
  _______X, XXXXXXXX, XXXXXXXX, X_______,
  ______XX, XXXXXXXX, XXXXXXXX, XX______,
  _____XXX, XXXX__X_, _X__XXXX, XXX_____,
  ____XXXX, XXXX__X_, _X__XXXX, XXXX____,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___
};

static const unsigned char acPhone2[] = {
  ________, ________, ________, ________,
  ________, ________, _______X, XX______,
  ________, ________, ___XXXXX, XXXX____,
  ________, ________, _XXXXXXX, XXXX____,
  ________, _______X, XXXXXXXX, XXXXX___,
  ________, _____XXX, XXXXXXXX, XXXXX___,
  ________, ___XXXXX, XXX_XXXX, XXX_____,
  ________, _XXXXXXX, X___XXXX, X_______,
  _______X, XXXXXXX_, _____XX_, ________,
  _____XXX, XXXXX___, ________, ________,
  ___XXXXX, XXX_____, ________, ________,
  __XXXXXX, X_______, ________, ________,
  _XXXXXXX, ________, ________, ________,
  _XXXXXXX, ________, ________, ________,
  XXXXXXXX, X_______, ________, ________,
  XXXXXXXX, X__XX___, ___XX___, ________,
  XXXXXXX_, ___XX___, ___XX___, ________,
  _XXXX___, ___XX___, ___XX___, ________,
  _XX_____, ___XX___, ___XX___, ________,
  _______X, XXXXXXXX, XXXXXXXX, X_______,
  ______XX, XXXXXXXX, XXXXXXXX, XX______,
  _____XXX, XXXX__X_, _X__XXXX, XXX_____,
  ____XXXX, XXXX__X_, _X__XXXX, XXXX____,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXX__X_, _X__XXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___,
  ___XXXXX, XXXXXXXX, XXXXXXXX, XXXXX___
};

static const GUI_BITMAP bm_1bpp_0 = { 32, 31, 4, 1, acPhone0, &Palette};  //--------------(1)
static const GUI_BITMAP bm_1bpp_1 = { 32, 31, 4, 1, acPhone1, &Palette};
static const GUI_BITMAP bm_1bpp_2 = { 32, 31, 4, 1, acPhone2, &Palette};

/*******************************************************************
*
*       static code
*
********************************************************************
*/
/*******************************************************************
*
*       _Wait
*/
static int _Wait(int Delay) {  //--------------(2)
  int EndTime;
  int r;

  r = 1;
  EndTime = GUI_GetTime() + Delay;
  while (GUI_GetTime() < EndTime) {
    GUI_Exec();
    if (GUI_GetKey() == GUI_ID_OK) {
      r = 0;
      break;
    }
  }
  return r;
}

/*******************************************************************
*
*       _DemoButton
*/
static void _DemoButton(void) {
  BUTTON_Handle hButton;

  GUI_SetFont(&GUI_Font8x16);
  GUI_DispStringHCenterAt("Click on phone button...", 160,80);
  GUI_Delay(500);
  //
  // Create the button and modify its attributes
  //
  hButton = BUTTON_Create(142, 100, 36, 40, GUI_ID_OK, WM_CF_SHOW); //--------------(3)
  BUTTON_SetBkColor (hButton, 1, GUI_RED);
  //
  // Loop until button is pressed
  //
  while (1) {
    BUTTON_SetBitmapEx(hButton, 0, &bm_1bpp_1, 2, 4); //--------------(4)
    BUTTON_SetBitmapEx(hButton, 1, &bm_1bpp_1, 2, 4);
    if (!_Wait(50)) break;
    BUTTON_SetBitmapEx(hButton, 0, &bm_1bpp_0, 2, 4);
    BUTTON_SetBitmapEx(hButton, 1, &bm_1bpp_0, 2, 4);
    if (!_Wait(45)) break;
    BUTTON_SetBitmapEx(hButton, 0, &bm_1bpp_2, 2, 4);
    BUTTON_SetBitmapEx(hButton, 1, &bm_1bpp_2, 2, 4);
    if (!_Wait(50)) break;
    BUTTON_SetBitmapEx(hButton, 0, &bm_1bpp_0, 2, 4);
    BUTTON_SetBitmapEx(hButton, 1, &bm_1bpp_0, 2, 4);
    if (!_Wait(45)) break;
  }
  BUTTON_SetBitmapEx(hButton, 0, &bm_1bpp_1, 2, 4);
  BUTTON_SetBitmapEx(hButton, 1, &bm_1bpp_1, 2, 4);
  GUI_ClearRect(0, 80, 319, 120);
  GUI_DispStringHCenterAt("You have answered the telephone", 160, 145);
  GUI_Delay(2000);
  //
  // Delete button object
  //
  WM_DeleteWindow(hButton);
  GUI_ClearRect(0, 50, 319, 239);
  GUI_Delay(400);
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       MainTask
*/
void MainTask(void) {
  GUI_Init();
  //
  // Check if recommended memory for the sample is available
  //
  if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
    GUI_ErrorOut("Not enough memory available."); 
    return;
  }
  GUI_SetBkColor(GUI_BLACK);
  GUI_Clear();
  GUI_SetColor(GUI_WHITE);
  GUI_SetFont(&GUI_Font24_ASCII);
  GUI_DispStringHCenterAt("WIDGET_PhoneButton - Sample", 160, 5);
  while (1) {
    _DemoButton();
  }
}
  1. 用于按钮上面显示的三种位图。
  2. 按键时间等待函数,这个函数设计的比较巧妙,大家可以学习下。这个函数的主要功能是在函数形参设置的时间范围内,ID为GUI_ID_OK的按钮还没有按下,那么返回1,在设置的时间内按下了,返回0。
  3. 通过函数BUTTON_Create将按钮创建到桌面窗口。
  4. 通过函数BUTTON_SetBitmapEx设置按钮控件显示的位图。通过此函数的第二个参数可以设置按钮在按下(BUTTON_BI_PRESSED,用数值表示的话是数字1),未按下(BUTTON_BI_UNPRESSED,用数值表示的话是数字0)和禁止状态(BUTTON_BI_DISABLED,用数值表示的话是数字2)显示的位图。最后两个参数是用来设置位图在按钮中的显示位置,坐标位置是相对按钮的坐标位置。emWin手册中还有一个位图显示函数BUTTON_SetBitmap,比函数BUTTON_SetBitmapEx少了最后两个坐标位置的参数

显示效果如下:

54.7 实验例程说明(RTOS)

配套例子:

V7-572_emWin6.x实验_Button按钮控件显示流位图(QSPI Flash RTOS)

实验目的:

  1. 本实验主要学习按钮控件显示流位图的方法
  2. emWin功能的实现在MainTask.c文件里面。

实验内容:

1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。

2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串口打印信息,如果使用RTT打印信息:

MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

#define Enable_RTTViewer 1

4、各个任务实现的功能如下:

App Task Start 任务 :启动任务,这里用作BSP驱动包处理。

App Task MspPro任务 :消息处理,这里用作LED闪烁。

App Task UserIF 任务 :按键消息处理。

App Task COM 任务 :暂未使用。

App Task GUI 任务 :GUI任务。

μCOS-III任务调试信息(按K1按键,串口打印):

RTT 打印信息方式:

程序设计:

任务栈大小分配:

μCOS-III任务栈大小在app_cfg.h文件中配置:

#define APP_CFG_TASK_START_STK_SIZE 512u

#define APP_CFG_TASK_MsgPro_STK_SIZE 2048u

#define APP_CFG_TASK_COM_STK_SIZE 512u

#define APP_CFG_TASK_USER_IF_STK_SIZE 512u

#define APP_CFG_TASK_GUI_STK_SIZE 2048u

任务栈大小的单位是4字节,那么每个任务的栈大小如下:

App Task Start 任务 :2048字节。

App Task MspPro任务 :8192字节。

App Task UserIF 任务 :2048字节。

App Task COM 任务 :2048字节。

App Task GUI 任务 :8192字节。

系统栈大小分配:

μCOS-III的系统栈大小在os_cfg_app.h文件中配置:

#define OS_CFG_ISR_STK_SIZE 512u

系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB

emWin动态内存配置:

GUIConf.c文件中的配置如下:

代码语言:javascript
复制
#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

emWin界面显示效果:

800*480分辨率界面效果。

54.8 实验例程说明(裸机)

配套例子:

V7-571_emWin6.x实验_Button按钮控件显示流位图(QSPI Flash 裸机)

实验目的:

  1. 本实验主要学习按钮控件显示流位图的方法。
  2. emWin功能的实现在MainTask.c文件里面。

emWin界面显示效果:

800*480分辨率界面效果。

emWin动态内存配置:

GUIConf.c文件中的配置如下:

代码语言:javascript
复制
#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

54.9 总结

本章教程主要为大家讲解了按钮控件显示位图和流位图的方法,非常具有实战价值,望初学者多做练习,务必要掌握。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-12-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第54章 emWin6.x的按钮Button控件显示位图和流位图(QSPI Flash存储)
    • 54.1 初学者重要提示
      • 54.2 下载算法存放位置(操作前必看)
        • 54.3 按钮控件显示位图的方法
          • 54.4 按钮控件显示流位图的方法
            • 54.5 内部Flash和QSPI Flash程序调试下载配置(重要必看)
              • 54.5.1 将字库文件转换为C数组格式文件
              • 54.5.2 设置字库文件到外部QSPI Flash。
              • 54.5.3 下载配置
            • 54.6 官方WIDGET_PhoneButton实例讲解
              • 54.7 实验例程说明(RTOS)
                • 54.8 实验例程说明(裸机)
                  • 54.9 总结
                  相关产品与服务
                  对象存储
                  对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档