{"id":2112,"date":"2023-11-15T13:39:46","date_gmt":"2023-11-15T13:39:46","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2112"},"modified":"2023-11-15T13:39:50","modified_gmt":"2023-11-15T13:39:50","slug":"revisedworking-with-stm32-and-display-nokia-5110-graphic-lcd","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2112","title":{"rendered":"[Revised]Working with STM32 and display: Nokia 5110 Graphic LCD"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"500\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1.jpg\" alt=\"\" class=\"wp-image-2113\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1.jpg 500w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1-300x300.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1-150x150.jpg 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1-400x400.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/nokia-5110-lcd-500x500-1-250x250.jpg 250w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/figure><\/div>\n\n\n\n<p>In this revised version of Nokia 5110 Display, we shall interface this type of LCD with STM32 and develop the appropriate driver to driver the screen to display texts and pictures.<\/p>\n\n\n\n<p>In this guid, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Nokia 5110 Graphic LCD.<\/li><li>LCD connection with STM32.<\/li><li>SPI driver.<\/li><li>Display driver.<\/li><li>Main code.<\/li><li>Code download.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 Nokia 5110 Graphic LCD:<\/h2>\n\n\n\n<p>Remember the days when cell phones were still \u201cdumb,\u201d and they had physical keypads and just a tiny monochrome LCD for a display? Now that iPhones, Galaxies, and the like have revolutionized that market, those little LCDs have to find a new purpose in life: adding customized graphical displays to projects!<\/p>\n\n\n\n<p>Nokia5110 LCD screen is a simple black and white screen but it was the best display for mobile in its time. The usage of the screen was mostly in the Nokia 3310 and 5110. Therefore, the increase of color graphics and smart screens the screen is now the only available in most of the developing projects and small low budget devices. In the LCD, the Liquid crystal method helps to show the output data with a total of 84\u00d748 pixels. The LCD uses the SPI pins to communicate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 What is Nokia5510 LCD Display?<\/h2>\n\n\n\n<p>Nokia 5510 LCD display is a graphics screen LCD display and has been used for a lot of applications. Initially, it was designed only for iconic Nokia 5510 cell phone screen but now we can easily use it for different purposes such as for displaying alphanumeric character, draw lines, shapes and even for displaying bitmap images because of its 84*48 monochrome pixels mean 84 columns and 48 rows. All necessary functions of this display are packed in a single small chip which is operated at very low voltages. It is very low cost more precise, more reliable and easy to use LCD display.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.3 Nokia5110 Pinout Diagram<\/h2>\n\n\n\n<p>The pin configuration of the LCD is almost SPI but in oneway only. The LCD only uses a one-way communication to operate because it doesn\u2019t have to send any data to the microcontroller. However, it has two modes of data and command modes for operating properly.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/microcontrollerslab.com\/wp-content\/uploads\/2020\/01\/Nokia-5110-LCD-Pinout-diagram-details.png\"><img decoding=\"async\" src=\"https:\/\/microcontrollerslab.com\/wp-content\/uploads\/2020\/01\/Nokia-5110-LCD-Pinout-diagram-details.png?ezimgfmt=rs:407x538\/rscb1\/ngcb1\/notWebP\" alt=\"Nokia5110 LCD Pinout diagram details\" class=\"wp-image-14779\" \/><\/a><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">1.3 Nokia5510 Pinout Diagram Details<\/h3>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><th>PINS<\/th><th>DETAIL<\/th><\/tr><tr><td>Pin6<\/td><td>Power (VCC)<\/td><td>The power pin will power up the LCD with external voltage to activate it.<\/td><\/tr><tr><td>Pin7<\/td><td>Back Light (BL)<\/td><td>The backlight is the internal color of the LCD. It is just turn on by giving the power input to its pin.<\/td><\/tr><tr><td>Pin8<\/td><td>Ground (GND)<\/td><td>The ground is internally common with LED and whole LCD. It helps to make common ground with external power and devices.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.4 SPI Communication Pins<\/h3>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><th>PINS<\/th><th>DETAIL<\/th><\/tr><tr><td>Pin1<\/td><td>Reset<\/td><td>The reset pins are to reset the Nokia5110 display. Here it will help in the programming library to reset it.<\/td><\/tr><tr><td>Pin2<\/td><td>Chip Enable (CE)<\/td><td>The enable pin in SPI helps to select the device in case of multiple devices. Here it will active the LCD with the LOW input signal.<\/td><\/tr><tr><td>Pin3<\/td><td>Data\/Command (DC)<\/td><td>Pin3 helps to switch between the command\/data mode. The HIGH signal is for data and LOW signal for command.<\/td><\/tr><tr><td>Pin4<\/td><td>Serial IN (DIN)<\/td><td>The \u201cserial in\u201d pin will send the data from the microcontroller\/Arduino to the LCD Nokia5110.<\/td><\/tr><tr><td>Pin5<\/td><td>Clock (CLK)<\/td><td>The LCD and microcontroller will require a common clock to operate because of their SPI communication. CLK pin will help to make it.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">1.5 Nokia5110 Features<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>The LCD is of 84\u00d748 pixels combination, which are useable with any microcontroller.<\/li><li>The SPI communication helps to communicate with LCD, which is common in every microcontroller.<\/li><li>It is available in multiple backlights.<\/li><li>The PCD8544 LCD driver helps to drive it, which is already present on it.<\/li><li>Bitmaps images are viewable on the Nokia5110.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.6 Nokia5110 LCD Applications<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Most of the pocket games use the LCD, like snake games, etc.<\/li><li>Mobile phones have a wide use of LCD.<\/li><li>The LCD is still in most of the industrial and commercial applications.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.7 Nokia5110 LCD Constructions<\/h2>\n\n\n\n<p>The Nokia5110 LCD uses a simple liquid crystal method for each pixel to show the data. In the liquid crystal, the three layers help to make a single pixel. The first layer is the glass, second is the polarized sheet and the third one is the crystal molecules. The light passes from one glass towards the other glass but it has to move from two polarized sheets. The polarized sheets are at different angles. So, to pass the light the molecules need to change their positions so the light gets a change in angle according to the second sheet with the help of modules. If light passes from it, then it is viewable by the user but in case of deflection, the LCD will show a dark pixel. However, the liquid crystals always use a light absorption method to show the image.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LCD Driver<\/h3>\n\n\n\n<p>The Nokia5110 LCD uses SPI communication to operate. It is due to the driver attached to it. The data from the controllers pass to the driver which store in the buffer and also show on the LCD until it is in the buffer. The new incoming data will able to replace the previous one. The driver only takes the SPI input signal and uses the rest of the pin to operate the LCD. The driver is PCD8544, which is only for 48\u00d784 pixels LCD. Its functionality is viewable by the following block diagram:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/microcontrollerslab.com\/wp-content\/uploads\/2020\/01\/Nokia-5110-LCD-block-diagram.png\"><img decoding=\"async\" src=\"https:\/\/microcontrollerslab.com\/wp-content\/uploads\/2020\/01\/Nokia-5110-LCD-block-diagram.png?ezimgfmt=rs:618x517\/rscb1\/ngcb1\/notWebP\" alt=\"block diagram\" class=\"wp-image-14778\" \/><\/a><\/figure>\n\n\n\n<p>The driver has its 504bytes GDD RAM. However, Its memory comes with 6 blanks and each blank has 84 segments and each segment can store the 8 bit of data. Therefore, the whole LCD data can store in the GDD RAM of the LCD screen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Output Pins<\/h3>\n\n\n\n<p>The input pins of the driver are the same as the LCD pins which are already in the pin configuration section.&nbsp; The output pins of the driver are responsible for every function on the LCD screen. However, four types of output pins exist in the driver. The first part is the Row and Column pins. The row pins are 48 and columns are 84 in numbers. Therefore, all these pins connect to each pixel of the LCD and they are responsible for each output by them. The next part is the power part. The VSS, VDD, and VLCD help to power up the LCD and itself. The third part is the test pins that connect with the ground. In the Nokia5110 LCD, they have no use.<\/p>\n\n\n\n<p>The last part is the oscillator pin, to attach an external oscillator. There will be remaining dummy pins that have no use in the LCD screen. In this Nokia5110 LCD, every kind of symbol is drawable. Even images can also show on the screen but first, it requires to convert into the bitmap format.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Working Principle of Nokia 5510 LCD Display<\/strong><\/h3>\n\n\n\n<p>The word LCD stands for liquid crystal display. Its name describes that every LCD display consists of liquid crystal. When an electric current is passed through these crystals then the magnetic field is produced. This magnetic field-aligned the molecules of liquid crystal forcefully, then when they are aligned precisely then they allow the light to pass through these crystals.<\/p>\n\n\n\n<p>The working phenomena of every LCD display are almost the same. But the voltages which are required to produce the magnetic field are different. On the biases of these voltages, the LCD display shows data which is coming from any type of controller. Two types of data have come from the controller\u2019s fist one is word data and second one graphic data. Each data produces a different magnetic field and the LCD display shows this data according to its magnetic field.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. LCD Connection with  STM32:<\/h2>\n\n\n\n<p>The connection diagram as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"591\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-1024x591.png\" alt=\"\" class=\"wp-image-2114\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-1024x591.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-300x173.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-768x443.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-1536x886.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-1150x663.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-750x432.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-400x231.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1-250x144.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screen-Shot-2022-01-03-at-6.55.55-AM-2048x1181-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>STM32F411 Nucleo-64<\/td><td>Nokia 5110 GLCD<\/td><\/tr><tr><td>5V<\/td><td>Vcc<\/td><\/tr><tr><td>5V<\/td><td>BL<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>PA5 (SCK SPI1)<\/td><td>CLK<\/td><\/tr><tr><td>PA7 (MOSI SPI1)<\/td><td>Din<\/td><\/tr><tr><td>PA0<\/td><td>DC<\/td><\/tr><tr><td>PA1<\/td><td>CE<\/td><\/tr><tr><td>PA4<\/td><td>RST<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. SPI driver:<\/h2>\n\n\n\n<p>Before we deal with SPI, refer to <a href=\"https:\/\/blog.embeddedexpert.io\/?p=466\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=466\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> for more details about SPI and how find the pins, set alternate function etc.<\/p>\n\n\n\n<p>We start of by creating header file with name of SPI1.h.<\/p>\n\n\n\n<p>Within the header file, include header guard:<\/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 SPI_H_\n#define SPI_H_\n\n\n\n#endif \/* SPI1_H_ *\/<\/pre><\/div>\n\n\n\n<p>Include standard integer:<\/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;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>SPI Functions:<\/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 SPI1_Pins_Init(void);\nvoid SPI1_Init(void);\nvoid SP11_Transmit(uint8_t *data,uint32_t size);\nvoid SPI1_Receive(uint8_t *data,uint32_t size);<\/pre><\/div>\n\n\n\n<p>Entire header file:<\/p>\n\n\n\n<p><\/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 SPI1_H_\n#define SPI1_H_\n\n#include &quot;stdint.h&quot;\n\nvoid SPI1_Pins_Init(void);\nvoid SPI1_Init(void);\nvoid SPI1_Transmit(uint8_t *data,uint32_t size);\nvoid SPI1_Receive(uint8_t *data,uint32_t size);\n\n\n#endif \/* SPI_H_ *\/<\/pre><\/div>\n\n\n\n<p>Now, create new source file with name of SPI1.c.<\/p>\n\n\n\n<p>Within the source include the following 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;}\">#include &quot;SPI1.h&quot;\n\n#include &quot;stm32f4xx.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare AF05 to hold the alternate function number:<\/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\t0x05<\/pre><\/div>\n\n\n\n<p>Populated functions from 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;}\">void SPI1_Pins_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \/\/enable clock for GPIOA\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1; \/\/set PA5, PA6 and PA7 to alternate function mode\n\tGPIOA-&gt;MODER &amp;=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);\n\n\tGPIOA-&gt;AFR[0]|=(AF05&lt;&lt;GPIO_AFRL_AFSEL5_Pos)|(AF05&lt;&lt;GPIO_AFRL_AFSEL6_Pos)|(AF05&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n}\n\nvoid SPI1_Init(void)\n{\n\t\/*Enable clock access to SPI1 module*\/\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_SPI1EN;\n\n\t\/*Configure the SPI with the following parameters\n\t * Master Mode.\n\t * Software slave management\n\t * *\/\n\n\tSPI1-&gt;CR1=SPI_CR1_MSTR|SPI_CR1_SSI|SPI_CR1_SSM;\n\n\t\/*Enable SPI1 peripheral *\/\n\tSPI1-&gt;CR1|=SPI_CR1_SPE;\n}\n\nvoid SPI1_Transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\t\/*Write the data to the data register*\/\n\t\tSPI1-&gt;DR = data[i];\n\t\ti++;\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((SPI1-&gt;SR &amp; (SPI_SR_BSY))){}\n\n\t\/*Clear OVR flag*\/\n\t(void)SPI1-&gt;DR;\n\t(void)SPI1-&gt;SR;\n}\n\nvoid SPI1_Receive(uint8_t *data,uint32_t size)\n{\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tSPI1-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_RXNE))){}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (SPI1-&gt;DR);\n\t\tsize--;\n\t}\n}\n<\/pre><\/div>\n\n\n\n<p>Entire source code:<\/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;SPI1.h&quot;\n\n#include &quot;stm32f4xx.h&quot;\n\n#define AF05\t0x05\n\n\nvoid SPI1_Pins_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \/\/enable clock for GPIOA\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1; \/\/set PA5, PA6 and PA7 to alternate function mode\n\tGPIOA-&gt;MODER &amp;=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);\n\n\tGPIOA-&gt;AFR[0]|=(AF05&lt;&lt;GPIO_AFRL_AFSEL5_Pos)|(AF05&lt;&lt;GPIO_AFRL_AFSEL6_Pos)|(AF05&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n}\n\nvoid SPI1_Init(void)\n{\n\t\/*Enable clock access to SPI1 module*\/\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_SPI1EN;\n\n\t\/*Configure the SPI with the following parameters\n\t * Master Mode.\n\t * Software slave management\n\t * *\/\n\n\tSPI1-&gt;CR1=SPI_CR1_MSTR|SPI_CR1_SSI|SPI_CR1_SSM;\n\n\t\/*Enable SPI1 peripheral *\/\n\tSPI1-&gt;CR1|=SPI_CR1_SPE;\n}\n\nvoid SPI1_Transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\t\/*Write the data to the data register*\/\n\t\tSPI1-&gt;DR = data[i];\n\t\ti++;\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((SPI1-&gt;SR &amp; (SPI_SR_BSY))){}\n\n\t\/*Clear OVR flag*\/\n\t(void)SPI1-&gt;DR;\n\t(void)SPI1-&gt;SR;\n}\n\nvoid SPI1_Receive(uint8_t *data,uint32_t size)\n{\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tSPI1-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_RXNE))){}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (SPI1-&gt;DR);\n\t\tsize--;\n\t}\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Display Driver:<\/h2>\n\n\n\n<p>Create new  header file with name of Nokia_5110_GLCD.h.<\/p>\n\n\n\n<p>Within the header file, include the header guard:<\/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 NOKIA_5110_GLCD_H_\n#define NOKIA_5110_GLCD_H_\n\n\n\n#endif \/* NOKIA_5110_GLCD_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Include the following header files:<\/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;stdint.h&quot;\n#include &quot;stdbool.h&quot;<\/pre><\/div>\n\n\n\n<p>Within the header guard, declare the dimensions of the display and black and white values:<\/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;}\">\/* 84x48 LCD Defines: *\/\n#define LCD_WIDTH   84 \/\/ Note: x-coordinates go wide\n#define LCD_HEIGHT  48 \/\/ Note: y-coordinates go high\n#define WHITE       0  \/\/ For drawing pixels. A 0 draws white.\n#define BLACK       1  \/\/ A 1 draws black.<\/pre><\/div>\n\n\n\n<p>Required functions:<\/p>\n\n\n\n<p><\/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 setLine(int x0, int y0, int x1, int y1, bool bw);\nvoid setRect(int x0, int y0, int x1, int y1, bool fill, bool bw);\nvoid setCircle (int x0, int y0, int radius, bool bw, int lineThickness);\nvoid setStr(char * dString, int x, int y, bool bw);\nvoid SetBitMap(const char * bitArray);\nvoid clearDisplay(bool bw);\nvoid gotoXY(int x, int y);\nvoid updateDisplay();\nvoid setContrast(int contrast);\nvoid invertDisplay();\nvoid lcdBegin(void);<\/pre><\/div>\n\n\n\n<p>Hence, the header file 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;}\">#ifndef NOKIA_5110_GLCD_H_\n#define NOKIA_5110_GLCD_H_\n\n#include &quot;stdint.h&quot;\n#include &quot;stdbool.h&quot;\n\n\n\/* 84x48 LCD Defines: *\/\n#define LCD_WIDTH   84 \/\/ Note: x-coordinates go wide\n#define LCD_HEIGHT  48 \/\/ Note: y-coordinates go high\n#define WHITE       0  \/\/ For drawing pixels. A 0 draws white.\n#define BLACK       1  \/\/ A 1 draws black.\n\n\nvoid setLine(int x0, int y0, int x1, int y1, bool bw);\nvoid setRect(int x0, int y0, int x1, int y1, bool fill, bool bw);\nvoid setCircle (int x0, int y0, int radius, bool bw, int lineThickness);\nvoid setStr(char * dString, int x, int y, bool bw);\nvoid SetBitMap(const char * bitArray);\nvoid clearDisplay(bool bw);\nvoid gotoXY(int x, int y);\nvoid updateDisplay();\nvoid setContrast(int contrast);\nvoid invertDisplay();\nvoid lcdBegin(void);\n\n#endif \/* NOKIA_5110_GLCD_H_ *\/<\/pre><\/div>\n\n\n\n<p>Create new source file with name of Nokia_5110_GLCD.c<\/p>\n\n\n\n<p>Within the source file, include the following 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;}\">#include &quot;Nokia_5110_GLCD.h&quot;\n#include &quot;STM32F4xx.h&quot;\n#include &quot;delay.h&quot;\n#include &lt;stdbool.h&gt;\n#include &quot;SPI1.h&quot;<\/pre><\/div>\n\n\n\n<p>Define some macros for DC, CS and RST 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;}\">\/*Macros of CS, RST and DC*\/\n\n#define LCD_COMMAND  \tGPIOA-&gt;BSRR|=GPIO_BSRR_BR0\n#define LCD_DATA    \tGPIOA-&gt;BSRR|=GPIO_BSRR_BS0\n\n#define CS0 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BR1\n#define CS1 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BS1\n\n#define RST0 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BR4\n#define RST1 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BS4<\/pre><\/div>\n\n\n\n<p>Array to hold ASCII characters that can be displayed:<\/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 const unsigned char ASCII[][5] = {\n  \/\/ First 32 characters (0x00-0x19) are ignored. These are\n  \/\/ non-displayable, control characters.\n   {0x00, 0x00, 0x00, 0x00, 0x00} \/\/ 0x20\n  ,{0x00, 0x00, 0x5f, 0x00, 0x00} \/\/ 0x21 !\n  ,{0x00, 0x07, 0x00, 0x07, 0x00} \/\/ 0x22 &quot;\n  ,{0x14, 0x7f, 0x14, 0x7f, 0x14} \/\/ 0x23 #\n  ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} \/\/ 0x24 $\n  ,{0x23, 0x13, 0x08, 0x64, 0x62} \/\/ 0x25 %\n  ,{0x36, 0x49, 0x55, 0x22, 0x50} \/\/ 0x26 &amp;\n  ,{0x00, 0x05, 0x03, 0x00, 0x00} \/\/ 0x27 '\n  ,{0x00, 0x1c, 0x22, 0x41, 0x00} \/\/ 0x28 (\n  ,{0x00, 0x41, 0x22, 0x1c, 0x00} \/\/ 0x29 )\n  ,{0x14, 0x08, 0x3e, 0x08, 0x14} \/\/ 0x2a *\n  ,{0x08, 0x08, 0x3e, 0x08, 0x08} \/\/ 0x2b +\n  ,{0x00, 0x50, 0x30, 0x00, 0x00} \/\/ 0x2c ,\n  ,{0x08, 0x08, 0x08, 0x08, 0x08} \/\/ 0x2d -\n  ,{0x00, 0x60, 0x60, 0x00, 0x00} \/\/ 0x2e .\n  ,{0x20, 0x10, 0x08, 0x04, 0x02} \/\/ 0x2f \/\n  ,{0x3e, 0x51, 0x49, 0x45, 0x3e} \/\/ 0x30 0\n  ,{0x00, 0x42, 0x7f, 0x40, 0x00} \/\/ 0x31 1\n  ,{0x42, 0x61, 0x51, 0x49, 0x46} \/\/ 0x32 2\n  ,{0x21, 0x41, 0x45, 0x4b, 0x31} \/\/ 0x33 3\n  ,{0x18, 0x14, 0x12, 0x7f, 0x10} \/\/ 0x34 4\n  ,{0x27, 0x45, 0x45, 0x45, 0x39} \/\/ 0x35 5\n  ,{0x3c, 0x4a, 0x49, 0x49, 0x30} \/\/ 0x36 6\n  ,{0x01, 0x71, 0x09, 0x05, 0x03} \/\/ 0x37 7\n  ,{0x36, 0x49, 0x49, 0x49, 0x36} \/\/ 0x38 8\n  ,{0x06, 0x49, 0x49, 0x29, 0x1e} \/\/ 0x39 9\n  ,{0x00, 0x36, 0x36, 0x00, 0x00} \/\/ 0x3a :\n  ,{0x00, 0x56, 0x36, 0x00, 0x00} \/\/ 0x3b ;\n  ,{0x08, 0x14, 0x22, 0x41, 0x00} \/\/ 0x3c &lt;\n  ,{0x14, 0x14, 0x14, 0x14, 0x14} \/\/ 0x3d =\n  ,{0x00, 0x41, 0x22, 0x14, 0x08} \/\/ 0x3e &gt;\n  ,{0x02, 0x01, 0x51, 0x09, 0x06} \/\/ 0x3f ?\n  ,{0x32, 0x49, 0x79, 0x41, 0x3e} \/\/ 0x40 @\n  ,{0x7e, 0x11, 0x11, 0x11, 0x7e} \/\/ 0x41 A\n  ,{0x7f, 0x49, 0x49, 0x49, 0x36} \/\/ 0x42 B\n  ,{0x3e, 0x41, 0x41, 0x41, 0x22} \/\/ 0x43 C\n  ,{0x7f, 0x41, 0x41, 0x22, 0x1c} \/\/ 0x44 D\n  ,{0x7f, 0x49, 0x49, 0x49, 0x41} \/\/ 0x45 E\n  ,{0x7f, 0x09, 0x09, 0x09, 0x01} \/\/ 0x46 F\n  ,{0x3e, 0x41, 0x49, 0x49, 0x7a} \/\/ 0x47 G\n  ,{0x7f, 0x08, 0x08, 0x08, 0x7f} \/\/ 0x48 H\n  ,{0x00, 0x41, 0x7f, 0x41, 0x00} \/\/ 0x49 I\n  ,{0x20, 0x40, 0x41, 0x3f, 0x01} \/\/ 0x4a J\n  ,{0x7f, 0x08, 0x14, 0x22, 0x41} \/\/ 0x4b K\n  ,{0x7f, 0x40, 0x40, 0x40, 0x40} \/\/ 0x4c L\n  ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} \/\/ 0x4d M\n  ,{0x7f, 0x04, 0x08, 0x10, 0x7f} \/\/ 0x4e N\n  ,{0x3e, 0x41, 0x41, 0x41, 0x3e} \/\/ 0x4f O\n  ,{0x7f, 0x09, 0x09, 0x09, 0x06} \/\/ 0x50 P\n  ,{0x3e, 0x41, 0x51, 0x21, 0x5e} \/\/ 0x51 Q\n  ,{0x7f, 0x09, 0x19, 0x29, 0x46} \/\/ 0x52 R\n  ,{0x46, 0x49, 0x49, 0x49, 0x31} \/\/ 0x53 S\n  ,{0x01, 0x01, 0x7f, 0x01, 0x01} \/\/ 0x54 T\n  ,{0x3f, 0x40, 0x40, 0x40, 0x3f} \/\/ 0x55 U\n  ,{0x1f, 0x20, 0x40, 0x20, 0x1f} \/\/ 0x56 V\n  ,{0x3f, 0x40, 0x38, 0x40, 0x3f} \/\/ 0x57 W\n  ,{0x63, 0x14, 0x08, 0x14, 0x63} \/\/ 0x58 X\n  ,{0x07, 0x08, 0x70, 0x08, 0x07} \/\/ 0x59 Y\n  ,{0x61, 0x51, 0x49, 0x45, 0x43} \/\/ 0x5a Z\n  ,{0x00, 0x7f, 0x41, 0x41, 0x00} \/\/ 0x5b [\n  ,{0x02, 0x04, 0x08, 0x10, 0x20} \/\/ 0x5c \\ (keep this to escape the backslash)\n  ,{0x00, 0x41, 0x41, 0x7f, 0x00} \/\/ 0x5d ]\n  ,{0x04, 0x02, 0x01, 0x02, 0x04} \/\/ 0x5e ^\n  ,{0x40, 0x40, 0x40, 0x40, 0x40} \/\/ 0x5f _\n  ,{0x00, 0x01, 0x02, 0x04, 0x00} \/\/ 0x60 `\n  ,{0x20, 0x54, 0x54, 0x54, 0x78} \/\/ 0x61 a\n  ,{0x7f, 0x48, 0x44, 0x44, 0x38} \/\/ 0x62 b\n  ,{0x38, 0x44, 0x44, 0x44, 0x20} \/\/ 0x63 c\n  ,{0x38, 0x44, 0x44, 0x48, 0x7f} \/\/ 0x64 d\n  ,{0x38, 0x54, 0x54, 0x54, 0x18} \/\/ 0x65 e\n  ,{0x08, 0x7e, 0x09, 0x01, 0x02} \/\/ 0x66 f\n  ,{0x0c, 0x52, 0x52, 0x52, 0x3e} \/\/ 0x67 g\n  ,{0x7f, 0x08, 0x04, 0x04, 0x78} \/\/ 0x68 h\n  ,{0x00, 0x44, 0x7d, 0x40, 0x00} \/\/ 0x69 i\n  ,{0x20, 0x40, 0x44, 0x3d, 0x00} \/\/ 0x6a j\n  ,{0x7f, 0x10, 0x28, 0x44, 0x00} \/\/ 0x6b k\n  ,{0x00, 0x41, 0x7f, 0x40, 0x00} \/\/ 0x6c l\n  ,{0x7c, 0x04, 0x18, 0x04, 0x78} \/\/ 0x6d m\n  ,{0x7c, 0x08, 0x04, 0x04, 0x78} \/\/ 0x6e n\n  ,{0x38, 0x44, 0x44, 0x44, 0x38} \/\/ 0x6f o\n  ,{0x7c, 0x14, 0x14, 0x14, 0x08} \/\/ 0x70 p\n  ,{0x08, 0x14, 0x14, 0x18, 0x7c} \/\/ 0x71 q\n  ,{0x7c, 0x08, 0x04, 0x04, 0x08} \/\/ 0x72 r\n  ,{0x48, 0x54, 0x54, 0x54, 0x20} \/\/ 0x73 s\n  ,{0x04, 0x3f, 0x44, 0x40, 0x20} \/\/ 0x74 t\n  ,{0x3c, 0x40, 0x40, 0x20, 0x7c} \/\/ 0x75 u\n  ,{0x1c, 0x20, 0x40, 0x20, 0x1c} \/\/ 0x76 v\n  ,{0x3c, 0x40, 0x30, 0x40, 0x3c} \/\/ 0x77 w\n  ,{0x44, 0x28, 0x10, 0x28, 0x44} \/\/ 0x78 x\n  ,{0x0c, 0x50, 0x50, 0x50, 0x3c} \/\/ 0x79 y\n  ,{0x44, 0x64, 0x54, 0x4c, 0x44} \/\/ 0x7a z\n  ,{0x00, 0x08, 0x36, 0x41, 0x00} \/\/ 0x7b {\n  ,{0x00, 0x00, 0x7f, 0x00, 0x00} \/\/ 0x7c |\n  ,{0x00, 0x41, 0x36, 0x08, 0x00} \/\/ 0x7d }\n  ,{0x10, 0x08, 0x08, 0x10, 0x08} \/\/ 0x7e ~\n  ,{0x78, 0x46, 0x41, 0x46, 0x78} \/\/ 0x7f DEL\n};<\/pre><\/div>\n\n\n\n<p>Frame buffer which will be written to the LCD:<\/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;}\">unsigned char displayMap_5110[LCD_WIDTH * LCD_HEIGHT \/ 8] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,0)-&gt;(11,7) ~ These 12 bytes cover an 8x12 block in the left corner of the display\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,0)-&gt;(23,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, \/\/ (24,0)-&gt;(35,7)\n  0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0x1E, 0x0E, 0x02, 0x00, \/\/ (36,0)-&gt;(47,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,0)-&gt;(59,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,0)-&gt;(71,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,0)-&gt;(83,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,8)-&gt;(11,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,8)-&gt;(23,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, \/\/ (24,8)-&gt;(35,15)\n  0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, \/\/ (36,8)-&gt;(47,15)\n  0xF8, 0xF0, 0xF8, 0xFE, 0xFE, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, \/\/ (48,8)-&gt;(59,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,8)-&gt;(71,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,8)-&gt;(83,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,16)-&gt;(11,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,16)-&gt;(23,23)\n  0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xF3, 0xE0, 0xE0, 0xC0, \/\/ (24,16)-&gt;(35,23)\n  0xC0, 0xC0, 0xE0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (36,16)-&gt;(47,23)\n  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x00, 0x00, 0x00, \/\/ (48,16)-&gt;(59,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,16)-&gt;(71,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,16)-&gt;(83,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,24)-&gt;(11,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,24)-&gt;(23,31)\n  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (24,24)-&gt;(35,31)\n  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (36,24)-&gt;(47,31)\n  0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, \/\/ (48,24)-&gt;(59,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,24)-&gt;(71,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,24)-&gt;(83,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,32)-&gt;(11,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,32)-&gt;(23,39)\n  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, \/\/ (24,32)-&gt;(35,39)\n  0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, \/\/ (36,32)-&gt;(47,39)\n  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,32)-&gt;(59,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,32)-&gt;(71,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,32)-&gt;(83,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,40)-&gt;(11,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,40)-&gt;(23,47)\n  0x00, 0x00, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, \/\/ (24,40)-&gt;(35,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (36,40)-&gt;(47,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,40)-&gt;(59,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,40)-&gt;(71,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,40)-&gt;(83,47) !!! The bottom right pixel!\n};<\/pre><\/div>\n\n\n\n<p>Now, we start with the functions.<\/p>\n\n\n\n<p>First function is GPIO initialization for CS,DC and RST pins 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;}\">static void Nokia_5110_Pins_Init(void)\n{\n\t\/*Enable Clock Access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Set PA0, PA1 and PA4 as Output*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE1_0|GPIO_MODER_MODE4_0;\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1|GPIO_MODER_MODE4_1);\n\n}<\/pre><\/div>\n\n\n\n<p>This function is defined as static which can be only used in this source file.<\/p>\n\n\n\n<p>Writing either data or command to the LCD:<\/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;}\">\/*Write data\/command functions*\/\nstatic void LCDcommand(uint8_t data)\n{\n\tCS0;\n\tLCD_COMMAND;\n\tSPI1_Transmit(&amp;data,1);\n\tCS1;\n}\n\nstatic void LCDdata(uint8_t data)\n{\n\tCS0;\n\tLCD_DATA;\n\tSPI1_Transmit(&amp;data,1);\n\tCS1;\n}<\/pre><\/div>\n\n\n\n<p>Defined as static since no other source file had the right to access them.<\/p>\n\n\n\n<p>Setting the pixel value:<\/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;}\">\/\/ color. 1=Black, 0= white.\nstatic void setPixel1(int x, int y, bool bw)\n{\n\t\/\/ First, double check that the coordinate is in range.\n\tif ((x &gt;= 0) &amp;&amp; (x &lt; LCD_WIDTH) &amp;&amp; (y &gt;= 0) &amp;&amp; (y &lt; LCD_HEIGHT))\n\t{\n\t\tint shift = y % 8;\n\n\t\tif (bw) \/\/ If black, set the bit.\n\t\t\tdisplayMap_5110[x + (y\/8)*LCD_WIDTH] |= 1&lt;&lt;shift;\n\t\telse   \/\/ If white clear the bit.\n\t\t\tdisplayMap_5110[x + (y\/8)*LCD_WIDTH] &amp;= ~(1&lt;&lt;shift);\n\t}\n}\n\n\/\/ Because I keep forgetting to put bw variable in when setting...\nstatic void setPixel(int x, int y)\n{\n\tsetPixel1(x, y, BLACK); \/\/ Call setPixel with bw set to Black\n}\n\nstatic void clearPixel(int x, int y)\n{\n\tsetPixel1(x, y, WHITE); \/\/ call setPixel with bw set to white\n}<\/pre><\/div>\n\n\n\n<p>Also declared as static.<\/p>\n\n\n\n<p>Initialization 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;}\">\/\/This sends the magical commands to the PCD8544\nvoid lcdBegin(void)\n{\n\tNokia_5110_Pins_Init();\n\tRST0;\n\tdelay(1000);\n\tRST1;\n\tCS0;\n\tLCDcommand( 0x21); \/\/Tell LCD extended commands follow\n\tdelay(10);\n\tLCDcommand( 0xB0); \/\/Set LCD Vop (Contrast)\n\tdelay(10);\n\tLCDcommand( 0x04); \/\/Set Temp coefficent\n\tdelay(10);\n\tLCDcommand( 0x14); \/\/LCD bias mode 1:48 (try 0x13)\n\tdelay(10);\n\t\/\/We must send 0x20 before modifying the display control mode\n\tLCDcommand( 0x20);\n\tdelay(10);\n\tLCDcommand( 0x0C); \/\/Set display control, normal mode.\n\tdelay(10);\n}<\/pre><\/div>\n\n\n\n<p>Support functions:<\/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;}\">\/\/ setLine draws a line from x0,y0 to x1,y1 with the set color.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setLine(int x0, int y0, int x1, int y1, bool bw)\n{\n\tint dy = y1 - y0; \/\/ Difference between y0 and y1\n\tint dx = x1 - x0; \/\/ Difference between x0 and x1\n\tint stepx, stepy;\n\n\tif (dy &lt; 0)\n\t{\n\t\tdy = -dy;\n\t\tstepy = -1;\n\t}\n\telse\n\t\tstepy = 1;\n\n\tif (dx &lt; 0)\n\t{\n\t\tdx = -dx;\n\t\tstepx = -1;\n\t}\n\telse\n\t\tstepx = 1;\n\n\tdy &lt;&lt;= 1; \/\/ dy is now 2*dy\n\tdx &lt;&lt;= 1; \/\/ dx is now 2*dx\n\tsetPixel1(x0, y0, bw); \/\/ Draw the first pixel.\n\n\tif (dx &gt; dy)\n\t{\n\t\tint fraction = dy - (dx &gt;&gt; 1);\n\t\twhile (x0 != x1)\n\t\t{\n\t\t\tif (fraction &gt;= 0)\n\t\t\t{\n\t\t\t\ty0 += stepy;\n\t\t\t\tfraction -= dx;\n\t\t\t}\n\t\t\tx0 += stepx;\n\t\t\tfraction += dy;\n\t\t\tsetPixel1(x0, y0, bw);\n\t\t}\n\t}\n\telse\n\t{\n\t\tint fraction = dx - (dy &gt;&gt; 1);\n\t\twhile (y0 != y1)\n\t\t{\n\t\t\tif (fraction &gt;= 0)\n\t\t\t{\n\t\t\t\tx0 += stepx;\n\t\t\t\tfraction -= dy;\n\t\t\t}\n\t\t\ty0 += stepy;\n\t\t\tfraction += dx;\n\t\t\tsetPixel1(x0, y0, bw);\n\t\t}\n\t}\n}\n\n\/\/ setRect will draw a rectangle from x0,y0 top-left corner to\n\/\/ a x1,y1 bottom-right corner. Can be filled with the fill\n\/\/ parameter, and colored with bw.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setRect(int x0, int y0, int x1, int y1, bool fill, bool bw)\n{\n\t\/\/ check if the rectangle is to be filled\n\tif (fill == 1)\n\t{\n\t\tint xDiff;\n\n\t\tif(x0 &gt; x1)\n\t\t\txDiff = x0 - x1; \/\/Find the difference between the x vars\n\t\telse\n\t\t\txDiff = x1 - x0;\n\n\twhile(xDiff &gt; 0)\n\t{\n\t\tsetLine(x0, y0, x0, y1, bw);\n\n\t\tif(x0 &gt; x1)\n\t\t\tx0--;\n\t\telse\n\t\t\tx0++;\n\n\t\txDiff--;\n\t\t}\n\t}\n\telse\n\t{\n\t\t\/\/ best way to draw an unfilled rectangle is to draw four lines\n\t\tsetLine(x0, y0, x1, y0, bw);\n\t\tsetLine(x0, y1, x1, y1, bw);\n\t\tsetLine(x0, y0, x0, y1, bw);\n\t\tsetLine(x1, y0, x1, y1, bw);\n\t}\n}\n\n\/\/ setCircle draws a circle centered around x0,y0 with a defined\n\/\/ radius. The circle can be black or white. And have a line\n\/\/ thickness ranging from 1 to the radius of the circle.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setCircle (int x0, int y0, int radius, bool bw, int lineThickness)\n{\n\tfor(int r = 0; r &lt; lineThickness; r++)\n\t{\n\t\tint f = 1 - radius;\n\t\tint ddF_x = 0;\n\t\tint ddF_y = -2 * radius;\n\t\tint x = 0;\n\t\tint y = radius;\n\n\t\tsetPixel1(x0, y0 + radius, bw);\n\t\tsetPixel1(x0, y0 - radius, bw);\n\t\tsetPixel1(x0 + radius, y0, bw);\n\t\tsetPixel1(x0 - radius, y0, bw);\n\n\t\twhile(x &lt; y)\n\t\t{\n\t\t\tif(f &gt;= 0)\n\t\t\t{\n\t\t\t\ty--;\n\t\t\t\tddF_y += 2;\n\t\t\t\tf += ddF_y;\n\t\t\t}\n\t\t\tx++;\n\t\t\tddF_x += 2;\n\t\t\tf += ddF_x + 1;\n\n\t\t\tsetPixel1(x0 + x, y0 + y, bw);\n\t\t\tsetPixel1(x0 - x, y0 + y, bw);\n\t\t\tsetPixel1(x0 + x, y0 - y, bw);\n\t\t\tsetPixel1(x0 - x, y0 - y, bw);\n\t\t\tsetPixel1(x0 + y, y0 + x, bw);\n\t\t\tsetPixel1(x0 - y, y0 + x, bw);\n\t\t\tsetPixel1(x0 + y, y0 - x, bw);\n\t\t\tsetPixel1(x0 - y, y0 - x, bw);\n\t\t}\n\t\tradius--;\n\t}\n}\n\n\/\/ This function will draw a char (defined in the ASCII table\n\/\/ near the beginning of this sketch) at a defined x and y).\n\/\/ The color can be either black (1) or white (0).\nvoid setChar(char character, int x, int y, bool bw)\n{\n\tint column; \/\/ temp byte to store character's column bitmap\n\tfor (int i=0; i&lt;5; i++) \/\/ 5 columns (x) per character\n\t{\n\t\tcolumn = ASCII[character - 0x20][i];\n\t\tfor (int j=0; j&lt;8; j++) \/\/ 8 rows (y) per character\n\t\t{\n\t\t\tif (column &amp; (0x01 &lt;&lt; j)) \/\/ test bits to set pixels\n\t\t\t\tsetPixel1(x+i, y+j, bw);\n\t\t\telse\n\t\t\t\tsetPixel1(x+i, y+j, !bw);\n\t\t}\n\t}\n}\n\n\/\/ setStr draws a string of characters, calling setChar with\n\/\/ progressive coordinates until it's done.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setStr(char * dString, int x, int y, bool bw)\n{\n\twhile (*dString != 0x00) \/\/ loop until null terminator\n\t{\n\t\tsetChar(*dString++, x, y, bw);\n\t\tx+=5;\n\t\tfor (int i=y; i&lt;y+8; i++)\n\t\t{\n\t\t\tsetPixel1(x, i, !bw);\n\t\t}\n\t\tx++;\n\t\tif (x &gt; (LCD_WIDTH - 5)) \/\/ Enables wrap around\n\t\t{\n\t\t\tx = 0;\n\t\t\ty += 8;\n\t\t}\n\t}\n}\n\n\/\/ This function will draw an array over the screen. (For now) the\n\/\/ array must be the same size as the screen, covering the entirety\n\/\/ of the display.\n\/\/ Also, the array must reside in FLASH and declared with PROGMEM.\nvoid SetBitMap(const char * bitArray)\n{\n\tfor (int i=0; i&lt;(LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tchar c = bitArray[i];\n\t\tdisplayMap_5110[i] = c;\n\t}\n}\n\n\/\/ This function clears the entire display either white (0) or\n\/\/ black (1).\n\/\/ The screen won't actually clear until you call updateDisplay()!\nvoid clearDisplay(bool bw)\n{\n\tfor (int i=0; i&lt;(LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tif (bw)\n\t\t\tdisplayMap_5110[i] = 0xFF;\n\telse\n\t\tdisplayMap_5110[i] = 0;\n\t}\n}\n\n\/\/ Helpful function to directly command the LCD to go to a\n\/\/ specific x,y coordinate.\nvoid gotoXY(int x, int y)\n{\n\tLCDcommand(0x80 | x);  \/\/ Column.\n\tLCDcommand( 0x40 | y);  \/\/ Row.  ?\n}\n\n\/\/ This will actually draw on the display, whatever is currently\n\/\/ in the displayMap array.\nvoid updateDisplay(void)\n{\n\tgotoXY(0, 0);\n\tfor (int i=0; i &lt; (LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\tLCDdata( displayMap_5110[i]);\n\t}\n}\n\n\/\/ Set contrast can set the LCD Vop to a value between 0 and 127.\n\/\/ 40-60 is usually a pretty good range.\nvoid setContrast(int contrast)\n{\n\tLCDcommand(0x21); \/\/Tell LCD that extended commands follow\n\tLCDcommand( 0x80 | contrast); \/\/Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark\n\tLCDcommand(0x20); \/\/Set display mode\n}\n\n\/* There are two ways to do this. Either through direct commands\nto the display, or by swapping each bit in the displayMap array.\nWe'll leave both methods here, comment one or the other out if\nyou please. *\/\nvoid invertDisplay(void)\n{\n\t\/* Direct LCD Command option\n\tLCDWrite(LCD_COMMAND, 0x20); \/\/Tell LCD that extended commands follow\n\tLCDWrite(LCD_COMMAND, 0x08 | 0x05); \/\/Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark\n\tLCDWrite(LCD_COMMAND, 0x20); \/\/Set display mode  *\/\n\n\/* Indirect, swap bits in displayMap option: *\/\n\tfor (int i=0; i &lt; (LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tdisplayMap_5110[i] = ~displayMap_5110[i] &amp; 0xFF;\n\t}\n\tupdateDisplay();\n}<\/pre><\/div>\n\n\n\n<p>Entire source 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;}\">#include &quot;Nokia_5110_GLCD.h&quot;\n#include &quot;STM32F4xx.h&quot;\n#include &quot;delay.h&quot;\n#include &lt;stdbool.h&gt;\n#include &quot;SPI1.h&quot;\n\n\/*Macros of CS, RST and DC*\/\n\n#define LCD_COMMAND  \tGPIOA-&gt;BSRR|=GPIO_BSRR_BR0\n#define LCD_DATA    \tGPIOA-&gt;BSRR|=GPIO_BSRR_BS0\n\n#define CS0 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BR1\n#define CS1 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BS1\n\n#define RST0 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BR4\n#define RST1 \t\t\tGPIOA-&gt;BSRR|=GPIO_BSRR_BS4\n\n\n\nstatic const unsigned char ASCII[][5] = {\n  \/\/ First 32 characters (0x00-0x19) are ignored. These are\n  \/\/ non-displayable, control characters.\n   {0x00, 0x00, 0x00, 0x00, 0x00} \/\/ 0x20\n  ,{0x00, 0x00, 0x5f, 0x00, 0x00} \/\/ 0x21 !\n  ,{0x00, 0x07, 0x00, 0x07, 0x00} \/\/ 0x22 &quot;\n  ,{0x14, 0x7f, 0x14, 0x7f, 0x14} \/\/ 0x23 #\n  ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} \/\/ 0x24 $\n  ,{0x23, 0x13, 0x08, 0x64, 0x62} \/\/ 0x25 %\n  ,{0x36, 0x49, 0x55, 0x22, 0x50} \/\/ 0x26 &amp;\n  ,{0x00, 0x05, 0x03, 0x00, 0x00} \/\/ 0x27 '\n  ,{0x00, 0x1c, 0x22, 0x41, 0x00} \/\/ 0x28 (\n  ,{0x00, 0x41, 0x22, 0x1c, 0x00} \/\/ 0x29 )\n  ,{0x14, 0x08, 0x3e, 0x08, 0x14} \/\/ 0x2a *\n  ,{0x08, 0x08, 0x3e, 0x08, 0x08} \/\/ 0x2b +\n  ,{0x00, 0x50, 0x30, 0x00, 0x00} \/\/ 0x2c ,\n  ,{0x08, 0x08, 0x08, 0x08, 0x08} \/\/ 0x2d -\n  ,{0x00, 0x60, 0x60, 0x00, 0x00} \/\/ 0x2e .\n  ,{0x20, 0x10, 0x08, 0x04, 0x02} \/\/ 0x2f \/\n  ,{0x3e, 0x51, 0x49, 0x45, 0x3e} \/\/ 0x30 0\n  ,{0x00, 0x42, 0x7f, 0x40, 0x00} \/\/ 0x31 1\n  ,{0x42, 0x61, 0x51, 0x49, 0x46} \/\/ 0x32 2\n  ,{0x21, 0x41, 0x45, 0x4b, 0x31} \/\/ 0x33 3\n  ,{0x18, 0x14, 0x12, 0x7f, 0x10} \/\/ 0x34 4\n  ,{0x27, 0x45, 0x45, 0x45, 0x39} \/\/ 0x35 5\n  ,{0x3c, 0x4a, 0x49, 0x49, 0x30} \/\/ 0x36 6\n  ,{0x01, 0x71, 0x09, 0x05, 0x03} \/\/ 0x37 7\n  ,{0x36, 0x49, 0x49, 0x49, 0x36} \/\/ 0x38 8\n  ,{0x06, 0x49, 0x49, 0x29, 0x1e} \/\/ 0x39 9\n  ,{0x00, 0x36, 0x36, 0x00, 0x00} \/\/ 0x3a :\n  ,{0x00, 0x56, 0x36, 0x00, 0x00} \/\/ 0x3b ;\n  ,{0x08, 0x14, 0x22, 0x41, 0x00} \/\/ 0x3c &lt;\n  ,{0x14, 0x14, 0x14, 0x14, 0x14} \/\/ 0x3d =\n  ,{0x00, 0x41, 0x22, 0x14, 0x08} \/\/ 0x3e &gt;\n  ,{0x02, 0x01, 0x51, 0x09, 0x06} \/\/ 0x3f ?\n  ,{0x32, 0x49, 0x79, 0x41, 0x3e} \/\/ 0x40 @\n  ,{0x7e, 0x11, 0x11, 0x11, 0x7e} \/\/ 0x41 A\n  ,{0x7f, 0x49, 0x49, 0x49, 0x36} \/\/ 0x42 B\n  ,{0x3e, 0x41, 0x41, 0x41, 0x22} \/\/ 0x43 C\n  ,{0x7f, 0x41, 0x41, 0x22, 0x1c} \/\/ 0x44 D\n  ,{0x7f, 0x49, 0x49, 0x49, 0x41} \/\/ 0x45 E\n  ,{0x7f, 0x09, 0x09, 0x09, 0x01} \/\/ 0x46 F\n  ,{0x3e, 0x41, 0x49, 0x49, 0x7a} \/\/ 0x47 G\n  ,{0x7f, 0x08, 0x08, 0x08, 0x7f} \/\/ 0x48 H\n  ,{0x00, 0x41, 0x7f, 0x41, 0x00} \/\/ 0x49 I\n  ,{0x20, 0x40, 0x41, 0x3f, 0x01} \/\/ 0x4a J\n  ,{0x7f, 0x08, 0x14, 0x22, 0x41} \/\/ 0x4b K\n  ,{0x7f, 0x40, 0x40, 0x40, 0x40} \/\/ 0x4c L\n  ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} \/\/ 0x4d M\n  ,{0x7f, 0x04, 0x08, 0x10, 0x7f} \/\/ 0x4e N\n  ,{0x3e, 0x41, 0x41, 0x41, 0x3e} \/\/ 0x4f O\n  ,{0x7f, 0x09, 0x09, 0x09, 0x06} \/\/ 0x50 P\n  ,{0x3e, 0x41, 0x51, 0x21, 0x5e} \/\/ 0x51 Q\n  ,{0x7f, 0x09, 0x19, 0x29, 0x46} \/\/ 0x52 R\n  ,{0x46, 0x49, 0x49, 0x49, 0x31} \/\/ 0x53 S\n  ,{0x01, 0x01, 0x7f, 0x01, 0x01} \/\/ 0x54 T\n  ,{0x3f, 0x40, 0x40, 0x40, 0x3f} \/\/ 0x55 U\n  ,{0x1f, 0x20, 0x40, 0x20, 0x1f} \/\/ 0x56 V\n  ,{0x3f, 0x40, 0x38, 0x40, 0x3f} \/\/ 0x57 W\n  ,{0x63, 0x14, 0x08, 0x14, 0x63} \/\/ 0x58 X\n  ,{0x07, 0x08, 0x70, 0x08, 0x07} \/\/ 0x59 Y\n  ,{0x61, 0x51, 0x49, 0x45, 0x43} \/\/ 0x5a Z\n  ,{0x00, 0x7f, 0x41, 0x41, 0x00} \/\/ 0x5b [\n  ,{0x02, 0x04, 0x08, 0x10, 0x20} \/\/ 0x5c \\ (keep this to escape the backslash)\n  ,{0x00, 0x41, 0x41, 0x7f, 0x00} \/\/ 0x5d ]\n  ,{0x04, 0x02, 0x01, 0x02, 0x04} \/\/ 0x5e ^\n  ,{0x40, 0x40, 0x40, 0x40, 0x40} \/\/ 0x5f _\n  ,{0x00, 0x01, 0x02, 0x04, 0x00} \/\/ 0x60 `\n  ,{0x20, 0x54, 0x54, 0x54, 0x78} \/\/ 0x61 a\n  ,{0x7f, 0x48, 0x44, 0x44, 0x38} \/\/ 0x62 b\n  ,{0x38, 0x44, 0x44, 0x44, 0x20} \/\/ 0x63 c\n  ,{0x38, 0x44, 0x44, 0x48, 0x7f} \/\/ 0x64 d\n  ,{0x38, 0x54, 0x54, 0x54, 0x18} \/\/ 0x65 e\n  ,{0x08, 0x7e, 0x09, 0x01, 0x02} \/\/ 0x66 f\n  ,{0x0c, 0x52, 0x52, 0x52, 0x3e} \/\/ 0x67 g\n  ,{0x7f, 0x08, 0x04, 0x04, 0x78} \/\/ 0x68 h\n  ,{0x00, 0x44, 0x7d, 0x40, 0x00} \/\/ 0x69 i\n  ,{0x20, 0x40, 0x44, 0x3d, 0x00} \/\/ 0x6a j\n  ,{0x7f, 0x10, 0x28, 0x44, 0x00} \/\/ 0x6b k\n  ,{0x00, 0x41, 0x7f, 0x40, 0x00} \/\/ 0x6c l\n  ,{0x7c, 0x04, 0x18, 0x04, 0x78} \/\/ 0x6d m\n  ,{0x7c, 0x08, 0x04, 0x04, 0x78} \/\/ 0x6e n\n  ,{0x38, 0x44, 0x44, 0x44, 0x38} \/\/ 0x6f o\n  ,{0x7c, 0x14, 0x14, 0x14, 0x08} \/\/ 0x70 p\n  ,{0x08, 0x14, 0x14, 0x18, 0x7c} \/\/ 0x71 q\n  ,{0x7c, 0x08, 0x04, 0x04, 0x08} \/\/ 0x72 r\n  ,{0x48, 0x54, 0x54, 0x54, 0x20} \/\/ 0x73 s\n  ,{0x04, 0x3f, 0x44, 0x40, 0x20} \/\/ 0x74 t\n  ,{0x3c, 0x40, 0x40, 0x20, 0x7c} \/\/ 0x75 u\n  ,{0x1c, 0x20, 0x40, 0x20, 0x1c} \/\/ 0x76 v\n  ,{0x3c, 0x40, 0x30, 0x40, 0x3c} \/\/ 0x77 w\n  ,{0x44, 0x28, 0x10, 0x28, 0x44} \/\/ 0x78 x\n  ,{0x0c, 0x50, 0x50, 0x50, 0x3c} \/\/ 0x79 y\n  ,{0x44, 0x64, 0x54, 0x4c, 0x44} \/\/ 0x7a z\n  ,{0x00, 0x08, 0x36, 0x41, 0x00} \/\/ 0x7b {\n  ,{0x00, 0x00, 0x7f, 0x00, 0x00} \/\/ 0x7c |\n  ,{0x00, 0x41, 0x36, 0x08, 0x00} \/\/ 0x7d }\n  ,{0x10, 0x08, 0x08, 0x10, 0x08} \/\/ 0x7e ~\n  ,{0x78, 0x46, 0x41, 0x46, 0x78} \/\/ 0x7f DEL\n};\n\n\nunsigned char displayMap_5110[LCD_WIDTH * LCD_HEIGHT \/ 8] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,0)-&gt;(11,7) ~ These 12 bytes cover an 8x12 block in the left corner of the display\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,0)-&gt;(23,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, \/\/ (24,0)-&gt;(35,7)\n  0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0x1E, 0x0E, 0x02, 0x00, \/\/ (36,0)-&gt;(47,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,0)-&gt;(59,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,0)-&gt;(71,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,0)-&gt;(83,7)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,8)-&gt;(11,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,8)-&gt;(23,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, \/\/ (24,8)-&gt;(35,15)\n  0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, \/\/ (36,8)-&gt;(47,15)\n  0xF8, 0xF0, 0xF8, 0xFE, 0xFE, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, \/\/ (48,8)-&gt;(59,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,8)-&gt;(71,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,8)-&gt;(83,15)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,16)-&gt;(11,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,16)-&gt;(23,23)\n  0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xF3, 0xE0, 0xE0, 0xC0, \/\/ (24,16)-&gt;(35,23)\n  0xC0, 0xC0, 0xE0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (36,16)-&gt;(47,23)\n  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x00, 0x00, 0x00, \/\/ (48,16)-&gt;(59,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,16)-&gt;(71,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,16)-&gt;(83,23)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,24)-&gt;(11,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,24)-&gt;(23,31)\n  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (24,24)-&gt;(35,31)\n  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \/\/ (36,24)-&gt;(47,31)\n  0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, \/\/ (48,24)-&gt;(59,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,24)-&gt;(71,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,24)-&gt;(83,31)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,32)-&gt;(11,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,32)-&gt;(23,39)\n  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, \/\/ (24,32)-&gt;(35,39)\n  0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, \/\/ (36,32)-&gt;(47,39)\n  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,32)-&gt;(59,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,32)-&gt;(71,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,32)-&gt;(83,39)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (0,40)-&gt;(11,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (12,40)-&gt;(23,47)\n  0x00, 0x00, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, \/\/ (24,40)-&gt;(35,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (36,40)-&gt;(47,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (48,40)-&gt;(59,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (60,40)-&gt;(71,47)\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \/\/ (72,40)-&gt;(83,47) !!! The bottom right pixel!\n};\n\n\nstatic void Nokia_5110_Pins_Init(void)\n{\n\t\/*Enable Clock Access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Set PA0, PA1 and PA4 as Output*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE1_0|GPIO_MODER_MODE4_0;\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1|GPIO_MODER_MODE4_1);\n\n}\n\n\/*Write data\/command functions*\/\nstatic void LCDcommand(uint8_t data)\n{\n\tCS0;\n\tLCD_COMMAND;\n\tSPI1_Transmit(&amp;data,1);\n\tCS1;\n}\n\nstatic void LCDdata(uint8_t data)\n{\n\tCS0;\n\tLCD_DATA;\n\tSPI1_Transmit(&amp;data,1);\n\tCS1;\n}\n\/\/ This function sets a pixel on displayMap to your preferred\n\/\/ color. 1=Black, 0= white.\nstatic void setPixel1(int x, int y, bool bw)\n{\n\t\/\/ First, double check that the coordinate is in range.\n\tif ((x &gt;= 0) &amp;&amp; (x &lt; LCD_WIDTH) &amp;&amp; (y &gt;= 0) &amp;&amp; (y &lt; LCD_HEIGHT))\n\t{\n\t\tint shift = y % 8;\n\n\t\tif (bw) \/\/ If black, set the bit.\n\t\t\tdisplayMap_5110[x + (y\/8)*LCD_WIDTH] |= 1&lt;&lt;shift;\n\t\telse   \/\/ If white clear the bit.\n\t\t\tdisplayMap_5110[x + (y\/8)*LCD_WIDTH] &amp;= ~(1&lt;&lt;shift);\n\t}\n}\n\n\/\/ Because I keep forgetting to put bw variable in when setting...\nstatic void setPixel(int x, int y)\n{\n\tsetPixel1(x, y, BLACK); \/\/ Call setPixel with bw set to Black\n}\n\nstatic void clearPixel(int x, int y)\n{\n\tsetPixel1(x, y, WHITE); \/\/ call setPixel with bw set to white\n}\n\n\/\/ setLine draws a line from x0,y0 to x1,y1 with the set color.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setLine(int x0, int y0, int x1, int y1, bool bw)\n{\n\tint dy = y1 - y0; \/\/ Difference between y0 and y1\n\tint dx = x1 - x0; \/\/ Difference between x0 and x1\n\tint stepx, stepy;\n\n\tif (dy &lt; 0)\n\t{\n\t\tdy = -dy;\n\t\tstepy = -1;\n\t}\n\telse\n\t\tstepy = 1;\n\n\tif (dx &lt; 0)\n\t{\n\t\tdx = -dx;\n\t\tstepx = -1;\n\t}\n\telse\n\t\tstepx = 1;\n\n\tdy &lt;&lt;= 1; \/\/ dy is now 2*dy\n\tdx &lt;&lt;= 1; \/\/ dx is now 2*dx\n\tsetPixel1(x0, y0, bw); \/\/ Draw the first pixel.\n\n\tif (dx &gt; dy)\n\t{\n\t\tint fraction = dy - (dx &gt;&gt; 1);\n\t\twhile (x0 != x1)\n\t\t{\n\t\t\tif (fraction &gt;= 0)\n\t\t\t{\n\t\t\t\ty0 += stepy;\n\t\t\t\tfraction -= dx;\n\t\t\t}\n\t\t\tx0 += stepx;\n\t\t\tfraction += dy;\n\t\t\tsetPixel1(x0, y0, bw);\n\t\t}\n\t}\n\telse\n\t{\n\t\tint fraction = dx - (dy &gt;&gt; 1);\n\t\twhile (y0 != y1)\n\t\t{\n\t\t\tif (fraction &gt;= 0)\n\t\t\t{\n\t\t\t\tx0 += stepx;\n\t\t\t\tfraction -= dy;\n\t\t\t}\n\t\t\ty0 += stepy;\n\t\t\tfraction += dx;\n\t\t\tsetPixel1(x0, y0, bw);\n\t\t}\n\t}\n}\n\n\/\/ setRect will draw a rectangle from x0,y0 top-left corner to\n\/\/ a x1,y1 bottom-right corner. Can be filled with the fill\n\/\/ parameter, and colored with bw.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setRect(int x0, int y0, int x1, int y1, bool fill, bool bw)\n{\n\t\/\/ check if the rectangle is to be filled\n\tif (fill == 1)\n\t{\n\t\tint xDiff;\n\n\t\tif(x0 &gt; x1)\n\t\t\txDiff = x0 - x1; \/\/Find the difference between the x vars\n\t\telse\n\t\t\txDiff = x1 - x0;\n\n\twhile(xDiff &gt; 0)\n\t{\n\t\tsetLine(x0, y0, x0, y1, bw);\n\n\t\tif(x0 &gt; x1)\n\t\t\tx0--;\n\t\telse\n\t\t\tx0++;\n\n\t\txDiff--;\n\t\t}\n\t}\n\telse\n\t{\n\t\t\/\/ best way to draw an unfilled rectangle is to draw four lines\n\t\tsetLine(x0, y0, x1, y0, bw);\n\t\tsetLine(x0, y1, x1, y1, bw);\n\t\tsetLine(x0, y0, x0, y1, bw);\n\t\tsetLine(x1, y0, x1, y1, bw);\n\t}\n}\n\n\/\/ setCircle draws a circle centered around x0,y0 with a defined\n\/\/ radius. The circle can be black or white. And have a line\n\/\/ thickness ranging from 1 to the radius of the circle.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setCircle (int x0, int y0, int radius, bool bw, int lineThickness)\n{\n\tfor(int r = 0; r &lt; lineThickness; r++)\n\t{\n\t\tint f = 1 - radius;\n\t\tint ddF_x = 0;\n\t\tint ddF_y = -2 * radius;\n\t\tint x = 0;\n\t\tint y = radius;\n\n\t\tsetPixel1(x0, y0 + radius, bw);\n\t\tsetPixel1(x0, y0 - radius, bw);\n\t\tsetPixel1(x0 + radius, y0, bw);\n\t\tsetPixel1(x0 - radius, y0, bw);\n\n\t\twhile(x &lt; y)\n\t\t{\n\t\t\tif(f &gt;= 0)\n\t\t\t{\n\t\t\t\ty--;\n\t\t\t\tddF_y += 2;\n\t\t\t\tf += ddF_y;\n\t\t\t}\n\t\t\tx++;\n\t\t\tddF_x += 2;\n\t\t\tf += ddF_x + 1;\n\n\t\t\tsetPixel1(x0 + x, y0 + y, bw);\n\t\t\tsetPixel1(x0 - x, y0 + y, bw);\n\t\t\tsetPixel1(x0 + x, y0 - y, bw);\n\t\t\tsetPixel1(x0 - x, y0 - y, bw);\n\t\t\tsetPixel1(x0 + y, y0 + x, bw);\n\t\t\tsetPixel1(x0 - y, y0 + x, bw);\n\t\t\tsetPixel1(x0 + y, y0 - x, bw);\n\t\t\tsetPixel1(x0 - y, y0 - x, bw);\n\t\t}\n\t\tradius--;\n\t}\n}\n\n\/\/ This function will draw a char (defined in the ASCII table\n\/\/ near the beginning of this sketch) at a defined x and y).\n\/\/ The color can be either black (1) or white (0).\nvoid setChar(char character, int x, int y, bool bw)\n{\n\tint column; \/\/ temp byte to store character's column bitmap\n\tfor (int i=0; i&lt;5; i++) \/\/ 5 columns (x) per character\n\t{\n\t\tcolumn = ASCII[character - 0x20][i];\n\t\tfor (int j=0; j&lt;8; j++) \/\/ 8 rows (y) per character\n\t\t{\n\t\t\tif (column &amp; (0x01 &lt;&lt; j)) \/\/ test bits to set pixels\n\t\t\t\tsetPixel1(x+i, y+j, bw);\n\t\t\telse\n\t\t\t\tsetPixel1(x+i, y+j, !bw);\n\t\t}\n\t}\n}\n\n\/\/ setStr draws a string of characters, calling setChar with\n\/\/ progressive coordinates until it's done.\n\/\/ This function was grabbed from the SparkFun ColorLCDShield\n\/\/ library.\nvoid setStr(char * dString, int x, int y, bool bw)\n{\n\twhile (*dString != 0x00) \/\/ loop until null terminator\n\t{\n\t\tsetChar(*dString++, x, y, bw);\n\t\tx+=5;\n\t\tfor (int i=y; i&lt;y+8; i++)\n\t\t{\n\t\t\tsetPixel1(x, i, !bw);\n\t\t}\n\t\tx++;\n\t\tif (x &gt; (LCD_WIDTH - 5)) \/\/ Enables wrap around\n\t\t{\n\t\t\tx = 0;\n\t\t\ty += 8;\n\t\t}\n\t}\n}\n\n\/\/ This function will draw an array over the screen. (For now) the\n\/\/ array must be the same size as the screen, covering the entirety\n\/\/ of the display.\n\/\/ Also, the array must reside in FLASH and declared with PROGMEM.\nvoid SetBitMap(const char * bitArray)\n{\n\tfor (int i=0; i&lt;(LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tchar c = bitArray[i];\n\t\tdisplayMap_5110[i] = c;\n\t}\n}\n\n\/\/ This function clears the entire display either white (0) or\n\/\/ black (1).\n\/\/ The screen won't actually clear until you call updateDisplay()!\nvoid clearDisplay(bool bw)\n{\n\tfor (int i=0; i&lt;(LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tif (bw)\n\t\t\tdisplayMap_5110[i] = 0xFF;\n\telse\n\t\tdisplayMap_5110[i] = 0;\n\t}\n}\n\n\/\/ Helpful function to directly command the LCD to go to a\n\/\/ specific x,y coordinate.\nvoid gotoXY(int x, int y)\n{\n\tLCDcommand(0x80 | x);  \/\/ Column.\n\tLCDcommand( 0x40 | y);  \/\/ Row.  ?\n}\n\n\/\/ This will actually draw on the display, whatever is currently\n\/\/ in the displayMap array.\nvoid updateDisplay(void)\n{\n\tgotoXY(0, 0);\n\tfor (int i=0; i &lt; (LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\tLCDdata( displayMap_5110[i]);\n\t}\n}\n\n\/\/ Set contrast can set the LCD Vop to a value between 0 and 127.\n\/\/ 40-60 is usually a pretty good range.\nvoid setContrast(int contrast)\n{\n\tLCDcommand(0x21); \/\/Tell LCD that extended commands follow\n\tLCDcommand( 0x80 | contrast); \/\/Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark\n\tLCDcommand(0x20); \/\/Set display mode\n}\n\n\/* There are two ways to do this. Either through direct commands\nto the display, or by swapping each bit in the displayMap array.\nWe'll leave both methods here, comment one or the other out if\nyou please. *\/\nvoid invertDisplay(void)\n{\n\t\/* Direct LCD Command option\n\tLCDWrite(LCD_COMMAND, 0x20); \/\/Tell LCD that extended commands follow\n\tLCDWrite(LCD_COMMAND, 0x08 | 0x05); \/\/Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark\n\tLCDWrite(LCD_COMMAND, 0x20); \/\/Set display mode  *\/\n\n\/* Indirect, swap bits in displayMap option: *\/\n\tfor (int i=0; i &lt; (LCD_WIDTH * LCD_HEIGHT \/ 8); i++)\n\t{\n\t\tdisplayMap_5110[i] = ~displayMap_5110[i] &amp; 0xFF;\n\t}\n\tupdateDisplay();\n}\n\n\/\/This sends the magical commands to the PCD8544\nvoid lcdBegin(void)\n{\n\tNokia_5110_Pins_Init();\n\tRST0;\n\tdelay(1000);\n\tRST1;\n\tCS0;\n\tLCDcommand( 0x21); \/\/Tell LCD extended commands follow\n\tdelay(10);\n\tLCDcommand( 0xB0); \/\/Set LCD Vop (Contrast)\n\tdelay(10);\n\tLCDcommand( 0x04); \/\/Set Temp coefficent\n\tdelay(10);\n\tLCDcommand( 0x14); \/\/LCD bias mode 1:48 (try 0x13)\n\tdelay(10);\n\t\/\/We must send 0x20 before modifying the display control mode\n\tLCDcommand( 0x20);\n\tdelay(10);\n\tLCDcommand( 0x0C); \/\/Set display control, normal mode.\n\tdelay(10);\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.Main.c:<\/h2>\n\n\n\n<p>In main.c 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;}\">#include &quot;delay.h&quot;\n#include &quot;Nokia_5110_GLCD.h&quot;\n#include &quot;SPI1.h&quot;\n#include &lt;math.h&gt;\n\n\n#define PI 3.14\n\n\nstatic const char xkcdSandwich[504] = {\n0xFF, 0x8D, 0x9F, 0x13, 0x13, 0xF3, 0x01, 0x01, 0xF9, 0xF9, 0x01, 0x81, 0xF9, 0xF9, 0x01, 0xF1,\n0xF9, 0x09, 0x09, 0xFF, 0xFF, 0xF1, 0xF9, 0x09, 0x09, 0xF9, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01,\n0xF9, 0xF9, 0x09, 0xF9, 0x09, 0xF9, 0xF1, 0x01, 0xC1, 0xE9, 0x29, 0x29, 0xF9, 0xF1, 0x01, 0xFF,\n0xFF, 0x71, 0xD9, 0x01, 0x01, 0xF1, 0xF9, 0x29, 0x29, 0xB9, 0xB1, 0x01, 0x01, 0x01, 0xF1, 0xF1,\n0x11, 0xF1, 0xF1, 0xF1, 0xE1, 0x01, 0xE1, 0xF1, 0x51, 0x51, 0x71, 0x61, 0x01, 0x01, 0xC1, 0xF1,\n0x31, 0x31, 0xF1, 0xFF, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x01, 0x60, 0xE0, 0xA0, 0x01, 0x01, 0x81,\n0xE1, 0x61, 0x60, 0xC0, 0x01, 0xE1, 0xE1, 0x21, 0x21, 0xE0, 0xC1, 0x01, 0xC1, 0xE1, 0x20, 0x20,\n0xFC, 0xFC, 0xE0, 0xE0, 0xC1, 0xE1, 0xE0, 0xC1, 0xE0, 0xE1, 0x01, 0xFC, 0xFC, 0x21, 0x21, 0xE1,\n0xC1, 0xE5, 0xE4, 0x01, 0xC1, 0xE0, 0x20, 0x21, 0x20, 0x00, 0x01, 0xFD, 0xFD, 0x21, 0x20, 0xE0,\n0x00, 0x00, 0x01, 0x01, 0xC0, 0x61, 0x31, 0x31, 0x21, 0x20, 0xC0, 0x81, 0x01, 0x01, 0x01, 0x00,\n0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02,\n0x03, 0x01, 0x00, 0x01, 0x03, 0xF2, 0x1A, 0x0B, 0x08, 0x0B, 0x1B, 0x10, 0x60, 0xE3, 0x03, 0x00,\n0x01, 0x03, 0x02, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03,\n0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, 0x02, 0x02, 0x03, 0x01, 0x00, 0x03,\n0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x80, 0x80, 0x80, 0x80, 0x60, 0x3F, 0x07,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x01, 0x01, 0x02, 0x03, 0x3E, 0xE8, 0xF8, 0xF0, 0xD0, 0x90,\n0x18, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0xFF,\n0x0C, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,\n0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,\n0x5F, 0x8F, 0x84, 0x05, 0x07, 0x06, 0x0C, 0x0E, 0x0E, 0x0C, 0x14, 0x34, 0x68, 0x88, 0xD8, 0x70,\n0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0xE0, 0x00, 0xF0, 0xF0, 0x00, 0x80,\n0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x20, 0x38,\n0x0E, 0x01, 0xC0, 0x3F, 0xE0, 0x00, 0x00, 0x03, 0x0E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xB6, 0xED, 0xC0, 0xC0,\n0xC0, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xE1, 0xE1, 0xC1,\n0xEF, 0xBB, 0x83, 0x86, 0x88, 0xB0, 0x80, 0x80, 0x80, 0x8F, 0x90, 0x90, 0x90, 0x9F, 0x8F, 0x80,\n0x9F, 0x9F, 0x87, 0x8D, 0x98, 0x80, 0x8C, 0x9E, 0x92, 0x92, 0x9F, 0xC0, 0xC7, 0xFF, 0xB8, 0x8F,\n0x80, 0x90, 0x90, 0xC0, 0xF0, 0x8E, 0x81, 0x80, 0x81, 0x8F, 0xB8, 0xE0, 0x80, 0x80, 0x80, 0x80,\n0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF,\n};\n\n\nint main(void)\n{\n\tSPI1_Pins_Init();\n\tSPI1_Init();\n\tlcdBegin();\n\tsetContrast(50);\n\tupdateDisplay();\n\n\twhile(1)\n\t{\n\t\tsetStr(&quot;STM32 NOKIA5110 bare metal&quot;, 0, LCD_HEIGHT-8, BLACK);\n\t\tupdateDisplay();\n\t\tdelay(1000);\n\t\tfor (int i=0; i&lt;5; i++)\n\t\t{\n\t\tinvertDisplay();\n\t\tdelay(200);\n\t\tinvertDisplay();\n\t\tdelay(200);\n\t\t}\n\t\tdelay(2000);\n\n\n\t\tclearDisplay(WHITE);\n\t\tint x0 = LCD_WIDTH\/2;\n\t\tint y0 = LCD_HEIGHT\/2;\n\t\tfor (float i=0; i&lt;2*PI; i+=PI\/8)\n\t\t{\n\t\tconst int lineLength = 24;\n\t\tint x1 = x0 + lineLength * sin(i);\n\t\tint y1 = y0 + lineLength * cos(i);\n\t\tsetLine(x0, y0, x1, y1, BLACK);\n\t\t\/\/updateDisplay();\n\t\tdelay(100);\n\t\t}\n\t\tclearDisplay(WHITE); \/\/ Start fresh\n\t\tfor (int x=0; x&lt;LCD_WIDTH; x+=8)\n\t\t{ \/\/ Swipe right black\n\t\tsetRect(0, 0, x, LCD_HEIGHT, 1, BLACK);\n\t\t\/\/ updateDisplay();\n\t\tdelay(10);\n\t\t}\n\t\tfor (int x=0; x&lt;LCD_WIDTH; x+=8)\n\t\t{\n\t\tsetRect(0, 0, x, LCD_HEIGHT, 1, WHITE);\n\t\t\/\/updateDisplay();\n\t\tdelay(10);\n\t\t}\n\t\tfor (int x=0; x&lt;12; x++)\n\t\t{\n\t\tsetRect(0, 0, x, LCD_HEIGHT, 1, 1);\n\t\tsetRect(11, 0, x+12, LCD_HEIGHT, 1, BLACK);\n\t\tsetRect(23, 0, x+24, LCD_HEIGHT, 1, BLACK);\n\t\tsetRect(35, 0, x+36, LCD_HEIGHT, 1, BLACK);\n\t\tsetRect(47, 0, x+48, LCD_HEIGHT, 1, BLACK);\n\t\tsetRect(59, 0, x+60, LCD_HEIGHT, 1, BLACK);\n\t\tsetRect(71, 0, x+72, LCD_HEIGHT, 1, BLACK);\n\t\tupdateDisplay();\n\t\tdelay(10);\n\t\t}\n\t\tsetRect(25, 10, 45, 30, 0, WHITE);\n\t\tsetRect(35, 20, 55, 40, 0, WHITE);\n\t\tsetLine(25, 10, 35, 20, WHITE);\n\t\tsetLine(45, 30, 55, 40, WHITE);\n\t\tsetLine(25, 30, 35, 40, WHITE);\n\t\tsetLine(45, 10, 55, 20, WHITE);\n\t\tupdateDisplay();\n\t\tdelay(2000);\n\t\tclearDisplay(WHITE);\n\t\tSetBitMap(xkcdSandwich);\n\t\tdelay(2000);\n\t}\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Code:<\/h2>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Nokia_5110_GLCD.zip\">Nokia_5110_GLCD<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Nokia_5110_GLCD.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Results:<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Nokia 5110 GLCD with STM32F4\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/56QW_Yk2dQQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In this revised version of Nokia 5110 Display, we shall interface this type of LCD with STM32 and develop the appropriate driver to driver the screen to display texts and pictures. In this guid, we shall cover the following: Nokia 5110 Graphic LCD. LCD connection with STM32. SPI driver. Display driver. Main code. Code download. [&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-2112","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\/2112"}],"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=2112"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2112\/revisions"}],"predecessor-version":[{"id":2117,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2112\/revisions\/2117"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}