STEmWin with Touch Screen on STM32F746G Dicovery – Bonus -Part 6

In this part of tutorial we will use touch in STEmWin using GUIBuilder to design our user interface.

For quite some time since last part of tutorial it has been bugging me how to use nice shiny buttons from STEmWin and touch support for them. Well I must say it finally worked and below is my process of making it work.

I used GUIBuilder to desing simple layout with two buttons and a label:

Here is link to FramewinDLG.c so that you can have the same file as I do.

I made additional folder inside our project to host GUIBuilder.exe and our design file:

In here we need to put GUIBuilder.exe from CubeMX Repository and our FramewinDLG.c. And don’t forget to include this folder in our project:

 

We need to include this file (FramewinDLG.c) in main.c so that we can display our “beautiful” design:

We also need to add variable for touch screen so that our program can communicate with STEmWin:

We need some function which will update touch data and send it to STEmWin:

For touch data inside our program we define another variable:

Somewhere inside initialization of our hardware we also need to initialize our green LED:

At the end of main function we need to add functions for updating touch data and our screen:

And finally we add code at the end of main.c:

It looks simple now, but it took me quite a few hours to finnaly get it to work.

Enjoy until next time!

Slemi

 

P.S.: If you found this helpful, I would appreciate clicking on Ad on the right side to give me a little “motivation”. 🙂

