[3rd Edition EMWIN tutorial] Chapter 57 emwin6 X cool clock dial design, combined with hardware RTC

Time:2022-5-11

The tutorial is constantly updated:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

Chapter 57: emwin6 X cool clock dial design, combined with hardware RTC

This chapter explains the cool clock in EMWIN, combined with hardware RTC.

57.1 # important tips for beginners

57.2 step 1: generate bitmap with relevant icons

57.3 step 2: develop storage devices

57.4 step 3, initialize the storage device

57.5 step 4, create the clock dial window

57.6 step 5: implementation of the most critical window callback function

57.7 experimental routine description (RTOS)

57.8 experimental routine description (bare metal)

57.9 summary

 

 

57.1 important tips for beginners

1. The key of EMWIN to realize the clock dial is the real-time icon rotation, that is, the function GUI_ MEMDEV_ Implementation of rotatehq.

57.2 step 1: generate bitmap with relevant icons

The original image of the bitmap has been saved in the doc folder of the supporting examples of this chapter’s tutorial. For the generation method of the bitmap, see Chapter 15 of this chapter’s tutorial. Here we choose the following format. The clock dial, hour hand, minute hand and second hand are the same settings:

57.3 step 2: develop storage devices

We will open up five storage devices here, all of which are 250 * 250 in size. Pay special attention to the 8888 color format with alpha channel for the storage device format.

/*Storage device required for clock dial*/
hMemBK = GUI_MEMDEV_CreateFixed(0,0, bmclock_classic_background.XSize, bmclock_classic_background.YSize,
 GUI_MEMDEV_HASTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);
    
    /*Storage device required for second hand of clock*/
hMemSec = GUI_MEMDEV_CreateFixed(0,0, bmclock_classic_background.XSize, bmclock_classic_background.YSize,
 GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);

    /*Storage device required for clock minute hand*/
hMemMin = GUI_MEMDEV_CreateFixed(0, 0, bmclock_classic_background.XSize, 
bmclock_classic_background.YSize,
 GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);

    /*Storage device required for clock hour*/
hMemHour = GUI_MEMDEV_CreateFixed(0, 0, bmclock_classic_background.XSize, 
bmclock_classic_background.YSize, 
GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);
 
    /*Storage device required for clock purpose storage*/
    hMemDST =GUI_MEMDEV_Cr

57.4 step 3, initialize the storage device

Here we need to initialize a value for the storage device, which is convenient for us to rotate the pointer later:

/*Draw the clock dial to the storage device*/
    GUI_MEMDEV_Select(hMemBK);
    GUI_SetBkColor(GUI_TRANSPARENT);
    GUI_Clear();
    GUI_DrawBitmap(&bmclock_classic_background, 0, 0); 
    GUI_MEMDEV_Select(0);
 
    /*Draw the second hand to the storage device*/
    GUI_MEMDEV_Select(hMemSec);
    GUI_SetBkColor(GUI_TRANSPARENT);
    GUI_Clear();
    GUI_DrawBitmap(&bmclock_standard_second_hand, 
                    0, 
                    0); 
    GUI_MEMDEV_Select(0);

    /*Draw minute hand to storage device*/
    GUI_MEMDEV_Select(hMemMin);
    GUI_SetBkColor(GUI_TRANSPARENT);
    GUI_Clear();
    GUI_DrawBitmap(&bmclock_standard_minute_hand, 0, 0);              
    GUI_MEMDEV_Select(0);

    /*Draw the hour hand to the storage device*/
    GUI_MEMDEV_Select(hMemHour);
    GUI_SetBkColor(GUI_TRANSPARENT);
    GUI_Clear();
    GUI_DrawBitmap(&bmclock_standard_hour_hand, 
                    0, 
                    0); 
                    
    GUI_MEMDEV_Select(0);
  • In particular, we have skills in drawing here. Since we are transparent pictures with alpha channel, we need to call the function GUI to draw to the storage device_ SetBkColor(GUI_TRANSPARENT),GUI_ Clear(), otherwise the drawn picture has a black background.

57.5 step 4, create the clock dial window

For example, to facilitate transplantation and management, we create the clock dial into a separate window:

/*Create a window to draw the clock*/
    WM_CreateWindowAsChild((xSize - bmclock_classic_background.XSize)/2 , 
                           (ySize - bmclock_classic_background.YSize)/2, 
                           bmclock_classic_background.XSize,
                           bmclock_classic_background.YSize, 
                           WM_HBKWIN, 
                           WM_CF_SHOW, 
                           _cbClock, 
                           0);

