HAL library 12- LCD for STM32Fxxx

LCD is first big library provided from me. It’s the same as SDRAM, it works on STM32F429-Discovery, STM32F439-EVAL and STM32F7-Discovery boards. With one library you can control 3 boards just by selecting proper define in your target.

Library can be extended to other boards. Library requires FMC peripheral for SDRAM for display memory, DMA2D for fastest graphic accelerations and LTDC for transferring layers to LCD.

Library

Read more about new HAL libraries

Features

  • Supports STM32F429-Discovery board
  • Supports STM32F439-EVAL board
  • Supports STM32F7-Discovery board
  • Supports DMA2D graphic acceleration for fastest drawing operations
  • Supports screen rotation
  • Supports multiple fonts
  • And more

Dependencies

  • HAL
  • TM
    • STM32Fxxx HAL
    • defines.h
    • TM GPIO
    • TM SDRAM
    • TM DMA2D GRAPHIC
    • TM FONTS
    • TM SPI when STM32F429-Discovery is used

Board pinouts

LCD pins are different for different board. Using proper defines (explained below) you can select which board is used.

For full pinout list, download and open LCD library and check header file with description.

Board selection

The most important thing is to tell library, which board is used in target system. There are 2 possible ways to do that. One (and I prefer it) is to check my DISCO library and follow instructions which define you have to set for proper board, and another, explained below.

If you choose option one, then you will have no worries in my future libraries where library needs to know exactly which board is used!

The second option (I don’t prefer it) is, to set define only for this library. Copy define corresponding to your board into defines.h file or make a global defines in compiler’s settings. I made global defines in Keil uVision under “Options for Target” -> “C/C++” tab.

Functions and enumerations

Example

Single LCD library for different boards

Single LCD library for different boards



Project is available on Github, download all libraries below.

Icon
TM STM32 Libraries