4 thoughts on “STEmWin with Touch Screen on STM32F746G Dicovery – Bonus -Part 6

  1. Hi There,

    Thank you for this example. You helped me a lot.
    If I want to read the Arduino analog pin 0 with your code what do I need to do ?>

    • You need to look at this article, where need to change line 1054 from:
      sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
      to
      sConfig.Channel = 0;
      and also you need to change main function from:
      GUI_Clear();
      GUI_SetFont(&GUI_FontComic24B_1);
      GUI_SetColor(GUI_ORANGE);
      GUI_GotoXY(200, 100);
      GUI_DispFloatFix(temp, 4, 1);
      GUI_DispString(“\xb0”);
      GUI_DispString(“C”);

      to:
      GUI_Clear();
      GUI_SetFont(&GUI_FontComic24B_1);
      GUI_SetColor(GUI_ORANGE);
      GUI_GotoXY(200, 100);
      GUI_DispDec(rawValue, 8);
      //GUI_DispFloatFix(temp, 4, 1);
      //GUI_DispString(“\xb0”);
      //GUI_DispString(“C”);

  2. TOUCH function is implemented using GUI BUILDER.
    However, the LCD screen appears oddly in letters and buttons.
    I don’t know where the problem is.
    int main(void)
    {
    /* Enable the CPU Cache */
    CPU_CACHE_Enable();

    /* STM32F7xx HAL library initialization:
    – Configure the Flash ART accelerator on ITCM interface
    – Configure the Systick to generate an interrupt each 1 msec
    – Set NVIC Group Priority to 4
    – Global MSP (MCU Support Package) initialization
    */
    HAL_Init();

    /* Configure the system clock to 200 MHz */
    SystemClock_Config();

    /* Configure LED1 */
    BSP_LED_Init(LED1);

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

    /* Compute the prescaler value to have TIM3 counter clock equal to 10 KHz */
    uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) – 1;

    /* Set TIMx instance */
    TimHandle.Instance = TIM3;

    /* Initialize TIM3 peripheral as follows:
    + Period = 500 – 1
    + Prescaler = ((SystemCoreClock/2)/10000) – 1
    + ClockDivision = 0
    + Counter direction = Up
    */
    TimHandle.Init.Period = 500 – 1;
    TimHandle.Init.Prescaler = uwPrescalerValue;
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
    if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
    {
    while(1)
    {
    }
    }

    /*##-2- Start the TIM Base generation in interrupt mode ####################*/
    /* Start Channel1 */
    if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
    {
    while(1)
    {
    }
    }

    /***********************************************************/
    if (BSP_TS_Init(480,272) != TS_OK)
    {

    while (1);
    }
    /* Init the STemWin GUI Library */
    BSP_SDRAM_Init(); /* Initializes the SDRAM device */
    __HAL_RCC_CRC_CLK_ENABLE(); /* Enable the CRC Module */

    GUI_Init();

    GUI_DispStringAt(“Starting…”, 0, 0);

    GUI_Initialized = 1;

    /* Activate the use of memory device feature */
    WM_SetCreateFlags(WM_CF_MEMDEV);

    MainTask();

    /* Infinite loop */
    for(;;);
    }

    /**
    * @brief Period elapsed callback in non blocking mode
    * @param htim: TIM handle
    * @retval None
    */
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    BSP_Background();
    }

    /**
    * @brief TIM MSP Initialization
    * This function configures the hardware resources used in this application:
    * – Peripheral’s clock enable
    * – Peripheral’s GPIO Configuration
    * @param htim: TIM handle pointer
    * @retval None
    */
    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
    {
    /*##-1- Enable peripherals and GPIO Clocks #################################*/
    /* TIMx Peripheral clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();

    /*##-2- Configure the NVIC for TIMx ########################################*/
    /* Set the TIMx priority */
    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);

    /* Enable the TIMx global Interrupt */
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
    }

    /**
    * @brief BSP_Background.
    * @param None
    * @retval None
    */
    void BSP_Background(void)
    {
    //BSP_LED_Toggle(LED1);
    }

    /**
    * @brief System Clock Configuration
    * The system Clock is configured as follow :
    * System Clock source = PLL (HSE)
    * SYSCLK(Hz) = 200000000
    * HCLK(Hz) = 200000000
    * AHB Prescaler = 1
    * APB1 Prescaler = 4
    * APB2 Prescaler = 2
    * HSE Frequency(Hz) = 25000000
    * PLL_M = 25
    * PLL_N = 400
    * PLL_P = 2
    * PLL_Q = 8
    * VDD(V) = 3.3
    * Main regulator output voltage = Scale1 mode
    * Flash Latency(WS) = 6
    * @param None
    * @retval None
    */
    static void SystemClock_Config(void)
    {
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_OscInitTypeDef RCC_OscInitStruct;
    HAL_StatusTypeDef ret = HAL_OK;

    /* Enable HSE Oscillator and activate PLL with HSE as source */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 25;
    RCC_OscInitStruct.PLL.PLLN = 400;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 8;

    ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
    if(ret != HAL_OK)
    {
    while(1) { ; }
    }

    /* Activate the OverDrive to reach the 200 MHz Frequency */
    ret = HAL_PWREx_EnableOverDrive();
    if(ret != HAL_OK)
    {
    while(1) { ; }
    }

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

    ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
    if(ret != HAL_OK)
    {
    while(1) { ; }
    }
    }

    /**
    * @brief CPU L1-Cache enable.
    * @param None
    * @retval None
    */
    static void CPU_CACHE_Enable(void)
    {
    /* Enable I-Cache */
    SCB_EnableICache();

    /* Enable D-Cache */
    SCB_EnableDCache();
    }

    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(“Wrong parameters value: file %s on line %d\r\n”, file, line) */

    /* Infinite loop */
    while (1)
    {}
    }
    #endif

    /*********************************************************************
    * *
    * SEGGER Microcontroller GmbH & Co. KG *
    * Solutions for real time microcontroller applications *
    * *
    **********************************************************************
    * *
    * C-file generated by: *
    * *
    * GUI_Builder for emWin version 5.40 *
    * Compiled Jun 22 2017, 10:13:26 *
    * (c) 2017 Segger Microcontroller GmbH & Co. KG *
    * *
    **********************************************************************
    * *
    * Internet: http://www.segger.com Support: support@segger.com *
    * *
    **********************************************************************
    */

    // USER START (Optionally insert additional includes)
    // USER END

    #include “DIALOG.h”
    #include “STM32746G_DISCOVERY_TS.h”
    /*********************************************************************
    *
    * Defines
    *
    **********************************************************************
    */
    #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
    #define ID_BUTTON_0 (GUI_ID_USER + 0x01)
    #define ID_BUTTON_1 (GUI_ID_USER + 0x02)
    #define ID_TEXT_0 (GUI_ID_USER + 0x03)

    // USER START (Optionally insert additional defines)
    // USER END

    /*********************************************************************
    *
    * Static data
    *
    **********************************************************************
    */

    // USER START (Optionally insert additional static data)
    // USER END

    /*********************************************************************
    *
    * _aDialogCreate
    */
    static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    { FRAMEWIN_CreateIndirect, “Framewin”, ID_FRAMEWIN_0, 0, 0, 480, 272, 0, 0x64, 0 },
    { BUTTON_CreateIndirect, “LED_ON”, ID_BUTTON_0, 60, 120, 150, 50, 0, 0x0, 0 },
    { BUTTON_CreateIndirect, “LED_OFF”, ID_BUTTON_1, 230, 120, 150, 50, 0, 0x0, 0 },
    { TEXT_CreateIndirect, “Lb1”, ID_TEXT_0, 123, 51, 223, 26, 0, 0x64, 0 },
    // USER START (Optionally insert additional widgets)
    // USER END
    };

    /*********************************************************************
    *
    * Static code
    *
    **********************************************************************
    */

    // USER START (Optionally insert additional static code)
    // USER END

    /*********************************************************************
    *
    * _cbDialog
    */
    static void _cbDialog(WM_MESSAGE * pMsg) {
    WM_HWIN hItem;
    int NCode;
    int Id;
    // USER START (Optionally insert additional variables)
    // USER END

    switch (pMsg->MsgId) {
    case WM_INIT_DIALOG:
    //
    // Initialization of ‘Framewin’
    //
    hItem = pMsg->hWin;
    FRAMEWIN_SetText(hItem, “STM32F746G STemWin Test”);
    FRAMEWIN_SetTextColor(hItem, GUI_MAKE_COLOR(0x000000FF));
    FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
    FRAMEWIN_SetFont(hItem, GUI_FONT_24_ASCII);
    //
    // Initialization of ‘LED_ON’
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
    BUTTON_SetFont(hItem, GUI_FONT_24_ASCII);
    BUTTON_SetText(hItem, “LED ON”);
    //
    // Initialization of ‘LED_OFF’
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
    BUTTON_SetFont(hItem, GUI_FONT_24_ASCII);
    BUTTON_SetText(hItem, “LED OFF”);
    //
    // Initialization of ‘Lb1’
    //
    hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
    TEXT_SetText(hItem, “LED ON/OFF CONTROL”);
    TEXT_SetFont(hItem, GUI_FONT_24_ASCII);
    // USER START (Optionally insert additional code for further widget initialization)
    // USER END
    break;
    case WM_NOTIFY_PARENT:
    Id = WM_GetId(pMsg->hWinSrc);
    NCode = pMsg->Data.v;
    switch(Id) {
    case ID_BUTTON_0: // Notifications sent by ‘LED_ON’
    switch(NCode) {
    case WM_NOTIFICATION_CLICKED:
    // USER START (Optionally insert code for reacting on notification message)
    hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
    //TEXT_SetText(hItem, “LED ON/OFF CONTROL”);
    TEXT_SetText(hItem, ” Green LED On “);
    TEXT_SetTextColor(hItem, GUI_GREEN);
    BSP_LED_On(LED_GREEN);
    // USER END
    break;
    case WM_NOTIFICATION_RELEASED:
    // USER START (Optionally insert code for reacting on notification message)

    // USER END
    break;
    // USER START (Optionally insert additional code for further notification handling)
    // USER END
    }
    break;
    case ID_BUTTON_1: // Notifications sent by ‘LED_OFF’
    switch(NCode) {
    case WM_NOTIFICATION_CLICKED:
    // USER START (Optionally insert code for reacting on notification message)
    hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
    //TEXT_SetText(hItem, “LED ON/OFF CONTROL”);
    TEXT_SetText(hItem, ” Green LED Off “);
    TEXT_SetTextColor(hItem, GUI_BLACK);
    // USER END
    break;
    case WM_NOTIFICATION_RELEASED:
    // USER START (Optionally insert code for reacting on notification message)
    BSP_LED_Off(LED1);
    // USER END
    break;
    // USER START (Optionally insert additional code for further notification handling)
    // USER END
    }
    break;
    // USER START (Optionally insert additional code for further Ids)
    // USER END
    }
    break;
    // USER START (Optionally insert additional message handling)
    // USER END
    default:
    WM_DefaultProc(pMsg);
    break;
    }
    }

    /*********************************************************************
    *
    * Public code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    * CreateFramewin
    */
    WM_HWIN CreateFramewin(void);
    WM_HWIN CreateFramewin(void) {
    WM_HWIN hWin;

    hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
    return hWin;
    }
    //
    void MainTask(void)
    {
    TS_StateTypeDef ts ;
    GUI_PID_STATE TS_State;
    //
    GUI_Clear();
    CreateFramewin();
    while(1) {
    BSP_TS_GetState(&ts) ;
    if(ts.touchDetected) {
    TS_State.x = ts.touchX[0] ;
    TS_State.y = ts.touchY[0] ;
    TS_State.Pressed = 1 ;
    }
    else {
    TS_State.Pressed = 0 ;
    }
    GUI_Exec();
    GUI_PID_StoreState(&TS_State);
    GUI_Delay(10);
    }

    }
    // USER START (Optionally insert additional public code)
    // USER END

    /*************************** End of file ****************************/

    Thank you YOUR TIME!!

    • Sorry! I tried my tutorial today, to see if everything still works… IT DOES NOT! Looks like I will have to write whole tutorial from scratch, since there are changes in CubeMX and else in the Repository. I hope you will find answers for the things you need…

Comments are closed.