57.6 step 5: implementation of the most critical window callback function

The code implementation is as follows:

/*
*********************************************************************************************************
*Function name: cam_ Stop
*Function Description: stop DMA and DCMI
*Formal parameter: None
*Return value: None
*********************************************************************************************************
*/
#include "MainTask.h"
void CAM_Stop(void)
{
    HAL_DCMI_Stop(&hdcmi);
}

void DMA1_Stream7_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_dcmi);
}

void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
    /*Turn off the camera*/
    CAM_Stop();
    WM_SendMessageNoPara(hWinMainTask, MSG_CAMERA);
    g_ tCam. CaptureOk = 1;        /*  Indicates the end of DMA transfer*/
}

/*
*********************************************************************************************************
*Function name:_ cbDialog
*Function Description: dialog box callback function        
*Formal parameter: PMSG callback parameter 
*Return value: None
*********************************************************************************************************
*/
static void _cbDialog(WM_MESSAGE * pMsg) 
{
    static  WM_HTIMER hTimerCAMERA;

    switch (pMsg->MsgId) 
    {
        /*Camera data received*/
        case MSG_CAMERA:
            hTimerCAMERA = WM_CreateTimer(pMsg->hWin, ID_TimerCAMERA, 2, 0);    
            break;
        
        case WM_TIMER:
            /*Delete timer*/
            WM_DeleteTimer(hTimerCAMERA);
        
            /*Select operation window*/
            WM_SelectWindow(hWinMainTask);
        
            /*Cache clean and invalidation*/
            SCB_CleanInvalidateDCache();
        
            /*Draw to multi buffer*/
            GUI_MULTIBUF_Begin();
            //g_tCam.CaptureOk = 0;
            GUI_MEMDEV_WriteAt(hMem, 0, 0);
            GUI_MULTIBUF_End();
        
            WM_SelectWindow(WM_HBKWIN);
        
            /*Start next drawing*/
            CAM_Start1(uiDispMemAddr);    
            break;

        default:
            WM_DefaultProc(pMsg);
            break;
    }
}

/*
*********************************************************************************************************
*Function name:_ cbClock
*Function Description: clock callback function
*Formal parameter: PMSG window callback message
*Return value: None
*********************************************************************************************************
*/
static void _cbClock(WM_MESSAGE * pMsg) {
    GUI_MEMDEV_Handle ret;

    int      t0;   /*  Count for three pointers*/
    int      t1;
    int      t2;
    
    switch (pMsg->MsgId) {
        case WM_CREATE:
            /*Create timer*/
            WM_ Createtimer (PMSG - > hwin, / * handle of the window receiving information*/
                            0, / * user defined ID. This value can be set to zero if multiple timers are not used for the same window*/
                            10, / * cycle, after which the specified window should receive the message*/
                            0);          /*  Reserved for future use, should be 0*/ 

            break;

        /*The time is updated once every 1 second*/
        case WM_TIMER:
            WM_RestartTimer(pMsg->Data.v, 1000);

            RTC_ReadClock();

            /*The first pointer counts, which is used to rotate the second hand*/
            t0 = 360 -  g_tRTC.Sec * 6;

            /*The second pointer count is used to rotate the minute hand*/
            t1 = 360 - g_tRTC.Min * 6;

            /*The third pointer count is used to rotate the hour hand*/
            t2 = 360 -   g_tRTC.Hour * 30;

            /*Draw the relevant contents into the storage device hmemdst*/
            ret = GUI_MEMDEV_Select(hMemDST);
            GUI_SetBkColor(GUI_RED);
            GUI_Clear();

            /*Draw clock dial*/
            GUI_MEMDEV_WriteAt(hMemBK,0, 0);

            /*Draw hour hand*/
            GUI_MEMDEV_RotateHQ(hMemHour, hMemDST, 0, 0, t2 * 1000, 1000);

            /*Draw minute hand*/
            GUI_MEMDEV_RotateHQ(hMemMin, hMemDST, 0, 0, t1 * 1000, 1000);

            /*Draw second hand*/
            GUI_MEMDEV_RotateHQ(hMemSec, hMemDST, 0, 0, t0 * 1000, 1000);

            GUI_MEMDEV_Select(ret);
            
            /*The execution window is invalid, which will trigger the execution of WM_ Paint message*/
            WM_InvalidateWindow(pMsg->hWin);
            break;

        case WM_PAINT:
            GUI_MEMDEV_WriteAt(hMemDST, (xSize - bmclock_classic_background.XSize)/2 , 
(ySize - bmclock_classic_background.YSize)/2);
            break;

        default:
            WM_DefaultProc(pMsg);
            break;
    }
}
  • WM_CREATE:

Created a timer.

  •  WM_TIMER:

1. Function WM_ The restartimer setting is updated once per second.

2. Function RTC_ Readclock is used to read the real-time clock of the hardware timer.

3. Via GUI_ MEMDEV_ Select enables the clock dial, hour hand, minute hand and second hand to be drawn into the storage device hmemdst.

4. Function GUI_ MEMDEV_ Rotatehq is used to rotate the pointer.

5. Function WM_ Invalidewindow invalidates the window, which triggers WM_ Execution of paint message.

  • WM_PAINT:

Through function GUI_ MEMDEV_ Writeat draws the clock dial to the interface as a whole.

57.7 experimental routine description (RTOS)

Supporting examples:

V7-579_ emWin6. X cool clock dial design, combined with hardware RTC (bare metal)

V7-580_ emWin6. X cool clock dial design, combined with hardware RTC (RTOS)

Purpose of the experiment:

  1. Learn the data collected by the dynamic display camera on EMWIN.
  2. EMWIN function is implemented in maintask C in the document.

Experiment content:

1. When K1 key is pressed, the serial port or RTT print task execution (serial port baud rate 115200, data bit 8, parity bit none, stop bit 1).

2. (1) all functions that use printf function pass through function app_ Printf implementation.

(2) App_ Printf function does the mutually exclusive operation of semaphores to solve the problem of resource sharing.

3. The default power on is to print information through the serial port. If RTT is used to print information:

MDK AC5, MDK AC6 or IAR enable BSP The macro in the H file can be defined as 1

#define Enable_RTTViewer  1

4. The functions of each task are as follows:

App task start task: start the task, which is used here as a BSP driver package.

App task msppro task: message processing, used here as LED flashing.

App task: key message processing.

App task com} task: not used yet.

App task: Gui task.

μCOS-IIITask debugging information (press K1 key and print through serial port):

RTT printing information mode:

Programming:

Task stack size allocation:

μ Cos-iii task stack size in app_ cfg. Configuration in H file:

#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

The unit of task stack size is 4 bytes, so the stack size of each task is as follows:

App task start: 2048 bytes.

App task msppro task: 8192 bytes.

App task: 2048 bytes.

App task com} task: 2048 bytes.

App task GUI task: 8192 bytes.

System stack size allocation:

μ The system stack size of cos-iii is in OS_ cfg_ app. Configuration in H file:

#define  OS_CFG_ISR_STK_SIZE                      512u     

The unit of system stack size is 4 bytes, so here is to configure the system stack size to 2KB

emWinDynamic memory configuration:

GUIConf. The configuration in the C file is as follows:

#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

Configure whether to use internal SRAM or external SDRAM as the dynamic memory of EMWIN through macro definition. When configuring:

#define  EX_ SRAM # 1 means using external SDRAM as EMWIN dynamic memory, with a size of 24MB.

#define  EX_ SRAM # 0 means using internal SRAM as EMWIN dynamic memory, with a size of 100kb.

By default, all EMWIN examples supporting this tutorial use external SDRAM as EMWIN dynamic memory.

emWinInterface display effect:

800 * 480 resolution interface effect.

57.8 experimental routine description (bare metal)

Supporting examples:

V7-579_ emWin6. X cool clock dial design, combined with hardware RTC (bare metal)

V7-580_ emWin6. X cool clock dial design, combined with hardware RTC (RTOS)

Purpose of the experiment:

  1. Learn the data collected by the dynamic display camera on EMWIN.
  2. EMWIN function is implemented in maintask C in the document.

emWinInterface display effect:

800 * 480 resolution interface effect.

emWinDynamic memory configuration:

GUIConf. The configuration in the C file is as follows:

#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

Configure whether to use internal SRAM or external SDRAM as the dynamic memory of EMWIN through macro definition. When configuring:

#define  EX_ SRAM # 1 means using external SDRAM as EMWIN dynamic memory, with a size of 24MB.

#define  EX_ SRAM # 0 means using internal SRAM as EMWIN dynamic memory, with a size of 100kb.

By default, all EMWIN examples supporting this tutorial use external SDRAM as EMWIN dynamic memory.

57.9 summary

This chapter mainly explains the cool clock display method for you. You can also try other ways to realize dynamic display.