STM32 libraries based on STM32Fxxx HAL drivers.

 

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Donttouchthebangbangfruit

    Hi TM,

    thank you for the great post. Unfortunately i am not able to jump into while(1) where i’m reading out an analog pin without DMA for yet. Could it be that this issue is connected to your library which you offer ?

    Best

    Here is the code :

    #include “stm32fxxx_hal.h”

    #include “defines.h”

    #include “tm_stm32_disco.h”

    #include “tm_stm32_delay.h”

    #include “tm_stm32_lcd.h”

    ADC_HandleTypeDef hadc1;

    void SystemClock_Config(void);

    static void MX_GPIO_Init(void);

    static void MX_ADC1_Init(void);

    uint32_t value;

    uint32_t zaehl;

    TM_FONT_SIZE_t FontSize;

    #if defined(STM32F7_DISCOVERY)

    char str[] = “This is LCD driver for F7-Discovery board”;

    #elif defined(STM32F439_EVAL)

    char str[] = “This is LCD driver for F439-Eval board”;

    #elif defined(STM32F429_DISCOVERY)

    char str[] = “F429-Discovery board”;

    #endif

    int x=0;

    int y=0;

    long z=0;

    int q=0;

    TIM_HandleTypeDef TIM_Handle;

    int main(void) {

    SystemClock_Config();

    MX_GPIO_Init();

    MX_ADC1_Init();

    HAL_ADC_Start(&hadc1);

    /* Init HAL layer */

    HAL_Init();

    /* Init LCD */

    TM_LCD_Init();

    /* Fill LCD with color */

    TM_LCD_Fill(0x0000);

    /* Put string on the middle of LCD */

    TM_LCD_SetFont(&TM_Font_16x26);

    TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)*2);

    TM_LCD_Puts(“Systemtest”);

    TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)/2);

    /* Get width and height of string */

    TM_FONT_GetStringSize(str, &FontSize, &TM_Font_11x18);

    /* Calculate middle of LCD */

    z = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

    TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)/2);

    TM_LCD_Puts(“0000”);

    while (1) {

    value = HAL_ADC_GetValue(&hadc1);

    zaehl=zaehl+1;

    }

    }

    void SystemClock_Config(void)

    {

    RCC_OscInitTypeDef RCC_OscInitStruct;

    RCC_ClkInitTypeDef RCC_ClkInitStruct;

    __PWR_CLK_ENABLE();

    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    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 = 8;

    RCC_OscInitStruct.PLL.PLLN = 336;

    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

    RCC_OscInitStruct.PLL.PLLQ = 7;

    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|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;

    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

    }

    void MX_ADC1_Init(void)

    {

    ADC_ChannelConfTypeDef sConfig;

    hadc1.Instance = ADC1;

    hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV6;

    hadc1.Init.Resolution = ADC_RESOLUTION12b;

    hadc1.Init.ScanConvMode = DISABLE;

    hadc1.Init.ContinuousConvMode = ENABLE;

    hadc1.Init.DiscontinuousConvMode = DISABLE;

    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

    hadc1.Init.NbrOfConversion = 1;

    hadc1.Init.DMAContinuousRequests = DISABLE;

    hadc1.Init.EOCSelection = EOC_SINGLE_CONV;

    HAL_ADC_Init(&hadc1);

    sConfig.Channel = ADC_CHANNEL_13;

    sConfig.Rank = 1;

    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    }

    void MX_GPIO_Init(void)

    {

    __GPIOC_CLK_ENABLE();

    }

    /* USER CODE BEGIN 4 */

    /* USER CODE END 4 */

    #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 CODE BEGIN 6 */

    /* User can add his own implementation to report the file name and line number,

    ex: printf(“Wrong parameters value: file %s on line %drn”, file, line) */

    /* USER CODE END 6 */

    }

    #endif

    /**

    * @}

    */

    /**

    * @}

    */

    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

    void kreis(void){

    for(x=0;x<=50;x++){

    TM_LCD_DrawFilledCircle(120,136,x,0xFFFF);

    HAL_Delay(20);

    }

    for(y=0;y<=50;y++){

    TM_LCD_DrawFilledCircle(120,136,y,0x0000);

    HAL_Delay(20);

    }

    }

    • RULES!! Which STMfamily?

      • Donttouchthebangbangfruit

        Sorry, didn’t knew about RULES here, STM32F429 Discovery Board.

        I tested it also without ADC and i’m not getting in :

        #include “stm32fxxx_hal.h”

        #include “defines.h”

        #include “tm_stm32_disco.h”

        #include “tm_stm32_delay.h”

        #include “tm_stm32_lcd.h”

        TM_FONT_SIZE_t FontSize;

        #if defined(STM32F7_DISCOVERY)

        char str[] = “This is LCD driver for F7-Discovery board”;

        #elif defined(STM32F439_EVAL)

        char str[] = “This is LCD driver for F439-Eval board”;

        #elif defined(STM32F429_DISCOVERY)

        char str[] = “F429-Discovery board”;

        #endif

        int x=0;

        int y=0;

        long z=0;

        int q=0;

        int zaehl=0;

        TIM_HandleTypeDef TIM_Handle;

        int main(void) {

        TM_RCC_InitSystem();
        HAL_Init();
        TM_LCD_Init();
        TM_LCD_Fill(0x0000);
        TM_LCD_SetFont(&TM_Font_16x26);

        TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)*2);

        TM_LCD_Puts(“Systemtest”);

        TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)/2);

        TM_FONT_GetStringSize(str, &FontSize, &TM_Font_11x18);

        z = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

        TM_LCD_SetXY((TM_LCD_GetWidth() – FontSize.Width) / 2, (TM_LCD_GetHeight() – FontSize.Height)/2);

        TM_LCD_Puts(“0000”);

        while (1) {

        zaehl=zaehl+1;

        }

        }

          • Donttouchthebangbangfruit

            Ok, there you go :

            http://pastebin.com/G3mgiDC4

          • Now we an have discussion.
            Program does not come to while(1)?

            Does it jump to hardfault? Go to debug and check this first. If it goes, find out where. Use step into from start of program and click it until you jump to hardfault (if you will, of course)

          • Donttouchthebangbangfruit

            Great, i use Keil 5 but how i can find in debug mode hardfault, never did that before?

          • Donttouchthebangbangfruit

            That’s what i found :

            http://postimg.org/image/59i0pp5ft/

          • Send entire project (delete build files, o. and all others) to my email.

          • Donttouchthebangbangfruit

            Ok, i did it

          • I’ve compiled, tested and result is: On LCD I see “SystemTest” message at 0,0 location.
            Try to redownload my libs.

          • Donttouchthebangbangfruit

            Yes that is working, the LCD is also working but i can not see a increment of “zaehl” 🙁 it is not jumping into the while(1)

          • Sure it does! Check bottom right for Watch1 window.
            http://screencloud.net/v/qn8e

          • Donttouchthebangbangfruit

            Yes i checked it. But you know what ? I did not enabled “Trace” in Debug > Settings > Trace

            🙂 Thank you

          • You don’t need that!

          • Donttouchthebangbangfruit

            But since that it is working ? Strange..

            And unfortunately i copied now my code for the ADC seems also not to work. Could you please dig in it :

            http://pastebin.com/Mcc0T12g

          • Enable clock for ADC, init GPIO pin as analog for first time. Then we can continue. For further problems contact via email. This has nothing to do with LCD anymore.

          • Donttouchthebangbangfruit

            Ok, but i allready did that with CubeMX.. i send you an email with the new project file

          • Maybe, if you send me a project with all libs included, I will check that.
            But how to debug. Go to debug mode using Debug button. Processor will come (at least it should) to main() function where yellow pointer will be shown on left. Then you have buttons “Step into”, “Step over”, “Step out” and more for navigation through code. Check uVision manual for more info.

  • Pingback: All STM32 HAL libraries - STM32F4 Discovery()

  • Nahum Budin

    Hi TM,

    First, I would like to start with a great THANK YOU :-).
    You are doing a great job.
    So many thanks for sharing it.

    Some feedback on using LCD on STM32F429-Discovery board.

    Just finalized the process of using the TM STM 32 libraries using CooCox IDE.

    Bottom line – I can see a text string on the LCD :-).

    In order to get there I had to put some modifications in some of the files.
    I tried to put the changes into the code while leaving the original code as remarks.
    I believe the best way will be just sending you the modified files, so you can look into it
    and compare it to the original files I have downloaded this morning.

    Please advise.

    Thanks,

    Nahum Budin.

    • What is now the problem which must be solved here?

      • Nahum Budin

        No problem to solve.
        I have solved the problems I have encountered

        For example in tm_stm32_gpio.h:

        #define TM_GPIO_SetPinLow(GPIOx, GPIO_Pin) ((GPIOx)->BSRR = (uint32_t)((GPIO_Pin) << 16)).

        GPIO_TypeDef has no member BSRR, there are BSRRL (for Low) and BSRRH (for High) (stm32f429xx.h)

        (or, instead I have changed it to HAL_GPIO_WritePin (GPIOx, GPIO_Pin, 0)).

        Just wanted to share this and some more issues I have found and fixed.

        Thank you.

        • Using STM324xx HAL drivers, structure for GPIO has BSRR only. 1.7.0 version of Cube.

          • Nahum Budin

            Interesting.
            The CooCox IDE includes an older version of the drivers, where there are BSRRH and L.
            Other issues I have found may also be related to drivers version.
            So, if any of you, CooCox IDE users, are having problems with TM libraries, please note.
            Thanks you for your support.

          • You can manually update drivers from coicix with new one downloaded from ST.

  • Daniel

    Hello TM, which is the easiest way to use a LCD 16×2? i am using a STM32F407vg

  • Hasanuzzaman Mamun

    Hi, If I want to burn a LCD example in my own board (designed by me with stm32f746vg) which LCD should I use? Do I need an LCD identical to that of Discovery board?

    Can you provide me the Driver IC name or LCD model name? Help me here please. I’m stuck

    • What about little research what here is supported?

      Technically you should use the same, yes since some configurations are sent.

      • Hasanuzzaman Mamun

        Do you know the DRIVER IC name of the STM32F7 disco board LCD?

  • victor

    Hi! Thank you for your posts!
    When I rebuild the project I get these errors: http://pastebin.com/xbMYAnmB. How can i solve them?

  • Victor

    I would like to know if it is possible to show an image or video using this library and how can i do it

    • No, it is not possible since both needs decoding process first.