{"id":2077,"date":"2023-10-25T08:12:39","date_gmt":"2023-10-25T08:12:39","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2077"},"modified":"2023-10-25T08:12:42","modified_gmt":"2023-10-25T08:12:42","slug":"working-with-stm32f429-discovery-display-part-1-environment-setup","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2077","title":{"rendered":"Working with STM32F429-discovery Display Part 1: Environment Setup"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"672\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01.jpeg\" alt=\"\" class=\"wp-image-2078\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01-300x197.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01-768x504.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01-750x492.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01-400x263.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/F9093660-01-250x164.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this multipart guide, we shall focus on the display that embedded on STM32F429 discovery board and develop the driver for the LCD and the touch panel.<\/p>\n\n\n\n<p>In part 1, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Feature of the STM32F429 discovery.<\/li><li>Environment setup.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Features of STM32F429 Discovery:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Features of STM32F429:<\/p>\n\n\n\n<p>\u2022 STM32F429ZIT6 microcontroller featuring 2 Mbytes of Flash memory, 256 Kbytes of RAM in an LQFP144 package<\/p>\n\n\n\n<p>\u2022 2.4&#8243; QVGA TFT LCD<\/p>\n\n\n\n<p>\u2022 USB OTG with Micro-AB connector<\/p>\n\n\n\n<p>\u2022 I3G4250D, ST MEMS motion sensor 3-axis digital output gyroscope<\/p>\n\n\n\n<p>\u2022 Six LEDs:<\/p>\n\n\n\n<p>\u2013 LD1 (red\/green) for USB communication<\/p>\n\n\n\n<p>\u2013 LD2 (red) for 3.3 V power-on<\/p>\n\n\n\n<p>\u2013 Two user LEDs: LD3 (green), LD4 (red)<\/p>\n\n\n\n<p>\u2013 Two USB OTG LEDs: LD5 (green) V BUS and LD6 (red) OC (over-current)<\/p>\n\n\n\n<p>\u2022 Two push-buttons (user and reset)<\/p>\n\n\n\n<p>\u2022 64-Mbit SDRAM<\/p>\n\n\n\n<p>\u2022 Extension header for LQFP144 I\/Os for a quick connection to the prototyping board and an easy probing<\/p>\n\n\n\n<p>\u2022 On-board ST-LINK\/V2-B<\/p>\n\n\n\n<p>\u2022 USB functions:<\/p>\n\n\n\n<p>\u2013 Debug port<\/p>\n\n\n\n<p>\u2013 Virtual COM port<\/p>\n\n\n\n<p>\u2013 Mass storage<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Since here we are focusing on the display part which is based on ILI9341, the display has the following features:<\/p>\n\n\n\n<p>ILI9341 is a 262,144-color single-chip SOC driver for a-TFT liquid crystal display with resolution of 240RGBx320 dots, comprising a 720-channel source driver, a 320-channel gate driver, 172,800&nbsp;bytes&nbsp;GRAM for graphic display data of 240RGBx320 dots, and power supply circuit.<\/p>\n\n\n\n<p>ILI9341 supports parallel 8-\/9-\/16-\/18-bit data bus MCU interface, 6-\/16-\/18-bit data bus RGB interface and 3-\/4-line serial peripheral interface (SPI). The moving picture area can be specified in internal GRAM by window address function. The specified window area can be updated selectively, so that moving picture can be displayed simultaneously independent of still picture area.<\/p>\n\n\n\n<p>ILI9341 can operate with 1.65V ~ 3.3V I\/O interface voltage and an incorporated voltage follower circuit to generate voltage levels for driving an LCD. ILI9341 supports full color, 8-color display mode and sleep mode for precise power control by software and these features make the ILI9341 an ideal LCD driver for medium or small size portable products such as digital cellular phones, smart phone, MP3 and PMP where long battery life is a major concern.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>&nbsp;Display resolution: [240xRGB](H) x 320(V)&nbsp;&nbsp;Output:<\/p>\n\n\n\n<p>&nbsp;720sourceoutputs<br>&nbsp;320gateoutputs<br>&nbsp;Commonelectrodeoutput(VCOM)<\/p>\n\n\n\n<p>&nbsp;a-TFT LCD driver with on-chip full display RAM: 172,800 bytes&nbsp;&nbsp;System Interface<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li> \u00a08-bits, 9-bits, 16-bits, 18-bits interface with 8080- \/8080- series MCU<\/li><li> \u00a06-bits,16-bits,18-bitsRGBinterfacewithgraphiccontroller<\/li><li> \u00a03-line\/4-lineserialinterface\u00a0Display mode:<br>\u00a0Fullcolormode(IdlemodeOFF):262K-color(selectablecolordepthmodebysoftware)\u00a0\u00a0Reducecolormode(IdlemodeON):8-color\u00a0Power saving mode:\u00a0\u00a0Sleepmode\u00a0On chip functions:<br>\u00a0VCOMgeneratorandadjustment<br>\u00a0Timinggenerator<br>\u00a0Oscillator<br>\u00a0DC\/DCconverter<br>\u00a0Line\/frameinversion<br>\u00a01presetGammacurvewithseparateRGBGammacorrection\u00a0Content Adaptive Brightness Control\u00a0\u00a0MTP (3 times):\u00a08-bitsforID1,ID2,ID3<br>\u00a07-bitsforVCOMadjustmen<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Low -power consumption architecture&nbsp;&nbsp;Lowoperatingpowersupplies:<\/p>\n\n\n\n<p>&nbsp;VDDI = 1.65V ~ 3.3V (logic)<\/p>\n\n\n\n<p>&nbsp;VCI = 2.5V ~ 3.3V&nbsp;(analog)&nbsp;LCD Voltage drive:<\/p>\n\n\n\n<p>&nbsp;Source\/VCOMpowersupplyvoltage&nbsp;&nbsp;DDVDH &#8211; GND = 4.5V ~ 5.8V<br>&nbsp;VCL &#8211; GND = -1.5V ~ -2.5V<\/p>\n\n\n\n<p>&nbsp;Gatedriveroutputvoltage<br>&nbsp;VGH &#8211; GND = 10.0V ~ 18.0V&nbsp;&nbsp;VGL &#8211; GND = -5.0V ~ -10.0V&nbsp;&nbsp;VGH &#8211; VGL 28V<\/p>\n\n\n\n<p>&nbsp;VCOMdriveroutputvoltage<br>&nbsp;VCOMH = 3.0V ~ (DDVDH \u2013 0.2)V&nbsp;&nbsp;VCOML = (VCL+0.2)V ~ 0V<br>&nbsp;VCOMH &#8211; VCOML 6.0V<\/p>\n\n\n\n<p>Operate temperature range: -40 to 85<br>a-Si TFT LCD storage capacitor : Cst on Common structure only<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Environment Setup:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start by creating new STM32CubeIDE project for register level development.<\/p>\n\n\n\n<p>Please refer to the following <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1255\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1255\" target=\"_blank\">guide<\/a> for the steps and modify the chip name from:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">STM32F411xE<\/pre><\/div>\n\n\n\n<p>In symbolics to:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">STM32F429xx<\/pre><\/div>\n\n\n\n<p>Now, create new source file with name of sys_init.c to configure the core to run at maximum 180MHz.<\/p>\n\n\n\n<p>Follow <a href=\"https:\/\/blog.embeddedexpert.io\/?p=454\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=454\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> to see how to configure the core to run at maximum frequency using only register.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Within sys_init:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f4xx.h&quot;\n\nvoid SystemInit (void)\n{\n\n\t#define PLL_M      4\n\t#define PLL_N      180\n\t#define PLL_P      2\n\t#define PLL_Q      9\n\n\t__IO uint32_t StartUpCounter = 0, HSEStatus = 0;\n\n\n\t  RCC-&gt;CR |= ((uint32_t)RCC_CR_HSEON);\n\n\n\t  do\n\t  {\n\t\tHSEStatus = RCC-&gt;CR &amp; RCC_CR_HSERDY;\n\t\tStartUpCounter++;\n\t  } while((HSEStatus == 0) &amp;&amp; (StartUpCounter != 3000));\n\n\t  if ((RCC-&gt;CR &amp; RCC_CR_HSERDY) != RESET)\n\t  {\n\t\tHSEStatus = (uint32_t)0x01;\n\t  }\n\t  else\n\t  {\n\t\tHSEStatus = (uint32_t)0x00;\n\t  }\n\n\t  if (HSEStatus == (uint32_t)0x01)\n\t  {\n\n\t\tRCC-&gt;APB1ENR |= RCC_APB1ENR_PWREN;\n\t\tPWR-&gt;CR &amp;= (uint32_t)~(PWR_CR_VOS);\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_HPRE_DIV1;\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_PPRE2_DIV1;\n\n\n\t\tRCC-&gt;CFGR |= RCC_CFGR_PPRE1_DIV2;\n\n\n\t\tRCC-&gt;PLLCFGR = PLL_M | (PLL_N &lt;&lt; 6) | (((PLL_P &gt;&gt; 1) -1) &lt;&lt; 16) |\n\t\t\t\t\t   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q &lt;&lt; 24);\n\n\n\t\tRCC-&gt;CR |= RCC_CR_PLLON;\n\n\n\t\twhile((RCC-&gt;CR &amp; RCC_CR_PLLRDY) == 0)\n\t\t{\n\t\t}\n\n\t\t\/* Configure Flash prefetch, Instruction cache, Data cache and wait state *\/\n\t\tFLASH-&gt;ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;\n\n\t\t\/* Select the main PLL as system clock source *\/\n\t\tRCC-&gt;CFGR &amp;= (uint32_t)((uint32_t)~(RCC_CFGR_SW));\n\t\tRCC-&gt;CFGR |= RCC_CFGR_SW_PLL;\n\n\t\t\/* Wait till the main PLL is used as system clock source *\/\n\t\twhile ((RCC-&gt;CFGR &amp; (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL)\n\t\t{;}\n\t  }\n\t  else\n\t  { \/* If HSE fails to start-up, the application will have wrong clock\n\t\t\t configuration. User can add here some code to deal with this error *\/\n\t  }\n\n\t  \/*Enable FPU*\/\n\t  SCB-&gt;CPACR |= ((3UL &lt;&lt; 10*2)|(3UL &lt;&lt; 11*2));\n}\n\n<\/pre><\/div>\n\n\n\n<p>Before we continue, we need to find which SPI bus the LCD is connected.<\/p>\n\n\n\n<p>From the STM32F429-Disco, we can find as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"936\" height=\"570\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM.png\" alt=\"\" class=\"wp-image-2079\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM.png 936w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM-300x183.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM-768x468.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM-750x457.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM-400x244.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-25-at-10.58.18-AM-250x152.png 250w\" sizes=\"(max-width: 936px) 100vw, 936px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>STM32F429-disco<\/td><td>ILI9341<\/td><\/tr><tr><td>PA7<\/td><td>LCD RST<\/td><\/tr><tr><td>PC2<\/td><td>LCD CS<\/td><\/tr><tr><td>PD13<\/td><td>LCD DC<\/td><\/tr><tr><td>PF7<\/td><td>SPI5 SCK<\/td><\/tr><tr><td>PF9<\/td><td>SPI5 MOSI (SDA)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Now, we create new header file with name of LCD_Pins.h .<\/p>\n\n\n\n<p>Within the header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef LCD_PINS_H_\n#define LCD_PINS_H_\n\n#include &quot;delay.h&quot;\n\n\n\/*SPI *\/\nvoid LCD_Pin_Init(void);\nvoid LCD_SPI_Init(void);\n\n\/*LCD*\/\nvoid LCD_RST(void);\nvoid LCD_Write_Cmd(uint8_t cmd);\nvoid LCD_Write_Data (uint8_t data);\n\n\n\n#endif \/* LCD_PINS_H_ *\/<\/pre><\/div>\n\n\n\n<p>Now create source file with name of LCD_Pins.c:<\/p>\n\n\n\n<p>Within the source file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f4xx.h&quot;\n#include &quot;LCD_Pins.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following symbolic for SPI5 as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define AF05\t\t\t\t\t\t0x05<\/pre><\/div>\n\n\n\n<p>Declare macros for setting the RST, CS and DC to either high or low.<\/p>\n\n\n\n<p>We shall use atomic access to write to the pin using BSRR register:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define LCD_RES_HIGH(void)\t\t\tGPIOA-&gt;BSRR=GPIO_BSRR_BS7\n#define LCD_RES_LOW(void)\t\t\tGPIOA-&gt;BSRR=GPIO_BSRR_BR7\n\n#define LCD_CS_HIGH(void)\t\t\tGPIOC-&gt;BSRR=GPIO_BSRR_BS2\n#define LCD_CS_LOW(void)\t\t\tGPIOC-&gt;BSRR=GPIO_BSRR_BR2\n\n#define LCD_DC_HIGH(void)\t\t\tGPIOD-&gt;BSRR=GPIO_BSRR_BS13\n#define LCD_DC_LOW(void)\t\t\tGPIOD-&gt;BSRR=GPIO_BSRR_BR13<\/pre><\/div>\n\n\n\n<p>Initialize the pins:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_Pin_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;\n\n\t\/*PA7*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE7_0;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE7_1;\n\tGPIOA-&gt;OSPEEDR|=GPIO_OSPEEDR_OSPEED7;\n\tGPIOA-&gt;ODR|=GPIO_ODR_OD7;\n\n\t\/*PC2*\/\n\tGPIOC-&gt;MODER|=GPIO_MODER_MODE2_0;\n\tGPIOC-&gt;MODER&amp;=~GPIO_MODER_MODE2_1;\n\tGPIOC-&gt;OSPEEDR|=GPIO_OSPEEDR_OSPEED2;\n\tGPIOC-&gt;ODR|=GPIO_ODR_OD2;\n\n\n\n\t\/*PD13*\/\n\tGPIOD-&gt;MODER|=GPIO_MODER_MODE13_0;\n\tGPIOD-&gt;MODER&amp;=~GPIO_MODER_MODE13_1;\n\tGPIOD-&gt;OSPEEDR|=GPIO_OSPEEDR_OSPEED13;\n\tGPIOD-&gt;ODR|=GPIO_ODR_OD13;\n\n\t\/*PF7 and PF9 for SPI5*\/\n\n\tGPIOF-&gt;MODER|=GPIO_MODER_MODE7_1|GPIO_MODER_MODE9_1;\n\tGPIOF-&gt;MODER&amp;=~(GPIO_MODER_MODE7_0|GPIO_MODER_MODE9_0);\n\n\tGPIOF-&gt;AFR[0]|=(AF05&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n\tGPIOF-&gt;AFR[1]|=(AF05&lt;&lt;GPIO_AFRH_AFSEL9_Pos);\n\n\n}<\/pre><\/div>\n\n\n\n<p>Initialize SPI5 with  following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Master mode.<\/li><li>Software slave management.<\/li><li>Baudrate to be Fclk\/8.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_SPI_Init(void)\n{\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SPI5EN;\n\tSPI5-&gt;CR1|=SPI_CR1_MSTR|SPI_CR1_SSM|SPI_CR1_SSI|\n\tSPI_CR1_BR_1;\n\n\tSPI5-&gt;CR1|=SPI_CR1_SPE;\n\n}\n<\/pre><\/div>\n\n\n\n<p>Function that will write n byte using SPI bus and declared as static since no other function shall access this function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static void spi5_transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\n\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(SPI5-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\t\/*Write the data to the data register*\/\n\t\tSPI5-&gt;DR = data[i];\n\t\ti++;\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(SPI5-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((SPI5-&gt;SR &amp; (SPI_SR_BSY))){}\n\n\t\/*Clear OVR flag*\/\n\t(void) SPI5-&gt;DR;\n\t(void) SPI5-&gt;SR;\n}<\/pre><\/div>\n\n\n\n<p>In order to reset the LCD, it needs the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set reset pin to low.<\/li><li>Wait for 50 milliseconds.<\/li><li>Set reset pin to high.<\/li><li>Wait for 20 milliseconds.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_RST(void)\n{\n\tLCD_RES_LOW();\n\tdelay(50);\n\tLCD_RES_HIGH();\n\tdelay(20);\n\n}<\/pre><\/div>\n\n\n\n<p>Also, we need to write some commands to the LCD, we need the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set DC to low for command mode.<\/li><li>Set CS to low to accept the SPI data.<\/li><li>Write the command.<\/li><li>Set CS back to high to indicate end of transmission.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_Write_Cmd(uint8_t cmd)\n{\n\tLCD_CS_LOW();\n\tLCD_DC_LOW();\n\tspi5_transmit(&amp;cmd,1);\n\tLCD_CS_HIGH();\n}\n<\/pre><\/div>\n\n\n\n<p>To write the data, it is similar to writing command except that DC should be high:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void LCD_Write_Data (uint8_t data)\n{\n\tLCD_CS_LOW();\n\tLCD_DC_HIGH();\n\tspi5_transmit (&amp;data,1);\n\tLCD_CS_HIGH();\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In part w2, we shall initialize the LCD and fill the screen with colors.<\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this multipart guide, we shall focus on the display that embedded on STM32F429 discovery board and develop the driver for the LCD and the touch panel. In part 1, we shall cover the following: Feature of the STM32F429 discovery. Environment setup. 1. Features of STM32F429 Discovery: Features of STM32F429: \u2022 STM32F429ZIT6 microcontroller featuring 2 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,19,11,12],"tags":[],"class_list":["post-2077","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-lcd","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2077"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2077"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2077\/revisions"}],"predecessor-version":[{"id":2080,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2077\/revisions\/2080"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2077"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2077"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2077"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}