{"id":13303,"date":"2017-04-24T14:14:11","date_gmt":"2017-04-24T18:14:11","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=13303"},"modified":"2018-06-13T23:32:37","modified_gmt":"2018-06-14T03:32:37","slug":"starting-stm8-microcontrollers","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/starting-stm8-microcontrollers\/","title":{"rendered":"Starting STM8 Microcontrollers"},"content":{"rendered":"<p style=\"text-align: justify\">STM8 microcontrollers are 8-bit general purpose microcontrollers from <strong>STMicroelectronics (STM)<\/strong>. STM is famous mainly for its line of 32-bit ARM Cortex microcontrollers \u2013 the STM32s. STM8 microcontrollers are rarely discussed in that context. However, STM8 MCUs are robust and most importantly they come packed with lots of hardware features. Except for the ARM core, 32-bit architecture, performance and some minor differences, STM8s have many peripheral similarities with STM32s. In my opinion, STM8s are equally or sometimes more matched than the popular PICs and AVRs in all areas. Unlike PICs and AVRs however, I have seen STM8s mostly in various SMD packages. Only a handful of STM8 chips are available in Plastic Dual-Inline Package (PDIP)\/through-hole packages. I think it is a big reason for which most small industries and hobbyists don\u2019t play with them as much as with other 8-bit families. People like to setup their test projects in breadboards, trial PCBs or strip-boards first, prototype and then develop for production. To cope with this issue, STM has provided several affordable STM8 Discovery (Disco) boards to get started with. Besides there are many cheap STM8 breakout-boards from China.<a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8003-Discovery.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13305 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8003-Discovery-580x244.jpg\" alt=\"STM8S003K3 Discovery\" width=\"580\" height=\"244\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8003-Discovery-580x244.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8003-Discovery.jpg 600w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><!--more--><\/p>\n<p style=\"text-align: justify\">I have experience playing with AVRs, PICs, 8051s, STM32s, MSP430s, TivaC and so on. To be honest, I thought learning about STM8 micros is a pure waste of time and energy. The learning curve will be steep. Things and tools would be different and thus difficult. However, gradually I found these MCUs very useful and there is literally no complexity at all. The main drive factor for learning STM8s is the price factor. They are very cheap. When it comes down to other things, I have not found any book on STM8s written in English. There is literally no 100% complete blog post on the internet that shows the basics. Similarly, same story with tools. I have been using MikroC for AVRs, 8051s and ARMs and it is my favourite but at the time of writing, there\u2019s no MikroC compiler for STM8 family. I have also not stumbled upon any Arduino-like IDE that supports STM8 micros. Arduino-based solutions are also not my favourite as they don\u2019t go deep and have several limitations. Maybe it is not my luck. After much study and search, I found out that there are a few C compilers for STM8s. However, any new tool is both different and difficult at first. It is not always easy to adapt to new environments. You may never know what unanticipated challenges and harshness a new environment may throw at you even when you reach certain levels of expertise. I also don\u2019t want to use any pirated software and so a free compiler was a major requirement. I found out ST Visual Develop and Cosmic COSC compiler are both free tools. Cosmic used to be a paid tool but now it is absolutely free. The only easy thing till then was buying the STM8S Value Line Discovery board for just a few dollars and downloading the stuffs.<\/p>\n<h2 style=\"text-align: justify\"><span lang=\"EN-GB\">The STM8 Family<\/span><\/h2>\n<p>There are over a hundred STM8 microcontrollers available today. The STM8 family can be simplified into three categorical groups as shown below.<a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8-Family.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13313 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8-Family.png\" alt=\"STM8 Family\" width=\"474\" height=\"288\" \/><\/a><\/p>\n<p style=\"text-align: justify\">There are subgroups within these groups but broadly speaking these three groups are what by which we can define the entire family. STM8S micros are general purpose robust and reliable micros that can be employed in almost all scopes. This is the most commonly used group and in fact we will be exploring it in this article. They are also cheap and smart. The second group \u2013 the STM8A family is intended mainly for automotive industries. This group is packed with additional hardware interfaces like CAN and LIN that are musts according to present-day automotive industry doctrine. The STM8As are also very versatile and are designed to withstand the harsh extremes of an automobile. For instance, STM8As can withstand high temperatures, in excess of 100\u00b0C. The last group consists of STM8L micros which are crafted for low power or battery-backed applications. Virtually they consume no power in idle mode. Thus, if you need high power savings or energy cuts in your projects, this group is the right choice. There are also low power editions of automotive-standard STM8 micros that are labelled STM8AL. Apart from all these there is also one variant of STM8 micros that are specifically designed for capacitive touch applications. These are called STM8Ts.<\/p>\n<p style=\"text-align: justify\">The features and benefits of STM8 micros are numerous and can\u2019t simply be expressed in few words. The more you explore, the more you will know. STM8s can be powered with 3.3V or 5V DC power supplies and have built-in brownout detection circuitry. The low power editions can operate at much lower voltages than these values. Official STM8 Discovery boards come with voltage selection jumpers to allow users to select operating voltage level as required. There is very minimum risk of program corruption due to EMI or some other similar unprecedented factors. There is a fail-safe security system for the clock system which ensures that a system based on a STM8 micro won\u2019t stop working or get stuck up should its external clock source fail. All internal hardware possesses more features than any other competitive 8-bit microcontroller families that are widely available in the market. The best part is the price benefit. You pay less for most. All these features are well-suited for extremely harsh industrial environments. STM8s are designed with maximum possible combinations of features. Beyond your wildest wet dream, there are many extraordinary stuffs waiting to be unboxed.<\/p>\n<p><!--nextpage--><\/p>\n<h2><span lang=\"EN-GB\">Overview of the Discovery Board<\/span><\/h2>\n<p style=\"text-align: justify\">For getting started with STM8s, STM has provided several STM8 Disco boards. There are also other third-party boards too. However, I strongly recommend Disco boards for learning and experimental purposes. There are several reasons for this recommendation. One main reason is the fact that all Disco boards come with on-board detachable ST-Link programmers and they are extremely cheap. Shown below is the top layout of a STM8S discovery board.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Layout.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13317 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Layout-580x328.png\" alt=\"Layout\" width=\"580\" height=\"328\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Layout-580x328.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Layout.png 805w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">The board I mostly used here in this article hosts a STM8S003K3T6 micro. It is a 32-pin entry-level microcontroller with 8kB flash memory, 1kB RAM and 128-byte true data EEPROM. It comes with some additional hardware \u2013 a LED connected to PD0 and a push button connected to PB7. Just as I stated before it also houses a detachable ST-Link V2 programmer. However, I don\u2019t recommend separating the programmer from the whole package. The board also has a prototyping area should one needs to prototype something. The overall board has a small form-factor and is a bit longer than a standard credit card. There are several other similar and popular STM8 Discovery boards like the STM8S105 Discovery.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S105-Discovery.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13315 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S105-Discovery.jpg\" alt=\"STM8S105 Discovery\" width=\"566\" height=\"230\" \/><\/a><\/p>\n<p style=\"text-align: justify\">There are also bulks of cheap Chinese minimum system STM8 development boards hosting different STM8 chips. Overall the boards and the chips are so cheap that many simple cheap gadgets from China are based on STM8 MCUs.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cheap-STM8-Boards.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13309 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cheap-STM8-Boards-580x433.png\" alt=\"Cheap STM8 Boards\" width=\"580\" height=\"433\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cheap-STM8-Boards-580x433.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cheap-STM8-Boards.png 602w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>Some cheap STM8-based simple products are shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Products.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13310 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Products-580x196.png\" alt=\"Products\" width=\"580\" height=\"196\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Products-580x196.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Products-1024x346.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Products.png 1089w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>The first one is a cheap DIY LC meter LC-100A. The other one is a simple DC panel meter. These are just simple examples. There are many industrial and sophisticated products based on STM8 micros.<br \/>\n<!--nextpage--><\/p>\n<h2 style=\"margin-top: 0in\"><span lang=\"EN-GB\">Hardware Tools<\/span><\/h2>\n<p style=\"text-align: justify\">The list of hardware tools needed is not very long.\u00a0 We will obviously need a STM8 board and I prefer a Discovery board over any other board since it comes with a built-in ST-Link programmer\/debugger hardware. If you have some other board like the ones I already showed, you will need a ST-Link programmer. I recommend an additional ST-Link programmer apart from the one available on board.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ST-LINK.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13312 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ST-LINK.png\" alt=\"ST-LINK\" width=\"534\" height=\"462\" \/><\/a><\/p>\n<p style=\"text-align: justify\">ST-Link programmers\/debuggers communicate with target STM8 micros via SWIM interface. This interface is the standard for all STM8 micros. Basically, it is a four-wire interface with two wires (VDD and GND) being used for powering the target. The rest two are reset I\/O and SWIM I\/O. In the official ST-Link V2 programmer unlike other ST-Link programmers, there is a dedicated port for SWIM interface with STM8 inscribed near it. Cheap USB thumb drive-sized ST-Links are also available in the market. They are portable and as good as the official ones. You can also DIY your own ST-Link programmer as the design for it is open source.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SWIM-Interface.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13316 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SWIM-Interface.png\" alt=\"SWIM Interface\" width=\"510\" height=\"183\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Apart from these we will also require some basic electronic lab stuffs like a USB-to-serial converter, connecting\/jumper wires, LEDs, buttons, various types of sensors, etc. that are typically found in a common Arduino starter kit.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Arduino-Starter-Kit.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13307 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Arduino-Starter-Kit.jpg\" alt=\"Arduino Starter Kit\" width=\"500\" height=\"500\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Arduino-Starter-Kit.jpg 500w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Arduino-Starter-Kit-150x150.jpg 150w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Arduino-Starter-Kit-90x90.jpg 90w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">It is yet better if you have either a logic analyser or oscilloscope. A good digital multimeter (DMM) and a well-regulated DC power supply\/source are must haves. You can also use a cell phone charging power bank as a power source since Disco boards have USB ports.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Saleae-Logic-4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13311 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Saleae-Logic-4-580x447.jpg\" alt=\"Saleae Logic 4\" width=\"580\" height=\"447\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Saleae-Logic-4-580x447.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Saleae-Logic-4.jpg 600w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><!--nextpage--><\/p>\n<h2><span lang=\"EN-GB\">Software Tools<\/span><\/h2>\n<p style=\"text-align: justify\">Just like any other software developer, my choice of language for software development is C language. I don\u2019t want to spend time coding complex stuffs in assembly or other languages. STM8s are also C optimized micros. Apart from these reasons, I chose C language for the fact that STMicroelectronics has provided a <strong><em>Standard Peripheral Library (SPL)<\/em><\/strong> that is very easy to use. With SPL, it becomes totally unnecessary to program each peripheral register with meaningless numbers and maintain coding sequence. We will never need to access registers for any reason as everything is done under the hood of SPL. All sequences are dealt inside the SPL. All that we will ever need is the clear concept of each hardware block, their working principles, their capabilities and limitations.<\/p>\n<p style=\"text-align: justify\">We will need an <strong><em>Integrated Development Environment (IDE)<\/em><\/strong> and a C-language toolchain. The best stuffs you can get your hands on at zero costs are <strong><em>ST Visual Develop (STVD)<\/em><\/strong> IDE and<strong><em> Cosmic <\/em><\/strong>C compiler. Both are free but a rather difficult to use at first. STVD also packs with a programmer software tool called <strong><em>ST Visual Programmer (STVP)<\/em><\/strong>. We will need STVP to upload codes to target STM8 micros.<\/p>\n<p style=\"text-align: justify\">Cosmic used to be a paid tool just like your PC\u2019s antivirus software but at the time of writing this article, the Cosmic team has made it absolutely free for STM8 family. However, to use it you will need to register and acquire a license key via email. Usually this procedure of acquiring license and registration is maintained automatically by the software company\u2019s server but with Cosmic it is different story. You will need to wait for some guy at Cosmic end to respond to your license request. It may take a few minutes or even a day but still the best part is getting a full version compiler for nothing.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13334 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD1-580x314.png\" alt=\"STVD\" width=\"580\" height=\"314\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD1-580x314.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD1-1024x555.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD1.png 1916w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>You can get<br \/>\nSTVD from here: <a href=\"http:\/\/www.st.com\/en\/development-tools\/stvd-stm8.html\" target=\"_blank\">http:\/\/www.st.com\/en\/development-tools\/stvd-stm8.html<\/a> and<br \/>\nCosmic C compiler from here: <a href=\"http:\/\/www.cosmic-software.com\/download.php\" target=\"_blank\">http:\/\/www.cosmic-software.com\/download.php<\/a>.<\/p>\n<p>You need to register in order to download both software. For Cosmic you will also need to acquire a free license for it work. So just fill in some basic info about you.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13336 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-1-580x476.png\" alt=\"COSMIC 1\" width=\"580\" height=\"476\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-1-580x476.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-1.png 685w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Firstly, we will need to install STVD. Installation procedure is simple and same as typical software installation. Just click next, next and next. After that we will need to install Cosmic C compiler. Again, just next, next and next until the screen as shown below.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13337\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2-580x438.png\" alt=\"COSMIC 2\" width=\"580\" height=\"438\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2-580x438.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2.png 693w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">After installation, you\u2019ll prompted for licence. You must register your license unless you have already registered. If you have already registered, then you\u2019ll be asked if to overwrite registration. You should skip reregistering.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2b1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13346\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-2b1.png\" alt=\"COSMIC 2b\" width=\"518\" height=\"191\" \/><\/a><\/p>\n<p>For the first run, you\u2019ll get the following screen looking for a valid license.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13339\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-3.png\" alt=\"COSMIC 3\" width=\"417\" height=\"568\" \/><\/a><\/p>\n<p style=\"text-align: justify\">You must fill all the starred (*) points to complete the process of registration. Select <strong><em>\u201cWrite to File\u201d<\/em><\/strong> option and save the file as a text (.txt) file. The file name should be <strong><em>\u201cCM8_license.txt\u201d<\/em><\/strong>. Send this file to <a href=\"mailto:stm8_Free@cosmic.fr\">stm8_Free@cosmic.fr<\/a> with subject \u201c<strong><em>STM8FSE, STM32 32K License Request\u201d<\/em><\/strong>. Now you\u2019ll need to wait for the Cosmic team to respond to you. They\u2019ll send you an email back with an electronic key license. The file will have a name like <strong><em>\u201clicense.lic\u201d<\/em><\/strong> and the email will have some instructions.<\/p>\n<p>This was my emailed license.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Email.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13343\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Email.png\" alt=\"Email\" width=\"361\" height=\"508\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Once you get the license, you\u2019ll need to show the software its location and complete the licensing process as shown below. Save the license file in a secured location.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13340\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-4.png\" alt=\"COSMIC 4\" width=\"341\" height=\"280\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><del><\/del><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13341\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-5.png\" alt=\"COSMIC 5\" width=\"332\" height=\"279\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-6.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13342\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/COSMIC-6.png\" alt=\"COSMIC 6\" width=\"334\" height=\"289\" \/><\/a><\/p>\n<p style=\"text-align: justify\">At the end of this process, we can enjoy the compiler without any limitations.<\/p>\n<p style=\"text-align: justify\">I also recommend that you download Sublime Text (<a href=\"https:\/\/www.sublimetext.com\/\">https:\/\/www.sublimetext.com\/<\/a>) or Notepad++ (<a href=\"https:\/\/notepad-plus-plus.org\/\">https:\/\/notepad-plus-plus.org\/<\/a>) for viewing your code with ease. These are very cool software. This is not mandatory though.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13363\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code.png\" alt=\"Code\" width=\"502\" height=\"565\" \/><\/a><\/p>\n<p><!--nextpage--><\/p>\n<h2><span lang=\"EN-GB\">STM8CubeMX<\/span><\/h2>\n<p style=\"text-align: justify\">Should I or should I not feel fortunate was my question at the time of writing this article and that\u2019s because STM8CubeMX was released in late February 2017. Yes, that\u2019s the time when I was compiling all these STM8 stuffs together. Prior to that I was wondering about a software similar to STM32CubeMX but for STM8s. Back then, I could not find one and raw documentations were only helpers. Although it is still in its early stages of development and still not as robust as its STM32 cousin in terms of code generation capabilities and other areas, we can expect great innovations in the near future. It reminds me of the early days of STM32CubeMX. Not everyone expected it to overcome all the challenges in a very short period of time.\u00a0 At present, we can use STM8CubeMX for common info on STM8 chips like pin assignments\/mapping, basic technical specs like memory capacities, possible clock configurations, etc. I can just wonder the potential future integrations and bug fixes. Power consumption calculator is one such tool hopefully to be integrated. STM, most likely, has some serious big plans for it. Nevertheless, we must thank STM for this cool software.<\/p>\n<p style=\"text-align: left\">Visit <a href=\"http:\/\/www.st.com\/en\/development-tools\/stm8cubemx.html\">http:\/\/www.st.com\/en\/development-tools\/stm8cubemx.html<\/a> to download.<\/p>\n<p style=\"text-align: left\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13347\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8CubeMX-580x314.png\" alt=\"STM8CubeMX\" width=\"580\" height=\"314\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8CubeMX-580x314.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8CubeMX-1024x555.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8CubeMX.png 1918w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">I recommend using it only as reference for now. Don\u2019t make yourself dependent on it. There are still many bugs fixes that are yet to be addressed. One example is as in the above screenshot. Notice Timer 4 (TIM4) is missing although STM8S003 micros have this timer. I\u2019m pretty sure the software developers are working hard on such silly issues. For now, it is more like a promise of good tidings to come. This is why I haven\u2019t included it in the \u201cmust-have\u201d software list and wanted it to be discussed separately.<\/p>\n<p><!--nextpage--><\/p>\n<h2><span lang=\"EN-GB\">Preparing the Software Tools<\/span><\/h2>\n<p style=\"text-align: justify\">Firstly, we need three major documents before starting to program STM8 micros. These are as follows:<\/p>\n<ol style=\"text-align: justify\">\n<li>STM8 Reference Manual.<br \/>\n<a href=\"http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/reference_manual\/9a\/1b\/85\/07\/ca\/eb\/4f\/dd\/CD00190271.pdf\/files\/CD00190271.pdf\/jcr:content\/translations\/en.CD00190271.pdf\">http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/reference_manual\/9a\/1b\/85\/07\/ca\/eb\/4f\/dd\/CD00190271.pdf\/files\/CD00190271.pdf\/jcr:content\/translations\/en.CD00190271.pdf<\/a><\/li>\n<\/ol>\n<ol style=\"text-align: justify\" start=\"2\">\n<li>Datasheet of the MCU (<strong><em>STM8S003<\/em><\/strong>) that we\u2019ll be using.<br \/>\n<a href=\"http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/datasheet\/42\/5a\/27\/87\/ac\/5a\/44\/88\/DM00024550.pdf\/files\/DM00024550.pdf\/jcr:content\/translations\/en.DM00024550.pdf\">http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/datasheet\/42\/5a\/27\/87\/ac\/5a\/44\/88\/DM00024550.pdf\/files\/DM00024550.pdf\/jcr:content\/translations\/en.DM00024550.pdf<\/a><\/li>\n<li>STM8SVLDiscovery Board User Manual.<br \/>\n<a href=\"http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/user_manual\/c8\/37\/11\/ba\/b5\/e7\/4c\/ee\/DM00040810.pdf\/files\/DM00040810.pdf\/jcr:content\/translations\/en.DM00040810.pdf\">http:\/\/www.st.com\/content\/ccc\/resource\/technical\/document\/user_manual\/c8\/37\/11\/ba\/b5\/e7\/4c\/ee\/DM00040810.pdf\/files\/DM00040810.pdf\/jcr:content\/translations\/en.DM00040810.pdf<\/a><\/li>\n<\/ol>\n<p style=\"text-align: justify\">These docs will be needed everywhere during learning session. The reference manual states the use and purpose of all the hardware blocks in details. It includes register descriptions, naming conventions, modes of operation of all hardware, etc. However, it does not specify the specifications of a given STM8 micro and that\u2019s because it is a generalized literature for all STM8S and STM8AF micros. As we know even within a family of micros, one MCU differs from another in many aspects. Most commonly this variation comes in the form of memory capacities and I\/O pin counts. Sometimes electrical specs also vary and so to know the limits and general specs of our target MCUs we need to checkout their respective datasheets. Lastly the Discovery board user manual is most useful for the hardware schematics, pin assignments and layouts. If you are using some other board then I suggest that you acquire at least its schematic.<\/p>\n<p style=\"text-align: justify\">Now with Cosmic, STVD and STVP installed our software tool setup is almost ready. There are two approaches to STM8 programming. The first uses the traditional concepts of register-access-based coding, meaning you\u2019ll have to set up every register on your own. The second way utilizes a specialized method of coding by using standard libraries developed by STM that are both universal and platform independent, meaning your C code will be same for any compiler using these libraries. These libraries are called <strong><em>Standard Peripheral Libraries (SPL)<\/em><\/strong>. With these libraries, no one will ever need to get down to register-level access. The libraries are so coded that a coder will only have to know his\/her chips\u2019 hardware specs and some basics of these hardware. On the coding part, he\/she will only have to set properties and desired values. The SPL manages the rest. For instance, when setting up a UART, we will only need to set interrupts, IOs and UART properties like baud rate, parity, etc. All of these setups are done with meaningful numbers and texts.<\/p>\n<p style=\"text-align: justify\">The STMicroelectronics Standard Peripheral Libraries (SPL) for STM8 microcontrollers can be found here: <a href=\"http:\/\/www.st.com\/en\/embedded-software\/stsw-stm8069.html\">http:\/\/www.st.com\/en\/embedded-software\/stsw-stm8069.html<\/a>.<\/p>\n<p style=\"text-align: justify\">I wrote this article using SPL since it will be ridiculous to code STM8s using the old-fashioned way of configuring registers one-by-one manually. Thus, it is a mandatory download item. You should preserve and retain the downloaded SPL zip file fully intact. You may need it when things get messy.<\/p>\n<p style=\"text-align: justify\">Now make two folders and name them <strong><em>\u201cinc\u201d<\/em><\/strong> and <strong><em>\u201csrc\u201d<\/em><\/strong>. The <strong><em>\u201cinc\u201d<\/em><\/strong> folder will be filled with all the header files (<strong><em>\u201c.h\u201d<\/em><\/strong> extension files) from the extracted zip file. Similarly, the <strong><em>\u201csrc\u201d<\/em><\/strong> folder will be holding the source files (<strong><em>\u201c.c\u201d<\/em><\/strong> extension files). For ease of work, it is better to keep these folders secured just like the SPL zip file because every time when we will be making new projects the files in these folders will be needed. You can copy these files to your project folder or you can keep it centrally somewhere. I prefer the former method as doing so will not have any conflicting issue with other projects needing modifications. However, it will cost hard-drive space. This method is however less confusing and trouble-free for beginners. Extract all the files as shown below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Source-and-Header-Files.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13328\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Source-and-Header-Files.png\" alt=\"Source and Header Files\" width=\"265\" height=\"407\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Note that there are more header files than source files. This is because there are two extra header files \u2013 <strong><em>stm8s.h <\/em><\/strong>and<strong><em> stm8s_conf.h <\/em><\/strong>that define processor type and processor properties. To make things work, we will have to comment one line of the <strong><em>stm8s_conf.h<\/em><\/strong>. You will find a line at the bottom of this file written as:<\/p>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><strong><em>#define USE_FULL_ASSERT\u00a0\u00a0\u00a0 (1)<\/em><\/strong><\/span><\/pre>\n<p style=\"text-align: justify\">You need to comment or disable this line, otherwise the compiler will throw tons of error messages.\u00a0 Always check this at the start of a project. Surely, we don\u2019t want to assert our code.<\/p>\n<h2><span lang=\"EN-GB\">Creating a New Code Project<\/span><\/h2>\n<p>Assuming that STVD, STVP and Cosmic are properly installed, we will see how to create a new project.<\/p>\n<ul>\n<li>Firstly, run STVD.<\/li>\n<li>Select <strong><em>File &gt;&gt; New Workspace<\/em><\/strong>.<\/li>\n<\/ul>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/New-Workspace.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-13331 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/New-Workspace-580x314.png\" alt=\"New Workspace\" width=\"580\" height=\"314\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/New-Workspace-580x314.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/New-Workspace-1024x555.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/New-Workspace.png 1919w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<ul>\n<li>Select <strong><em>Create workspace and project<\/em><\/strong>.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Create-New-Workspace.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13323\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Create-New-Workspace.png\" alt=\"Create New Workspace\" width=\"349\" height=\"326\" \/><\/a><\/p>\n<ul>\n<li>Select workspace folder and workspace name.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Workspace-Title.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13330\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Workspace-Title.png\" alt=\"Workspace Title\" width=\"457\" height=\"348\" \/><\/a><\/p>\n<ul>\n<li style=\"text-align: justify\">Set project name and select toolchain <strong><em>STM8 Cosmic<\/em><\/strong>. You may need to set the path of your Cosmic compiler\u2019s installation location. In my case, it is:<br \/>\n<strong><em>C:\\Program Files (x86)\\COSMIC\\FSE_Compilers\\CXSTM8<\/em><\/strong><\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Project-Details.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13327\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Project-Details.png\" alt=\"Project Details\" width=\"455\" height=\"345\" \/><\/a><\/p>\n<ul>\n<li style=\"text-align: justify\">Type and select target chip part number. Last two or three digits and letters are enough for finding the correct micro.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Chip-Selection.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13320\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Chip-Selection.png\" alt=\"Chip Selection\" width=\"339\" height=\"369\" \/><\/a><\/p>\n<ul>\n<li>Now add the source and header files from the previously mentioned SPL folder.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13324\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion.png\" alt=\"File Inclusion\" width=\"379\" height=\"544\" \/><\/a><\/p>\n<ul>\n<li>After file inclusions, the workspace tab changes as shown below:<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Files.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13325\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Files-290x650.png\" alt=\"Files\" width=\"290\" height=\"650\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Files-290x650.png 290w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Files.png 327w\" sizes=\"auto, (max-width: 290px) 100vw, 290px\" \/><\/a><\/p>\n<ul>\n<li style=\"text-align: justify\">Locate and open <strong><em>c <\/em><\/strong>file from the source tab, and then type <strong><em>#include &#8220;stm8s.h&#8221;<\/em><\/strong> at the top as shown below:<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/main-file.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13326\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/main-file.png\" alt=\"main file\" width=\"530\" height=\"584\" \/><\/a><\/p>\n<ul>\n<li style=\"text-align: justify\">You\u2019ll have to edit the <strong><em>h <\/em><\/strong>header file and uncomment the chip number you are going to use as shown below:<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S.h-Chip-Identification.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13329\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S.h-Chip-Identification-580x369.png\" alt=\"STM8S.h Chip Identification\" width=\"580\" height=\"369\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S.h-Chip-Identification-580x369.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STM8S.h-Chip-Identification.png 955w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<ul>\n<li style=\"text-align: justify\">Compile the code once using the key combination <strong><em>CTRL+F7 <\/em><\/strong>or by pressing the compile button. If everything is okay, there should be no error or warning message. The reason for this blank compilation is to use the compiler\u2019s powerful code assistant feature. With this feature, we can predict or complete a piece of code line by only writing the first few letters and then pressing <strong><em>CTRL + SPACE<\/em><\/strong> keys simultaneously.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code-Assistant.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13321\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code-Assistant-580x269.png\" alt=\"Code Assistant\" width=\"580\" height=\"269\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code-Assistant-580x269.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code-Assistant-1024x475.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Code-Assistant.png 1277w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">During compilation, you may get tons of errors for hardware files that are not available in your target STM8S micro. For instance, CAN hardware is not available in STM8S003K3 and so if you have added CAN source and header files you will get an error for that. Once identified by the error messages, the corresponding header and source files for that particular hardware must be removed.<\/p>\n<p style=\"text-align: justify\">A wiser approach to avoid this issue is to check device datasheet for available hardware in it. The contents section of datasheet shows this as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Hardware.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13956 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Hardware.png\" alt=\"Hardware\" width=\"444\" height=\"460\" \/><\/a><\/p>\n<p style=\"text-align: justify\">STM8CubeMX can also be used for this purpose but some hardware peripherals which do not have any input-output dependency are not shown in it as previously discussed.<\/p>\n<p style=\"text-align: center\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Hardware-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13955\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Hardware-2.png\" alt=\"Hardware 2\" width=\"264\" height=\"290\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Similarly, one more caution must be observed. Unless your code is using any interrupt, interrupt source and header files (<strong><em>stm8s_it.h <\/em><\/strong>and <strong><em>stm8s_it.c<\/em><\/strong>) must be excluded. Sometimes it is better to add only those files that you will need to complete a project. For example, if your project is just using GPIOs, it is better to add GPIO files only along with <strong><em>stm8s.h <\/em><\/strong>and <strong><em>stm8s_conf.h<\/em><\/strong>. However, I recommend this technique only after you have mastered STM8 coding well because in most cases you will need multiple hardware which have dependencies on each other. As an example, when using SPI, you\u2019ll need both GPIO and SPI modules. If you understand these dependencies, it is okay to select files as per need. You can, then, comment out unnecessary hardware module files specified in the <strong><em>stm8s.h<\/em><\/strong> header file and get a faster compilation and build process. After compilation, you should always build\/rebuild your project by hitting the <strong><em>Build<\/em><\/strong> or <strong><em>Rebuild<\/em><\/strong> button. This will generate the final <strong><em>s19<\/em><\/strong> output file in either <strong><em>Debug<\/em><\/strong> or <strong><em>Release<\/em><\/strong> folder according to the generation mode selected. If things are in order, there should be no error or warning message.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Coding-Final.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13322\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Coding-Final-580x313.png\" alt=\"Coding Final\" width=\"580\" height=\"313\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Coding-Final-580x313.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Coding-Final-1024x552.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Coding-Final.png 1353w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Lastly, I have not found any useful simulation software like Proteus VSM or Electronic Workbench that support STM8 family. Thus, we have to debug our code in real-life with real hardware. It may sound difficult but actually it is not so. We can, however, use such software to make models of STM8 micros and make our PCBs. I don\u2019t like simulations as they are not always accurate and real-world type.<\/p>\n<p style=\"text-align: justify\">One more advice I would like to give to the readers. Please read the SPL help file. It is located in the SPL zip file under the name <strong><em>stm8s-a_stdperiph_lib_um.chm<\/em><\/strong>. It explains each function, definition, data structure, all internal hardware modules and how to use them properly. This is a very important document and your best friend in coding STM8 micros. Apart from this document the reference manual is equally important as it details the capabilities of all internal hardware. I won\u2019t be detailing the internal hardware much as these docs will be doing so.<\/p>\n<p style=\"text-align: justify\">Check this video out for details:<br \/>\n<iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/sqCuSVjevrY?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2><span lang=\"EN-GB\">Uploading Code<\/span><\/h2>\n<p style=\"text-align: justify\">Codes generated by Cosmic C compiler have <strong><em>s19<\/em><\/strong> file extensions. It is similar to typical hex file format, containing user code as hex values. Well since we don\u2019t need to modify finally generated output files, it doesn\u2019t really matter in which format it is. All we will need is to upload them to our target MCUs. We can do it in two ways \u2013 either by using STVP or STVD.<\/p>\n<p style=\"text-align: justify\">Firstly, let\u2019s check the method with STVP. Run STVP software. For the first time the following window will appear. From here we have to select ST-Link programmer, SWIM interface and our target chip.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Selecting-Programmer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13350\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Selecting-Programmer-580x505.png\" alt=\"Selecting Programmer\" width=\"580\" height=\"505\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Selecting-Programmer-580x505.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Selecting-Programmer.png 647w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>STVP interface looks like any other programmer interface as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVP.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13353\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVP-580x310.png\" alt=\"STVP\" width=\"580\" height=\"310\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVP-580x310.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVP-1024x547.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVP.png 1364w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Notice the mid tabs at the bottom of the hex values. From here we can see the hex values for program memory, data\/EEPROM memory and configuration settings. The configuration setting bits are intended for setting some special hardware configurations or extending features of the target as well as setting memory readout protection.<a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-3.png\"><br \/>\n<\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Configuration-Bits1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13361\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Configuration-Bits1-580x310.png\" alt=\"Configuration Bits\" width=\"580\" height=\"310\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Configuration-Bits1-580x310.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Configuration-Bits1-1024x548.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Configuration-Bits1.png 1364w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Try not to mess with security or protection bit at first or during tests as it will lock your chip up, rendering it useless. You won\u2019t simply be able to write it again until you unlock it. Unless needed, we won\u2019t be changing any default configuration bit. One thing to note is the fact that upon new compilation and build, the newly generated output file is automatically reloaded. The rest of the stuffs like loading or saving a s19 file, reading, writing and others are as simple as like with other programmers. I won\u2019t be explaining these steps as I assume that readers of this article already know how to do all these from their previous experiences with other MCUs.<\/p>\n<p style=\"text-align: justify\">Now we will explore how we can upload a code to our target using STVD. After compiling and building a project successfully without any error, the compiler will generate a s19 output file either in <strong><em>Debug<\/em><\/strong> or <strong><em>Release<\/em><\/strong> folder depending on which mode of compilation selected. By default, <strong><em>Debug<\/em><\/strong> mode is selected unless the coder changed it and so our desired s19 file will be in this folder. First, we need to open the programmer interface. We can do that either by clicking the icon as shown below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Icon.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13356\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Icon.png\" alt=\"Icon\" width=\"142\" height=\"43\" \/><\/a><\/p>\n<p>or we can go to <strong><em>Tools &gt;&gt; Programmer<\/em><\/strong>.<\/p>\n<p>We will get a new window as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13357\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface.png\" alt=\"STVD Programmer Interface\" width=\"527\" height=\"406\" \/><\/a><\/p>\n<p style=\"text-align: justify\">As the name of the new window suggests, it is a light-weight programmer interface but good enough for our purpose. Notice that there are many options and four tabs. Here again we need to select programmer, programming interface (SWIM) and erase\/blank check options. Then we go to the next tab to select files for EEPROM (if any) and Program (also Flash\/Code) memory as shown below. You can add\/remove files just as usually.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13358\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-2.png\" alt=\"STVD Programmer Interface 2\" width=\"527\" height=\"407\" \/><\/a><\/p>\n<p>Next, we set configuration bits if needed from the tab as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13355\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-3.png\" alt=\"STVD Programmer Interface 3\" width=\"525\" height=\"409\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Finally, we are ready to upload code. Just hit the start button and wait for the process to finish.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13362\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/STVD-Programmer-Interface-4.png\" alt=\"STVD Programmer Interface 4\" width=\"526\" height=\"403\" \/><\/a><\/p>\n<p>Every time a code is programmed, it is verified automatically.<\/p>\n<p><!--nextpage--><\/p>\n<h2>General Purpose Input Output (GPIO)<\/h2>\n<p style=\"text-align: justify\">The very first <em>\u201cHello World\u201d<\/em> project that we do with every new embedded device is a simple LED blinking program. Here we do the same. We will be basically testing both input and output function by making a variable flash rate blinking LED. Check the schematic of the Disco board. Check the pins with which the on-board LED and the push button are connected.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Disco-Schematic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13364\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Disco-Schematic-580x485.png\" alt=\"Disco Schematic\" width=\"580\" height=\"485\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Disco-Schematic-580x485.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Disco-Schematic.png 657w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">You can also use the STM8CubeMX in board selector mode for this too.<\/p>\n<p style=\"text-align: justify\">Shown below is the internal block diagram of GPIO pins:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13365\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic.png\" alt=\"Schematic\" width=\"535\" height=\"513\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Because each I\/O is independently configurable and have many options associated with it, its block looks complex at first sight. Check the various options every I\/O possess:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functionality.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13366\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functionality.png\" alt=\"Functionality\" width=\"544\" height=\"370\" \/><\/a><\/p>\n<p>Shown below are the SPL functions associated with the GPIO module.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13367\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functions-580x359.png\" alt=\"Functions\" width=\"580\" height=\"359\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functions-580x359.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Functions.png 808w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Observe the code below. This is the power of the ST\u2019s SPL. The code is written with no traditional register access. Everything here has a meaningful nomenclature, just like regular naming\/words of the reference manual\/comments. There shouldn\u2019t be any issue understanding the code. The code is almost Arduino-like. Here we are polling an input pin\u2019s state to alter the blink rate of a LED.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13368\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\" alt=\"CubeMX\" width=\"415\" height=\"537\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main (void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0bool i = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0for(;;) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i ^= 1;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch(i)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 0:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 1:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}\r\n<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>The following lines deinitialize the GPIOs we used. Every time you reconfigure or setup a hardware peripheral for the first time you must deinitialize it before using it. Though it is not mandatory, it will remove any chance of wrong\/conflicting configurations.<\/p>\n<pre><span style=\"color: #0000ff\"><em>\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<p>After deinitialization, we are good to go for initializing or setting up the GPIOs. Inputs can be with or without internal pull-up resistors. Outputs can be either push-pull totem-pole or open drain types. Each pin can be individually configured and does not have any dependency on another. The following codes set GPIO PB7 as a floating input with no interrupt capability and GPIO PD0 as a fast push-pull output. PB7 is set up as a floating input rather than an internally pulled-up input because the button on the Disco board is already pulled up externally.<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);<\/em><\/span><\/pre>\n<p>The remaining part of the code in the main loop is just polling the button\u2019s state and<\/p>\n<pre><span style=\"color: #0000ff\"><em>for(;;) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i ^= 1;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch(i)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 0:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 1:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221924.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13390\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221924-580x237.jpg\" alt=\"IMG_20170402_221924\" width=\"580\" height=\"237\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221924-580x237.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221924.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221928.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13391\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221928-580x237.jpg\" alt=\"IMG_20170402_221928\" width=\"580\" height=\"237\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221928-580x237.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/IMG_20170402_221928.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/GPIO.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13369\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/GPIO-580x237.gif\" alt=\"GPIO\" width=\"580\" height=\"237\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/Rr1vpfoze4w?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Clock System (CLK)<\/h2>\n<p style=\"text-align: justify\">The internal network of STM8 clock system allows us to tune up operating speeds of peripherals and CPU according to our needs. Software delays and power consumption depend on how the clock system is set.<\/p>\n<p style=\"text-align: justify\">In STM8 micros, there are three main clock sources \u2013 <strong><em>High Speed Internal Clock (HSI)<\/em><\/strong>, <strong><em>High Speed External Clock (HSE) <\/em><\/strong>and<strong><em> Low Speed Internal Clock (LSI)<\/em><\/strong>. The HSI has an oscillating frequency of 16MHz and is an internal RC oscillator with good precision \u2013 about 1% tolerant over a wide temperature range. HSE can be an external clock circuitry, temperature-compensated crystal oscillator (TCXO) or ordinary crystal resonator. It accepts all frequencies from 1MHz to 24MHz. Lastly, LSI clock is also an independent internal RC oscillator-based clock source that is mainly intended for idle or low power operating modes and the independent watchdog timer (IWDG). It has a fixed factory calibrated operating frequency of 128kHz and is not as accurate as HSI or HSE. There are also clock dividers\/prescalers at various points to scale clocks as per requirement. Mainly two prescalers are what we need \u2013 the HSI prescaler and the CPU divider. Peripherals are directly feed by the main clock source. Additionally, there is a clock output pin (CCO) that outputs a given clock frequency. It can be used to clock another micro, generate clock for other devices like logic ICs. It can also be used as a free oscillator or perform clock performance tests. There\u2019s fail-safe clock security that makes HSI backup of HSE. Should HSE fail, HSI takes over automatically. Check the internal block diagram below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Internal-Block-Diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13370\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Internal-Block-Diagram.png\" alt=\"Internal Block Diagram\" width=\"416\" height=\"488\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13371\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX1-580x422.png\" alt=\"CubeMX1\" width=\"580\" height=\"422\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX1-580x422.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX1.png 837w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<h4 style=\"text-align: justify\"><u><br \/>\n<\/u>Hardware Connection<\/h4>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13372\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX2.png\" alt=\"CubeMX2\" width=\"369\" height=\"525\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">The code example below demonstrates how to run the CPU at 2 MHz clock using HSI and extract 500 kHz clock output from CCO pin using CCO output selection. HSE is divided by 8, i.e. 16 MHz divided by 8 equals 2 MHz. This 2 MHz is the master clock source and further divided four times to get 500 kHz.<\/p>\n<p style=\"text-align: justify\">Note CCO pin is only available in some pins. For example, in STM8S003K3 this pin is either PD0 pin or PC4. We will need to override the default function of PD0 pin to favour for CCO output. To do so, we will need to change Alternate Function (<strong><em>AFR5<\/em><\/strong>) configuration bit during code upload.<\/p>\n<pre><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LED_pin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_PIN_0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LED_port\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIOD<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_WriteLow(LED_port, LED_pin);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>  clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>  CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_CCOConfig(CLK_OUTPUT_CPU);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0CLK_CCOCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_CCORDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0GPIO_DeInit(LED_port);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0GPIO_Init(LED_port, LED_pin, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>The full explanation of this code is given in the last segment of this article. The only thing I\u2019ll describe here is this part:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_CCOConfig(CLK_OUTPUT_CPU);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_CCOCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>while(CLK_GetFlagStatus(CLK_FLAG_CCORDY) == FALSE);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">These lines select the clock source that the CCO pin will output, enable the CCO module and wait for it to stabilize. Here I selected the CCO to output CPU clock.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cco.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13373\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cco-580x309.png\" alt=\"cco\" width=\"580\" height=\"309\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cco-580x309.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cco-1024x546.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cco.png 1366w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/IeLUc_s3jBE?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>External Interrupt (EXTI)<\/h2>\n<p style=\"text-align: justify\">External interrupt is an additional feature of GPIOs in input mode. It makes a micro to respond instantly to changes done on it GPIO input pin(s) by an external events\/triggers, skipping other tasks. External interrupts are useful in many scenarios. For instance, an emergency button. Consider the case of a treadmill. You are running at a speed and suddenly you get an ache in one of your ankles. You\u2019ll surely want to stop running immediately. Rather decreasing speed in small steps, you can hit the emergency button to quickly stop the treadmill. The emergency button will interrupt all other processes and immediately instruct the treadmill\u2019s CPU to decrease speed faster than otherwise possible. Thus, it has high priority over other processes.<\/p>\n<p style=\"text-align: justify\">In most 8-bit micros, there are few external interrupt pins and very limited options are available for them but that\u2019s not the case with STM\u2019s micros. In STM8s, almost all GPIO pins have independent external interrupt capability with input Schmitt triggers. Additionally, there\u2019s interrupt controller to set interrupt priority.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13375\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic1.png\" alt=\"Schematic\" width=\"535\" height=\"513\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13368\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\" alt=\"CubeMX\" width=\"415\" height=\"537\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">We will do the same variable flash rate LED blinking example as in the GPIO example but this time with the DISCO board\u2019s button in external interrupt mode. The code here needs special attention as now we will see how interrupts are configured and coded. This code is way different than anything I saw before. I\u2019m saying so because you\u2019ll need to follow certain steps unlike other compilers. In other compilers, all we do is create the interrupt function and tell the compiler the interrupt vector address. Same here too but too many steps involved.<\/p>\n<p style=\"text-align: justify\">Now check the interrupt vector table of STM8S003 below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Vector-Table.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13376\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Vector-Table-542x650.png\" alt=\"Vector Table\" width=\"542\" height=\"650\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Vector-Table-542x650.png 542w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Vector-Table.png 710w\" sizes=\"auto, (max-width: 542px) 100vw, 542px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">You\u2019ll find this table not in the reference manual but in the device\u2019s datasheet. This table varies with devices and so be sure of correct datasheet. The DISCO board\u2019s button is connected to PB7 and so clearly, we will need <strong><em>IRQ4<\/em><\/strong>, i.e. EXTI1 or PORTB external interrupts. All external interrupts on GPIOB pin are masked in this vector address.<\/p>\n<p style=\"text-align: justify\">Please note that codes that use peripheral interrupts need <strong><em>stm8s_it.h<\/em><\/strong> and <strong><em>stm8s_it.c<\/em><\/strong> files. Therefore, add them if you are to use interrupts.<\/p>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>bool state = FALSE;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void EXTI_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0EXTI_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0do<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(state == TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(100);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0}while (TRUE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_PU_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void EXTI_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0ITC_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0ITC_SetSoftwarePriority(ITC_IRQ_PORTB, ITC_PRIORITYLEVEL_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0EXTI_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_ONLY);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0EXTI_SetTLISensitivity(EXTI_TLISENSITIVITY_FALL_ONLY);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8_interrupt_vector.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>\/*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BASIC INTERRUPT VECTOR TABLE FOR STM8 devices<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Copyright (c) 2007 STMicroelectronics<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0*\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>#include \"stm8s_it.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>typedef void @far (*interrupt_handler_t)(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>struct interrupt_vector \r\n{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0unsigned char interrupt_instruction;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0interrupt_handler_t interrupt_handler;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/@far @interrupt void NonHandledInterrupt (void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* in order to detect unexpected events during development, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 it is recommended to set a breakpoint on the following instruction<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern void _stext();\u00a0\u00a0\u00a0\u00a0 \/* startup routine *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>struct interrupt_vector const _vectab[] = {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, (interrupt_handler_t)_stext}, \/* reset *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* trap\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq0\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq1\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq2\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq3\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, (interrupt_handler_t)EXTI1_IRQHandler}, \/* irq4\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq5\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq6\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq7\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq8\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq9\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq10 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq11 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq12 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq13 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq14 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq15 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq16 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq17 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq18 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq19 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq20 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq21 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq22 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq23 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq24 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq25 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq26 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq27 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq28 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq29 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Now check the top parts of the <strong><em>stm8s_it.h<\/em><\/strong> and <strong><em>stm8s_it.c<\/em><\/strong> files respectively.<\/p>\n<p><strong><em><u>stm8s_it.h<\/u><\/em><\/strong><\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/stm8s_it.h_file.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13379\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/stm8s_it.h_file.png\" alt=\"stm8s_it.h_file\" width=\"479\" height=\"269\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8s_it.c<\/u><\/em><\/strong><\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/stm8s_it.c_file.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13380\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/stm8s_it.c_file.png\" alt=\"stm8s_it.c_file\" width=\"453\" height=\"198\" \/><\/a><\/p>\n<p>These must be coded.<\/p>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">Most part of the code is same as previous codes and so I won\u2019t be going through them again. However, there\u2019s something new:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void EXTI_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ITC_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ITC_SetSoftwarePriority(ITC_IRQ_PORTB, ITC_PRIORITYLEVEL_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0EXTI_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_ONLY);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0EXTI_SetTLISensitivity(EXTI_TLISENSITIVITY_FALL_ONLY);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">This function is where we are setting up the external interrupt. The first two lines deinitiate the interrupt controller and set priority while initiating it. It is not mandatory unless you want to set interrupt priority. Then we configure the external interrupt on PORTB pins. We also set the edge that will invoke an interrupt. Finally, we enable global interrupt. There goes the <strong><em>main.c<\/em><\/strong> file<\/p>\n<p style=\"text-align: justify\">Now it\u2019s time to explain the <strong><em>stm8_interrupt_vector.c<\/em><\/strong> file. The top part of this file must include this line <em>#include &#8220;stm8s_it.h&#8221;<\/em>. It must also have the following section commented out:<\/p>\n<pre><span style=\"color: #0000ff\"><em>\/\/@far @interrupt void NonHandledInterrupt (void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* in order to detect unexpected events during development, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 it is recommended to set a breakpoint on the following instruction<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">We need to let our compiler know the name of the function that it should call when a particular interrupt is triggered. There are two parts for that. Firstly, the interrupt vector address and secondly the name of the function. This is reason for this line:<\/p>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)EXTI1_IRQHandler}, \/* irq4\u00a0 *\/<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Lastly, the <strong><em>stm8s_it.h<\/em><\/strong> and <strong><em>stm8s_it.c<\/em><\/strong> files contain the prototype and the function that will execute the interrupt service routine (ISR). In our case, the ISR will change the logic state of the Boolean variable<strong><em> state<\/em><\/strong>. This will alter that flashing rate in the main loop.<\/p>\n<h4>Demo<\/h4>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/P6qdmWgH-Ls?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Beeper (BEEP)<\/h2>\n<p style=\"text-align: justify\">The beeper hardware is a sound generation unit. This is a hardware not found in other micros and is useful in scenarios where we need an audible output. An alarm is a good example. The beeper unit uses LSI to generate 1kHz, 2kHz and 4kHz square wave outputs that can be directly feed to a small piezo tweeter (not buzzer). In most STM8 micros, the beeper module\u2019s I\/O pin (PD4) is not accessible unless alternate function configuration bit is altered during code upload. However, there are few exceptional chips like the STM8S003 in which we don\u2019t need to change any configuration bit at all. The beeper module has dependencies with the Auto-Wake-Up (AWU) module.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13381\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic2.png\" alt=\"Schematic\" width=\"441\" height=\"611\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void beeper_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 beeper_setup();\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_WriteLow(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BEEP_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_WriteHigh(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BEEP_Cmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 };<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_LSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_OD_LOW_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void beeper_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 BEEP_DeInit(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 BEEP_LSICalibrationConfig(128000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 BEEP_Init(BEEP_FREQUENCY_2KHZ);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">As stated earlier beeper module is dependent on the AWU module and so we need to enable this module\u2019s peripheral clock:<\/p>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, ENABLE);<\/em><\/span><\/pre>\n<p>We need to set the beeper port pin as an output pin:<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<p>Configuring the beeper is straight. Just like other peripherals, we deinitialize it first and set both LSI and beep frequency. Optionally we can calibrate the LSI.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void beeper_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0\u00a0BEEP_DeInit(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 BEEP_LSICalibrationConfig(128000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 BEEP_Init(BEEP_FREQUENCY_2KHZ);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>To activate\/deactivate the beeper we need to use the following instructions:<\/p>\n<pre><span style=\"color: #0000ff\"><em>BEEP_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>BEEP_Cmd(DISABLE);<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Beeper.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13382\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Beeper-580x362.jpg\" alt=\"Beeper\" width=\"580\" height=\"362\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Beeper-580x362.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Beeper.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/LDPtULsJao8?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Alphanumeric LCD<\/h2>\n<p style=\"text-align: justify\">Alphanumeric liquid crystal displays are the most common and basic form of displays after seven segments and LED displays. They are useful for projecting multiple data quickly in ways that are otherwise difficult with other kinds of displays.<\/p>\n<p style=\"text-align: justify\">To interface a LCD with a STM8 micro, we need LCD library. The STM8 SPL does not have a library for such displays and we need to code it on our own. Interfacing a LCDs are not difficult tasks as no special hardware is required to drive LCDs other than GPIOs. However, there are some tasks needed in the software end. We need to include the library files. The process of library inclusion is discussed in the later part of this article as it needs some special attentions. The example I\u2019m sharing here uses 6 GPIO pins from GPIOC. The read-write (R\/W) pin of the LCD is connected to ground. The layout is as shown below.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13383\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Schematic3.png\" alt=\"Schematic\" width=\"473\" height=\"623\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<p><strong><em><u>lcd.h<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\" <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_PORT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIOD<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_RS\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_2\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_EN\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_3\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_DB4 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_DB5 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_5<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_DB6 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_6 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define LCD_DB7 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_7 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define clear_display\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x01\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n<\/em><\/span><span style=\"color: #0000ff\"><em>#define goto_home\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x02\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>#define cursor_direction_inc\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x04 | 0x02)\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>#define cursor_direction_dec\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x04 | 0x00)\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>#define display_shift\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x04 | 0x01) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define display_no_shift\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x04 | 0x00)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define display_on\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x04)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define display_off\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x02) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define cursor_on\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x02)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define cursor_off\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x00)\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define blink_on\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x01)\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define blink_off\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x08 | 0x00)\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _8_pin_interface\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x10)\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _4_pin_interface\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x00)\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _2_row_display\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x08) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _1_row_display\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x00)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _5x10_dots\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x40)\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define _5x7_dots\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(0x20 | 0x00)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DAT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define CMD\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_GPIO_init(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_init(void);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_send(unsigned char value, unsigned char mode);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_4bit_send(unsigned char lcd_data);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_putstr(char *lcd_string);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_putchar(char char_data);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_clear_home(void);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_goto(unsigned char\u00a0 x_pos, unsigned char\u00a0 y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void toggle_EN_pin(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void toggle_io(unsigned char lcd_data, unsigned char bit_pos, unsigned char pin_num);<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>lcd.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"lcd.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_GPIO_init(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_RS, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_EN, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_DB4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_DB5, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_DB6, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(LCD_PORT, LCD_DB7, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 delay_ms(10);\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_init(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_GPIO_init();\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_RS);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB7);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB6);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB5);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB4); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB7);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB6);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB5);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB4);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB7);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB6);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB5);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB4);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB7);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB6);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_DB5);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, LCD_DB4);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send((_4_pin_interface | _2_row_display | _5x7_dots), CMD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send((display_on | cursor_off | blink_off), CMD); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send(clear_display, CMD);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send((cursor_direction_inc | display_no_shift), CMD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_send(unsigned char value, unsigned char mode)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 switch(mode)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case DAT:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(LCD_PORT, LCD_RS);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case CMD:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteLow(LCD_PORT, LCD_RS);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0LCD_4bit_send(value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>} \u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_4bit_send(unsigned char lcd_data)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 7, LCD_DB7);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 6, LCD_DB6);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 5, LCD_DB5);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 4, LCD_DB4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 3, LCD_DB7);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 2, LCD_DB6);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 1, LCD_DB5);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_io(lcd_data, 0, LCD_DB4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 toggle_EN_pin();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_putstr(char *lcd_string)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 do<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_send(*lcd_string++, DAT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 }while(*lcd_string != '\\0');<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_putchar(char char_data)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send(char_data, DAT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_clear_home(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send(clear_display, CMD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_send(goto_home, CMD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void LCD_goto(unsigned char\u00a0 x_pos, unsigned char\u00a0 y_pos)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 if(y_pos == 0)\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_send((0x80 | x_pos), CMD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 else <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_send((0x80 | 0x40 | x_pos), CMD); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void toggle_EN_pin(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, LCD_EN);\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 delay_ms(2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT,LCD_EN);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void toggle_io(unsigned char lcd_data, unsigned char bit_pos, unsigned char pin_num)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 bool temp = FALSE;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 temp = (0x01 &amp; (lcd_data &gt;&gt; bit_pos));<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 switch(temp)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case TRUE:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_WriteHigh(LCD_PORT, pin_num);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 default:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_WriteLow(LCD_PORT, pin_num);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"lcd.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 const char txt1[] = {\"MICROARENA\"}; <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 const char txt2[] = {\"SShahryiar\"}; <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 const char txt3[] = {\"STM8S003K\"};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 const char txt4[] = {\"Discovery\"};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 unsigned char s = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_init();\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_clear_home(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_goto(3, 0);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_putstr(txt1); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_goto(3, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_putstr(txt2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 delay_ms(4000);\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_clear_home();\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 for(s = 0; s &lt; 9; s++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_goto((3 + s), 0);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_putchar(txt3[s]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(90);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 for(s = 0; s &lt; 9; s++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LCD_goto((3 + s), 1);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(txt4[s]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(90);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 }\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while (TRUE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_DeInit();\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_DeInit(LCD_PORT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">There\u2019s little to explain this code as it involves GPIOs only. The codes for the LCD are coded using all available info on its datasheet, just initialization and working principle. One thing to note, however, is the CPU clock speed. If the CPU clock is too fast, LCDs may not work. This is because most LCDs have a maximum working frequency of 250kHz. It is best to keep this frequency below 200 kHz.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13384\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-1-580x377.jpg\" alt=\"LCD (1)\" width=\"580\" height=\"377\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-1-580x377.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-1.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13385\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-2-580x377.jpg\" alt=\"LCD (2)\" width=\"580\" height=\"377\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-2-580x377.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-2.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/TJg2Tuu4QaQ?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p><!--nextpage--><\/p>\n<h2 style=\"text-align: justify\">Analog-to-Digital Converter (ADC)<\/h2>\n<p style=\"text-align: justify\">ADC is a very important peripheral in any modern-day microcontroller. It is used to read analogue outputs from sensors, sense voltage levels and so on. For example, we can use an ADC to read a LM35 temperature sensor. The voltage output from the sensor is proportional to temperature and so we can use the voltage info to back-calculate temperature. STM8S003K3 has four ADC channels associated with one ADC block. Other STM8 micros have more ADC channels and ADC blocks. The ADC of STM8 micros is just as same as the ADCs of other micros. There are a few additional features. Shown below is the block diagram of the STM8\u2019s ADC peripheral:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13386\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram-580x520.png\" alt=\"Block Diagram\" width=\"580\" height=\"520\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram-580x520.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram.png 618w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>A few things must be noted before using the ADC. These enhance performance significantly:<\/p>\n<ul>\n<li>Input impedance should be less than 10k\u2126.<\/li>\n<li>It is better to keep ADC clock within or less than 4MHz.<\/li>\n<li>Schmitt triggers must be disabled.<\/li>\n<li>Opamp-based input buffer and filter circuits are preferred if possible.<\/li>\n<li>If the ADC has reference source pins, they should be connected to a precision reference source like LM336. It is recommended to use a good LDO regulator chip otherwise.<\/li>\n<li>Unused ADC pins should not be configured or disabled. This will reduce power consumption.<\/li>\n<li>Rather taking single samples, ADC readings should be sampled at fixed regular intervals and averaged to get rid of minute fluctuations in readings.<\/li>\n<li>Right-justified data alignment should be used as it is most convenient to use.<\/li>\n<li>PCB\/wire tracks leading to ADC channels must be short to reduce interference effects.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC_CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13387\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC_CubeMX.png\" alt=\"ADC_CubeMX\" width=\"432\" height=\"559\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void ADC1_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main()<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0unsigned int A0 = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_init();\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_clear_home(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto(0, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putstr(\"STM8 ADC\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto(0, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putstr(\"A0\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_StartConversion();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0A0 = ADC1_GetConversionValue();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ClearFlag(ADC1_FLAG_EOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lcd_print(4, 1, A0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(90);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void ADC1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_DeInit();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_CHANNEL_0,<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_PRESSEL_FCPU_D18, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_EXTTRIG_GPIO, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ALIGN_RIGHT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_SCHMITTTRIG_CHANNEL0, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0char chr = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0chr = ((value \/ 1000) + 0x30);\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto(x_pos, y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0chr = (((value \/ 100) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto((x_pos + 1), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0chr = (((value \/ 10) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto((x_pos + 2), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0chr = ((value % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto((x_pos + 3), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>First, we need to enable the peripheral clock of the ADC module:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);<\/em><\/span><\/pre>\n<p>Secondly, we have to set out ADC pin as a floating GPIO with no interrupt capability:<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<p>ADC setup needs a few info regarding the desired ADC channel:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void ADC1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_DeInit();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_CHANNEL_0,<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_PRESSEL_FCPU_D18, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_EXTTRIG_GPIO, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ALIGN_RIGHT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_SCHMITTTRIG_CHANNEL0, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0ADC1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">The second line of the above function states that we are going to use ADC channel 0 (PB0) with no Schmitt trigger. We are also not going to use external triggers from timer\/GPIO modules. Since the master clock is running at 8MHz, the ADC prescaler divides the master\/peripheral clock to get a sampling frequency of 444 kHz. We are also going to use continuous conversion mode because we want to continually read the ADC input and don\u2019t want to measure it in certain intervals. Lastly right-justified data alignment is used as it is easy to read from such.<\/p>\n<p style=\"text-align: justify\">In the main loop, we need to start ADC conversion and wait for the conversion to complete. We are not using interrupt methods and so we need to poll if ADC conversion has completed. At the end of conversion, we can read the ADC and clear ADC End of Conversion (EOC) flag.<\/p>\n<pre><span style=\"color: #0000ff\"><em>ADC1_StartConversion();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>A0 = ADC1_GetConversionValue();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>ADC1_ClearFlag(ADC1_FLAG_EOC);<\/em><\/span><\/pre>\n<p>The rest of the code is about printing the ADC data on a LCD.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13389\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC-580x534.jpg\" alt=\"ADC\" width=\"580\" height=\"534\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC-580x534.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/ADC.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/rx68zPDEZUU?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<p>&nbsp;<\/p>\n<h2>Analog Watchdog (AWD)<\/h2>\n<p style=\"text-align: justify\">The AWD is one additional feature that most microcontrollers in the market do not have. AWD is more like a comparator but with the exception that we can set both the upper and lower limits of this comparator as per our requirement unlike fixed levels in other micros. The region between the upper and lower limits is called guarded zone. Beyond the boundaries of the guarded zone, the AWD unit kicks off.<\/p>\n<p style=\"text-align: justify\">The AWD unit is very useful in situations where we need to monitor the output of a sensor for example and take quick actions. For instance, consider a temperature controller. We would want the controller to turn on a heater should temperature fall below some level and turn it off when temperature rises to some high value without complex calculations and constant monitoring in our application firmware. In other microcontrollers, we would have accomplished this simple task using conditional <strong><em>IF-ELSE<\/em><\/strong> statements.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-Block-Diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13392\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-Block-Diagram.png\" alt=\"AWD Block Diagram\" width=\"442\" height=\"208\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13393\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD.png\" alt=\"AWD\" width=\"373\" height=\"179\" \/><\/a><\/p>\n<h4><u><br \/>\n<\/u>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD_CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13394\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD_CubeMX.png\" alt=\"AWD_CubeMX\" width=\"423\" height=\"561\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void ADC1_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main()<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0unsigned int a1 = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_init();\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_clear_home(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(0, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putstr(\"STM8 AWD\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(0, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putstr(\"A1\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while (TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ClearFlag(ADC1_FLAG_EOC);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_StartConversion();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(ADC1_GetFlagStatus(ADC1_FLAG_EOC) == 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a1 = ADC1_GetConversionValue();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lcd_print(4, 1, a1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(ADC1_GetFlagStatus(ADC1_FLAG_AWD))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ClearFlag(ADC1_FLAG_AWD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(90);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_1, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void ADC1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_DeInit();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_CHANNEL_1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_PRESSEL_FCPU_D10, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_EXTTRIG_GPIO, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_ALIGN_RIGHT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_SCHMITTTRIG_CHANNEL1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_AWDChannelConfig(ADC1_CHANNEL_1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_SetHighThreshold(600);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_SetLowThreshold(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0ADC1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0char chr = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0chr = ((value \/ 1000) + 0x30);\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(x_pos, y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0chr = (((value \/ 100) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto((x_pos + 1), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0chr = (((value \/ 10) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto((x_pos + 2), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0chr = ((value % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto((x_pos + 3), y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(chr); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">The code for the AWD example is just as the one demonstrated in the ADC example. However, this time the ADC channel is channel 1 (PB1). Setting up the AWD is simple. We just need to set the limits, specify which channel to be monitored and enable the AWD unit.<\/p>\n<pre><span style=\"color: #0000ff\"><em>ADC1_AWDChannelConfig(ADC1_CHANNEL_1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>ADC1_SetHighThreshold(600);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>ADC1_SetLowThreshold(200);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Here we have set 600 and 200 ADC counts as upper and lower limits respectively.<\/p>\n<p style=\"text-align: justify\">In the main function, we are simply polling AWD flag. If an AWD (beyond boundary zone) event on PB1 pin occurs the LED on PD0 starts flashing. If PB1 senses voltage between 200 and 600 ADC counts, the LED is turned off, indicating guarded zone.<\/p>\n<pre><span style=\"color: #0000ff\"><em>if(ADC1_GetFlagStatus(ADC1_FLAG_AWD))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0ADC1_ClearFlag(ADC1_FLAG_AWD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13395\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-1-580x517.jpg\" alt=\"AWD (1)\" width=\"580\" height=\"517\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-1-580x517.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-1.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13396\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-2-580x326.jpg\" alt=\"AWD (2)\" width=\"580\" height=\"326\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-2-580x326.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/AWD-2-1024x576.jpg 1024w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/bvVNuVpeFPk?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p><!--nextpage--><\/p>\n<h2>Independent Watchdog (IWDG)<\/h2>\n<p style=\"text-align: justify\">The IWDG is just the ordinary watchdog timer we usually find in any modern micro. The purpose of this timer is to recover a micro from an unanticipated event that may result in unresponsive or erratic behaviour. As the name suggests, this timer does not share anything with any other internal hardware peripheral and is clocked by LSI (128kHz) only. Thus, it is invulnerable to main clock (HSE or HSI) failure.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13398\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram1-580x139.png\" alt=\"Block Diagram\" width=\"580\" height=\"139\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram1-580x139.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram1.png 720w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Clock-Diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13399\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Clock-Diagram-580x253.png\" alt=\"Clock Diagram\" width=\"580\" height=\"253\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Clock-Diagram-580x253.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Clock-Diagram.png 831w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">The IWDG works by decrementing a counter, counting time in the process. When the counter hits zero, a reset is issued. Usually we would want that this reset never occurs and so the counter is periodically updated in the application firmware. If for some reason, the counter is not refreshed, a reset will occur, recovering the MCU from a disastrous situation.<\/p>\n<p style=\"text-align: justify\">Configuring the IWDG is very easy with SPL. There are certain steps to follow but SPL manages them well internally. All we\u2019ll need is to configure the IWDG and reload it periodically before time runs out.<\/p>\n<p style=\"text-align: justify\">The formula required to calculate timeout is given below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13400\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula.png\" alt=\"Formula\" width=\"249\" height=\"183\" \/><\/a><\/p>\n<p>Typical values of timeout are as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Typical-Values.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13401\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Typical-Values-580x258.png\" alt=\"Typical Values\" width=\"580\" height=\"258\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Typical-Values-580x258.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Typical-Values.png 754w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13368\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\" alt=\"CubeMX\" width=\"415\" height=\"537\" \/><\/a><\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void IWDG_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0unsigned int t = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_WriteLow(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0for(t = 0; t &lt; 60000; t++);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(t = 0; t &lt; 1000; t++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_ReloadCounter();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void IWDG_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_Enable();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_SetPrescaler(IWDG_Prescaler_128);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_SetReload(0x99);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">In this example, we need not to look at peripheral and CPU clock as IWDG is not dependent on them. Still we can see that the CPU is running at 500 kHz speed while the peripherals at 2 MHz speed.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">To setup the IWDG, we need to enable it first and then apply <strong><em>Write Access Protection<\/em><\/strong> key (0x55). We just need to set the prescaler and the counter value. The down counter will start from this value and count down to zero unless refreshed. In this example, the prescaler is set to 128 and reload value is set to 153 (0x99). Thus, with these we get a timeout of approximately 300ms. After entering these values we must prevent accidental changes in the firmware and so to do so the write access must be disabled.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void IWDG_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_Enable();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_SetPrescaler(IWDG_Prescaler_128);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_SetReload(0x99);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Disco board\u2019s user button and LED are used for the demo. At the very beginning, the LED is lit for some time before the IWDG is configured, indicating the start of the firmware. In the main loop, the LED is toggled with some delay arranged by a<strong><em> for<\/em><\/strong> loop. Inside the loop, the button\u2019s state is polled. If the button is kept pressed it will always be in logic low state, reloading the IWDG counter. If its state changes to logic high and 300ms passes out, a reset is triggered.<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>for(t = 0; t &lt; 1000; t++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>     if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IWDG_ReloadCounter();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 IWDG_WriteAccessCmd(IWDG_WriteAccess_Disable);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>Note it is possible to calibrate LSI. It is however rarely needed.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/05XKoy0ieHo?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Window Watchdog (WWDG)<\/h2>\n<p style=\"text-align: justify\">The WWDG is a bit more advanced watchdog timer. Unlike the IWDG, it will trigger a reset condition if its counter is reloaded earlier or later than a predefined time window. This kind of timer is usually found in high-end microcontrollers like ARMs, ATXMegas and recently released micros. Cool features like this and others make me feel that indeed STM8s are high-end affordable 8-bit alternatives when compared to traditional 8-bit MCUs.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13402\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram2-580x310.png\" alt=\"Block Diagram\" width=\"580\" height=\"310\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram2-580x310.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Block-Diagram2.png 690w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">The WWDG works by comparing a down counter against a window register. The counter can only be refreshed when its value is greater than 0x3F and less than window register value. If the counter is refreshed before the value set on window register or when the counter is less than or equal to 0x3F. If the counter hits the value 0x3F, reset automatically triggers. It is programmer\u2019s responsibility to refresh the counter at proper time. Note unlike IWDG, WWDG is not independent of main clock.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13403\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing.png\" alt=\"Timing\" width=\"376\" height=\"247\" \/><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13404\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula1.png\" alt=\"Formula\" width=\"543\" height=\"89\" \/><\/a><\/p>\n<h4><u><br \/>\n<\/u>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13368\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\" alt=\"CubeMX\" width=\"415\" height=\"537\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">The code example here demonstrates WWDG action. Simply Disco board\u2019s user LED and button are used. When the code starts executing, the LED starts blinking slowly, indicating the start of the code. When the code executes the main loop, the LED blinks rapidly to indicate main loop execution. If the button is pressed randomly the micro is reset because the counter is refreshed before the allowed time. Sometimes the micro may not reset because the counter may be in the allowed window \u2013 hence the name Window Watchdog.<\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void WWDG_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0unsigned char i = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0for(i = 0x00; i &lt; 0x04; i++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(40);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0WWDG_setup();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>          if((GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE) || \r\n             ((WWDG_GetCounter() &gt; 0x60) &amp;&amp;\u00a0\u00a0\u00a0 (WWDG_GetCounter() &lt; 0x7F)))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WWDG_SetCounter(0x7F);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(20);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV64);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void WWDG_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0WWDG_Init(0x7F, 0x60);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: justify\">Explanation<\/h4>\n<p style=\"text-align: justify\">There\u2019s no way to enable watchdogs manually in software as they are always enabled. However, there are configuration bits to select if the IWDG and the WWDG are enabled in software or hardware. They only come in effect when configured. This is cool.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/WDG-Configuration-Bits.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13405\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/WDG-Configuration-Bits-580x242.png\" alt=\"WDG Configuration Bits\" width=\"580\" height=\"242\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/WDG-Configuration-Bits-580x242.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/WDG-Configuration-Bits.png 608w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>For WWDG, we just need to set the value of the down counter and the window register value only.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void WWDG_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0WWDG_Init(0x7F, 0x60);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p><span style=\"color: #000000\">We need to monitor the WWDG in order to reload it when it is the right time window.<\/span><\/p>\n<pre><span style=\"color: #0000ff\"><em>while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>      if((GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE) || \r\n      ((WWDG_GetCounter() &gt; 0x60) &amp;&amp;\u00a0\u00a0\u00a0 (WWDG_GetCounter() &lt; 0x7F)))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WWDG_SetCounter(0x7F);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteReverse(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(20);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<p>Remember too early or too late will reset the micro.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/a_JWHJCh_-o?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Timer Overview<\/h2>\n<p style=\"text-align: justify\">Timers are perhaps the most versatile piece of hardware in any micro. As their name tells, timers are useful for measurement of timed events like frequency, time, phase sequence, etc. and generate time-based events like PWM, waveform, etc. Timers are also needed for touch sensing applications.<\/p>\n<p style=\"text-align: justify\">In any STM8 micro, there are three categories of timers. These are:<\/p>\n<ul style=\"text-align: justify\">\n<li>Advanced Control Timer (TIM1)<\/li>\n<li>General Purpose Timers (TIM2, TIM3 &amp; TIM5)<\/li>\n<li>Basic Timers (TIM4 &amp; TIM6)<\/li>\n<\/ul>\n<p style=\"text-align: justify\">The basic working principle of all timers are same with some minor differences. Advanced timers are mainly intended for applications requiring specialized motor control, SMPSs, inverters, waveform generation, pulse width measurements, etc. Then there are general purpose timers that share almost all the features of advanced timer without the advanced features like brake, dead-time control, etc. Basic timers are all same as general purpose timers but lack PWM output\/capture input pins and are intended mainly for time base generations. Here\u2019s the summary of all timers of STM8 micros:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timer-Comparision.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13406\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timer-Comparision-580x417.png\" alt=\"Timer Comparision\" width=\"580\" height=\"417\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timer-Comparision-580x417.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timer-Comparision.png 625w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Unlike the timers of other micros, STM8 timers have the more functionality that are otherwise only available in some special micros only. Timer cover a significant part of the reference manual. They are so elaborate that it is not possible to describe all of them in just one post. Therefore, here we\u2019ll be exploring the basics for now.<\/p>\n<p><!--nextpage--><\/p>\n<h2>Time Base Generation (TIM2)<\/h2>\n<p style=\"text-align: justify\">Time base generation is the most basic property of any timer and is also the most needed requirement in embedded systems. This mode can be used with or without interrupt. We\u2019ll first check the method firstly without interrupt and then with interrupt.<\/p>\n<p style=\"text-align: justify\">With time base generation, we can accurately time stuffs and events that are more precise than using delays, loops or other methods. Time base generation utilizes hardware timers and so work independently from other processes. It has many uses. For instance, with it we can avoid software delays, generate time slots of a Real-Time Operating System (RTOS) and many other tasks.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Time-Base-Unit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13408\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Time-Base-Unit.png\" alt=\"Time-Base Unit\" width=\"556\" height=\"103\" \/><\/a><\/p>\n<p style=\"text-align: justify\">The time base unit for all timers of STM8 is all same. There are a few differences. For example, Timer 1 (TIM1) has a repetition counter. It is like a counter within another counter. Other timers lack this part. All timers can count up while advance timers can count down too.<\/p>\n<p style=\"text-align: justify\">The basic theory of time base generation is you have a peripheral clock which you would like to scale according to your need. Thus, you prescale it and use the new clock to run a counter. The counter will tick, incrementing count as time flies. It is just like counting from 0 to 100 and repeating from 0 again after reaching 100. Shown below is the generalized formula for finding an important event called timer reload:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula-for-TIM-base.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13410\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Formula-for-TIM-base.png\" alt=\"Formula for TIM base\" width=\"575\" height=\"106\" \/><\/a><\/p>\n<p style=\"text-align: justify\">This is the amount of time that will pass before timer overflow event occurs and the timer restarts from its initial count.<\/p>\n<p style=\"text-align: justify\">In my example, the peripheral or master clock is set to 2MHz. Thus, to make timer 2 (TIM2) reload after roughly 2 seconds, I have to prescale it by a factor of 2048 and load it with 1952 counts. Note that TIM2 doesn\u2019t have a repetition counter and so it is set to 1.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13368\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/CubeMX.png\" alt=\"CubeMX\" width=\"415\" height=\"537\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">In this example, Disco board\u2019s user LED is turned-on and off without using any software delay. TIM2 is used to create time delay as such that the code is not stuck in a time-wasting loop.<\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM2_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(TIM2_GetCounter() &gt; 976)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteLow(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 };<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_OD_HIZ_SLOW);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0IM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 TIM2_TimeBaseInit(TIM2_PRESCALER_2048, 1952);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>Firstly, the CPU and the peripheral clock are both set at 2 MHz.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<p>As explained earlier, to get 2 second timer reload interval we need to prescale the timer by 2048 and load its counter with 1952. This is what should be the setup for TIM2:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0TIM2_TimeBaseInit(TIM2_PRESCALER_2048, 1952);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>Our goal is to keep the LED on for 1 second and off for 1 second. It takes 1952 TIM2 counts for 2 second interval and so one second passes when this count is 976. Thus, in the main loop we are checking the value of TIM2\u2019s counter. From 0 to 976 counts, the LED is on and from 977 to 1952 counts, the LED is off. Note that the LED\u2019s positive end is connected to VDD and so it will turn on only PD0 is low.<\/p>\n<pre><span style=\"color: #0000ff\"><em>if(TIM2_GetCounter() &gt; 976)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_WriteLow(GPIOD, GPIO_PIN_0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/ZstHDHAAHOM?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Timer Interrupt (TIM4)<\/h2>\n<p style=\"text-align: justify\">In this example uses the same concepts of the previous example but it is based on timer interrupt \u2013 TIM4 interrupt. Timer interrupts are very important interrupts apart from other interrupts in a micro. To me they are highly valuable and useful.<\/p>\n<p style=\"text-align: justify\">This example demonstrates how to scan and project information on multiple seven segment displays with timer interrupt while the main loop can process the information to be displayed.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM4-Interrupt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13411\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM4-Interrupt.png\" alt=\"TIM4 Interrupt\" width=\"551\" height=\"603\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int value = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned char n = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned char seg = 0x01;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>const unsigned char num[0x0A] = \r\n{0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM4_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM4_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while (TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(999);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>     GPIO_Init(GPIOC, ((GPIO_Pin_TypeDef)(GPIO_PIN_4 | GPIO_PIN_5 \r\n               | GPIO_PIN_6 | GPIO_PIN_7)), GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM4_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM4_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM4_TimeBaseInit(TIM4_PRESCALER_32, 128);\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM4_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8s_it.h (top part only)<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#ifndef __STM8S_IT_H<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define __STM8S_IT_H<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>@far @interrupt void TIM4_UPD_IRQHandler(void);<\/em><\/span><\/pre>\n<pre><\/pre>\n<pre><\/pre>\n<pre><span style=\"color: #0000ff\">\/* Includes ------------------------------------------------------------------*\/<\/span><\/pre>\n<pre><span style=\"color: #0000ff\">#include \"stm8s.h\"<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8s_it.c (top part only)<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s_it.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned int value;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned char n;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned char seg;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern const unsigned char num[10];<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM4_UPD_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0switch(seg)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 1:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = (value \/ 1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xE0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 2:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = ((value \/ 100) % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xD0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 3:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = ((value \/ 10) % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xB0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 4:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = (value % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0x70);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0seg++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(seg &gt; 4)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 seg = 1;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n       TIM4_ClearFlag(TIM4_FLAG_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8_interrupt_vector.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s_it.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>typedef void @far (*interrupt_handler_t)(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>struct interrupt_vector {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 unsigned char interrupt_instruction;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 interrupt_handler_t interrupt_handler;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/@far @interrupt void NonHandledInterrupt (void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* in order to detect unexpected events during development, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 it is recommended to set a breakpoint on the following instruction<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/return;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/\/}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern void _stext();\u00a0\u00a0\u00a0\u00a0 \/* startup routine *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>struct interrupt_vector const _vectab[] = {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, (interrupt_handler_t)_stext}, \/* reset *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* trap\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq0\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq1\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq2\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq3\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq4\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq5\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq6\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq7\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq8\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq9\u00a0 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq10 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq11 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq12 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq13 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq14 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq15 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq16 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq17 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq18 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq19 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq20 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq21 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq22 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, (interrupt_handler_t)TIM4_UPD_IRQHandler}, \/* irq23 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq24 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq25 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq26 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq27 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq28 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {0x82, NonHandledInterrupt}, \/* irq29 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>Both the peripheral and CPU clocks are running at 2MHz.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>....<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">TIM4 is a basic timer and so it is better to use it for such tasks. We initialize it by setting its prescaler to 32 and loading its counter with 128. These values will make TIM4 overflow and interrupt every 2ms \u2013 enough time to project info in one seven segment. There are 4 seven segment displays and so within 8ms all four are updated and your eyes see it as if all projecting info at the same time \u2013 a trick of vision. Lastly, we need to enable what kind of interrupt we are expecting from the timer and finally enable the global interrupt.<\/p>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><em>void TIM4_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM4_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM4_TimeBaseInit(TIM4_PRESCALER_32, 128);\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM4_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\r\n    enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Remember the first interrupt example? We have to let the compiler know which interrupt we are using. If you look at the datasheet, you\u2019ll see that TIM4 update\/overflow is located in IRQ23. We need this and so we should make the following change in the <strong><em>stm8_interrupt_vector.c<\/em><\/strong> file:<\/p>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)TIM4_UPD_IRQHandler}, \/* irq23 *\/<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Remember to add the interrupt header and source files as we are going to use interrupt here. Inside the ISR, we do the scanning of each seven segment. Every time an overflow interrupt occurs, a seven segment is changed. At the end of the ISR a counter is incremented to select the next display when new overflow event occurs. Inside the <strong><em>Switch-Case<\/em><\/strong>, we turn on the seven segment and decide the value that seven segment should show. Finally, the timer overflow\/update flag is cleared.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM4_UPD_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0switch(seg)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 1:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = (value \/ 1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xE0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 2:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = ((value \/ 100) % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xD0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 3:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = ((value \/ 10) % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0xB0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case 4:<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n = (value % 10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOD, num[n]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Write(GPIOC, 0x70);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0seg++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(seg &gt; 4)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 seg = 1;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n       TIM4_ClearFlag(TIM4_FLAG_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13413\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM4.jpg\" alt=\"TIM4\" width=\"555\" height=\"640\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/Sa20Hf2N4gE?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>General Purpose Pulse Width Modulation (TIM2 PWM)<\/h2>\n<p style=\"text-align: justify\">Pulse Width Modulation (PWM) is a must-have feature of any microcontroller. PWM has many uses like motor control, SMPSs, lighting control, sound generation, waveform generation, etc. Unlike other micros which have limited PWM channels, STM8 has several PWM channels. For instance, STM8S003K has seven independent PWM channels, three of which belong to TIM2 \u2013 a general purpose (GP) timer.<\/p>\n<p style=\"text-align: justify\">PWMs generated by GP timers are basic PWMs. They can be used for simple tasks like LED brightness control, servo motor control, etc. that don\u2019t require advanced features like dead-time, brake or complementary waveform generation. In this section, we will see how to use TIM2 to generate simple PWMs.<\/p>\n<p style=\"text-align: justify\">Please note that in more advanced STM8 micros, timer I\/Os are dependent on alternate function configuration bits. Check those bits before uploading codes. In some STM8 micros, the I\/Os are also remappable, meaning that the I\/Os can be swapped in different GPIOs. Take the help of STM8CubeMx if needed.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/GP-PWM-CubeMX.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13414\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/GP-PWM-CubeMX.png\" alt=\"GP PWM CubeMX\" width=\"405\" height=\"575\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">This is a pretty simple example. Here all three channels of TIM2 are used to smoothly fade and glow three LEDs connected to the timer channels.<\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0signed int pwm_duty = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(pwm_duty = 0; pwm_duty &lt; 1000; pwm_duty += 10)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare1(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare2(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare3(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(pwm_duty = 1000; pwm_duty &gt; 0; pwm_duty -= 10)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare1(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare2(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare3(pwm_duty);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOA);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, ((GPIO_Pin_TypeDef)GPIO_PIN_3 | GPIO_PIN_4), \r\n                GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0\u00a0TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_HIGH);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_LOW);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC3Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_HIGH);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>Again, the CPU and the peripheral clock are set at 2 MHz.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<p>Next, we need to configure the PWM GPIOs as outputs.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOA);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, ((GPIO_Pin_TypeDef)GPIO_PIN_3 | GPIO_PIN_4), \r\n                GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Just like other microcontrollers, PWM generation involves a timer. Here as said TIM2 is that timer. We need to set time base first before actually configuring the PWM channels.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0\u00a0TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1000);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_HIGH);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_LOW);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC3Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                   TIM2_OCPOLARITY_HIGH);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);\r\n<\/em>}<\/span><\/pre>\n<p style=\"text-align: justify\">In the codes above, TIM2 has a time base of 16ms or 62.5kHz. This time base is further divided by the <strong><em>Output Compare (OC) <\/em><\/strong>unit. Thus, here the 62.5kHz base is further divided by 1000 to get 62.5Hz PWM frequency. The maximum duty cycle is therefore 1000. Additionally, we can set PWM polarity and command the channel if or if not should it behave in an inverted manner.<\/p>\n<p style=\"text-align: justify\">To change PWM duty, we need to call the following function:<\/p>\n<pre><span style=\"color: #0000ff\"><em>TIM2_SetCompareX(pwm_duty); \u00a0 \u00a0 \u00a0 \u00a0  \u00a0 \u00a0 \u00a0 \u00a0where X represents channel ID (1, 2 or 3)<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Note that in STM8 micros, there is a trade-off between duty cycle and PWM frequency. If the PWM resolution, i.e. duty cycle is big then PWM frequency is small and vice-versa. This is true for all timers.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM2-PWM.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13415\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM2-PWM-580x523.jpg\" alt=\"TIM2 PWM\" width=\"580\" height=\"523\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM2-PWM-580x523.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM2-PWM.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/BPS5unUHDz4?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p><!--nextpage--><\/p>\n<h2>Advanced Pulse Width Modulation (TIM1 PWM)<\/h2>\n<p style=\"text-align: justify\">Timer 1 (TIM1) is an advance timer and so the PWMs generated by it have several additional features that are not available with other timers. For example, it is possible to generate complementary PWMs with TIM1. Up to three sets of complimentary PWMs can be generated. Such PWMs are useful in designing three phase inverters, rectifiers and other power-related tasks. TIM1 PWMs are also very useful for motor control applications. It is also possible to add dead-time and brake. Apart from these TIM1 can also generate PWMs just like GP timers. In this mode however, complimentary PWM outputs are unavailable and up to four independent PWM channels can be made available.<\/p>\n<p style=\"text-align: justify\">In this example, I have demonstrated how to create complementary PWMs in TIM1 PWM channel 1.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13416\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM.png\" alt=\"TIM1 PWM\" width=\"479\" height=\"579\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0signed int i = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(i = 0; i &lt; 1000; i += 1)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_SetCompare1(i);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(i = 1000; i &gt; 0; i -= 1)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_SetCompare1(i);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_UP, 1000, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OC1Init(TIM1_OCMODE_PWM1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OUTPUTSTATE_ENABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OUTPUTNSTATE_ENABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a01000, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCPOLARITY_LOW, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCNPOLARITY_LOW, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0TIM1_OCIDLESTATE_RESET, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCNIDLESTATE_RESET);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM1_CtrlPWMOutputs(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><u>Explanation<\/u><\/p>\n<p>This time we used the full 16MHz speed of HSI both for peripheral and CPU clocks:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);<\/em><\/span><\/pre>\n<p>Like as with the previous example PWM output GPIOs are set as outputs:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">TIM1 and OC channel initialization is just like the previous example with some minor differences. The time base generation part seems to have some additional arguments. These are because:<\/p>\n<ul style=\"text-align: justify\">\n<li>Unlike other timers, TIM1 prescaler value is not a fixed set of multiples of 2.<\/li>\n<li>The counting mode is not just up mode counting. Counting mode can also be down counting.<\/li>\n<li>TIM1 has additional repetition counter.<\/li>\n<li>Except the basic timers all timers in STM8 are 16-bit timer.<\/li>\n<\/ul>\n<p style=\"text-align: justify\">If you open the header file for TIM1, you\u2019ll see many functions. Many of these functions are not available with other timers, expressing the power of an advance timer.<\/p>\n<p style=\"text-align: justify\">Likewise, there are some additional info we must feed when configuring the OC channels. We need to set info about complementary channels even if we don\u2019t need them. We can additionally set the default idle states of PWMs apart from polarities.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_UP, 1000, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OC1Init(TIM1_OCMODE_PWM1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OUTPUTSTATE_ENABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OUTPUTNSTATE_ENABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a01000, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCPOLARITY_LOW, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCNPOLARITY_LOW, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0TIM1_OCIDLESTATE_RESET, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_OCNIDLESTATE_RESET);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM1_CtrlPWMOutputs(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>To change the duty cycle of a channel, we need to call this function:<\/p>\n<pre><span style=\"color: #0000ff\"><em>TIM1_SetCompareX(duty_cycle);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/\u00a0\u00a0 where X represents channel ID (1, 2, 3 or 4)<\/em><\/span><\/pre>\n<p>Complementary outputs occur in pairs and so they are interdependent. That\u2019s why there is no separate function for outputs labelled <strong><em>N<\/em><\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13418\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM-580x270.jpg\" alt=\"TIM1 PWM\" width=\"580\" height=\"270\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM-580x270.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM1-PWM.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cpwm.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13419\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cpwm-580x311.png\" alt=\"cpwm\" width=\"580\" height=\"311\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cpwm-580x311.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cpwm-1024x548.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/cpwm.png 1361w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/uclCXH1ZPWU?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Timer Input Capture (TIM1 &amp; TIM2)<\/h2>\n<p style=\"text-align: justify\">Input capture is needed for measurements of pulses, pulse widths, frequencies, phase detection and similar stuffs. With external interrupts these measurements can be done with some limitations. However, using timer capture has some serious benefits. First of all, accuracy of measurements and secondly timer capture simplifies many tasks as timers themselves time stuffs properly. Dedicated hardware make stuffs like PWM measurement less complex and resource-friendly too.<\/p>\n<p style=\"text-align: justify\">STM8 timers have several capture channels just like output compare channels (PWM). The number of input capture channels is same as the number of PWM channels. Except basic timers all timers have input capture option.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM-CAP.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13420\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/TIM-CAP.png\" alt=\"TIM CAP\" width=\"491\" height=\"589\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">In this demo, TIM2 is configured to generate PWM on its CH1 output. TIM1 is configured to capture every rising edge of incoming waveform at its input capture channel CH1. When a capture event occurs, the current time count of TIM1 is saved. By deducting the recent capture count from the previous capture count, we can measure time period of the incoming PWM signal and hence its frequency. If the frequency is too high, TIM1 may overflow and so we need to take care of it too. We, thus, need to check TIM1 overflow event too.<\/p>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"lcd.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int overflow_count = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned long pulse_ticks = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned long start_time = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned long end_time = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned long value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main()<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 unsigned long time_period = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM1_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0TIM2_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0LCD_init();\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0LCD_clear_home(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0LCD_goto(0, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0LCD_putstr(\"T\/ms:\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0delay_ms(10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0time_period = pulse_ticks;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lcd_print(0, 1, time_period);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(400);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_TimeBaseInit(2000, TIM1_COUNTERMODE_UP, 55535, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, \r\n                 TIM1_ICSELECTION_DIRECTTI, 1, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ITConfig(TIM1_IT_CC1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\r\n     enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1250);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                  TIM2_OCPOLARITY_LOW);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare1(625);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned long value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0char tmp[6] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20} ;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0tmp[0] = (((value \/ 100000) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0tmp[1] = (((value \/ 10000) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0tmp[2] = (((value \/ 1000) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0tmp[3] = (((value \/ 100) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0tmp[4] = (((value \/ 10) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0tmp[5] = ((value % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(x_pos, y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putstr(tmp);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8_interrupt_vector.c (Interrupt vector address part only)<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)TIM1_UPD_IRQHandler}, \/* irq11 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)TIM1_CH1_CCP_IRQHandler}, \/* irq12 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8s_it.h (Top part only)<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#ifndef __STM8S_IT_H<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define __STM8S_IT_H<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>@far @interrupt void TIM1_UPD_IRQHandler(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>@far @interrupt void TIM1_CH1_CCP_IRQHandler(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\/* Includes ------------------------------------------------------------------*\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>stm8s_it.c (Top part only)<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s_it.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned int overflow_count;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned long pulse_ticks;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned long start_time;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>extern unsigned long end_time;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_UPD_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0overflow_count++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearITPendingBit(TIM1_IT_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearFlag(TIM1_FLAG_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_CH1_CCP_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0end_time = TIM1_GetCapture1();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0pulse_ticks = ((overflow_count &lt;&lt; 16) - start_time + end_time);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0start_time = end_time;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0overflow_count = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearITPendingBit(TIM1_IT_CC1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearFlag(TIM1_FLAG_CC1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">The clocks and peripherals are set first. We are using 2 MHz peripheral clock and the CPU is running at 500 kHz.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">GPIOs must be set too. Since TIM2 is to output PWM, its CH1 must be set output. Likewise, TIM1\u2019s CH1 GPIO must be set as an input.<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_IN_FL_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">TIM1 need to be configured for input capture. We need to set time base for TIM1 first. It is set as such that TIM1 will overflow every second. Then we set input capture channel by specifying the edge sensitivity, channel, mode and scalars. Since we will be using interrupts, we must enable relevant interrupts.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_TimeBaseInit(2000, TIM1_COUNTERMODE_UP, 55535, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, \r\n                 TIM1_ICSELECTION_DIRECTTI, 1, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ITConfig(TIM1_IT_CC1, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\r\n     enableInterrupts();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">TIM2 is set for PWM generation on its CH1. The generated PWM will have a frequency of 50Hz and 50% duty cycle. The setup of TIM2 should be by now self-explanatory:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM2_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_TimeBaseInit(TIM2_PRESCALER_32, 1250);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000, \r\n                  TIM2_OCPOLARITY_LOW);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_SetCompare1(625);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM2_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">In the vector table of <strong><em>stm8_interrupt_vector.c <\/em><\/strong>file, we need to specify the interrupts we will be using:<\/p>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)TIM1_UPD_IRQHandler}, \/* irq11 *\/<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{0x82, (interrupt_handler_t)TIM1_CH1_CCP_IRQHandler}, \/* irq12 *\/<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">We have to specify the interrupt subroutine (ISR) prototype functions in the <strong><em>stm8s_it.h<\/em><\/strong> file. These functions are the places where the code will jump when respective interrupt occurs:<\/p>\n<pre><span style=\"color: #0000ff\"><em>@far @interrupt void TIM1_UPD_IRQHandler(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>@far @interrupt void TIM1_CH1_CCP_IRQHandler(void);<\/em><\/span><\/pre>\n<p>The ISR functions are coded in the <strong><em>stm8s_it.c<\/em><\/strong> file:<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_UPD_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0overflow_count++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearITPendingBit(TIM1_IT_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearFlag(TIM1_FLAG_UPDATE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<p>The first part is dealing with TIM1 overflow. If a capture occurs when TIM1 count is near to reset value we need to take this account. This part does so and an overflow counter is incremented.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void TIM1_CH1_CCP_IRQHandler(void) <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0end_time = TIM1_GetCapture1();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0pulse_ticks = ((overflow_count &lt;&lt; 16) - start_time + end_time);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0start_time = end_time;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0overflow_count = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearITPendingBit(TIM1_IT_CC1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0TIM1_ClearFlag(TIM1_FLAG_CC1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">The second part is where TIM1 capture is recorded. Once a rising edge is captured, an interrupt is issued. In the interrupt, we must first save the current TIM1 counter count in the variable named <strong><em>end_time<\/em><\/strong>. The formula for pulse tick is then computed. Note how the TIM1 overflow is addressed in the formula. The new start time should be the previous capture time because we need to deduct old capture count from new capture count. Lastly, overflow counter, capture flag and pending interrupts are cleared.<\/p>\n<p style=\"text-align: justify\">In the main loop, we are just displaying the time period of capture in a LCD while everything is being processed in the background by interrupts:<\/p>\n<pre><span style=\"color: #0000ff\"><em>while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>     time_period = pulse_ticks;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0lcd_print(0, 1, time_period);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0delay_ms(400);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>};<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Capture.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13422\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Capture-580x348.jpg\" alt=\"Capture\" width=\"580\" height=\"348\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Capture-580x348.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Capture-600x360.jpg 600w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Capture.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/capture.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13423\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/capture-580x220.png\" alt=\"capture\" width=\"580\" height=\"220\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/capture-580x220.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/capture-1024x389.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/capture.png 1111w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/bzLUDwuFQTw?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Communication Overview<\/h2>\n<p style=\"text-align: justify\">STM8 microcontrollers are packed with several communication interfaces. These interfaces are needed to communicate with external devices like sensors, actuators, drives, etc. The most commonly used ones are Serial Communication (<strong><em>UART<\/em><\/strong>), Serial Peripheral Interface (<strong><em>SPI<\/em><\/strong>) and Inter-Integrated Circuit (<strong><em>I2C<\/em><\/strong>). There are also other additional more robust communication interfaces like Controller Area Network (<strong><em>CAN<\/em><\/strong>), Local Interconnect Network (<strong><em>LIN<\/em><\/strong>), Infrared Data Association (<strong><em>IrDA<\/em><\/strong>) and <strong><em>RS-485<\/em><\/strong>. The latter communications will not be discussed here in this article and are kept for future issues. These are methods are, however, not frequently used and are special forms of communications. For example, CAN and LIN are mostly used in automotive industries. Each method communication has its own advantages and disadvantages. Here we\u2019ll see the individual basics of various methods of communications.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Comms-Comparision.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13424\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Comms-Comparision-580x507.png\" alt=\"Comms Comparision\" width=\"580\" height=\"507\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Comms-Comparision-580x507.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Comms-Comparision.png 610w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">In STM8 microcontrollers, LIN, IrDA, RS-485 and UART all share the UART hardware peripheral. For other communications, there are dedicated separate hardware. We will now be exploring the basic ones here.<\/p>\n<p><!--nextpage--><\/p>\n<h2>Serial Communication (UART)<\/h2>\n<p style=\"text-align: justify\">Serial communication is perhaps the mostly-used classic communication method for interfacing a PC or other machines with a micro. With just two wire, we can achieve a full-duplex point-to-point communication. Owing to its simplicity and wide usage, it is the communication interface backbone that is used with GSM modems, RF modules, Bluetooth devices like RN-52, Wi-Fi devices like the popular ESP8266, etc. It is also widely used in industries. Other communications rely on it, for example, RS-485, LIN, etc.<\/p>\n<p style=\"text-align: justify\">\u00a0<a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/PPT.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13431\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/PPT-580x151.png\" alt=\"PPT\" width=\"580\" height=\"151\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/PPT-580x151.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/PPT-1024x267.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/PPT.png 1040w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Most STM8s have at least one UART module. Some have more than one. Different UARTs have different features as shown:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UARTs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13432\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UARTs-580x242.png\" alt=\"UARTs\" width=\"580\" height=\"242\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UARTs-580x242.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UARTs.png 891w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">To learn more about UART visit the following link:<\/p>\n<p style=\"text-align: justify\"><a href=\"https:\/\/learn.mikroe.com\/uart-serial-communication\/\">https:\/\/learn.mikroe.com\/uart-serial-communication\/<\/a><\/p>\n<p style=\"text-align: justify\">The UARTs of STM8 micros are so robust and packed with so many features that it is quite impossible to explain them all in this one article. Here we will explore the basic serial communication only.\u00a0 LIN and IRDA will hopefully be covered in future articles.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cubemx.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13430\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cubemx-469x650.png\" alt=\"Cubemx\" width=\"469\" height=\"650\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cubemx-469x650.png 469w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Cubemx.png 625w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void UART1_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0unsigned char i = 0;\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0char ch = 0;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_init();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_clear_home();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(0, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putstr(\"TX:\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(0, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putstr(\"RX:\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if(UART1_GetFlagStatus(UART1_FLAG_RXNE) == TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ch = UART1_ReceiveData8();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(7, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(ch);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_ClearFlag(UART1_FLAG_RXNE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_SendData8(i + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n          if(UART1_GetFlagStatus(UART1_FLAG_TXE) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LCD_goto(7, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LCD_putchar(i + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i++;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 };<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void UART1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_Init(9600, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_WORDLENGTH_8D, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_STOPBITS_1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_PARITY_NO, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_SYNCMODE_CLOCK_DISABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_MODE_TXRX_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>Explanation<\/h4>\n<p>The peripheral and CPU clocks are set at 2MHz:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);<\/em><\/span><\/pre>\n<p>The TX-RX GPIO pins are set as output and input respectively:<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_DeInit(GPIOD);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);<\/em><\/span><\/pre>\n<p>UART setup is straightforward. We just need to set baud rate, no. of data bits, no. of stop bit, parity and type of communication (synchronous or asynchronous).<\/p>\n<pre><span style=\"color: #0000ff\"><em>void UART1_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_Init(9600, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_WORDLENGTH_8D, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_STOPBITS_1, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_PARITY_NO, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_SYNCMODE_CLOCK_DISABLE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0UART1_MODE_TXRX_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0UART1_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">In the main code, we are checking both transmission complete and reception complete flags. With these flags, we will know if new data arrived and if it is possible to send a new data.<\/p>\n<p style=\"text-align: justify\">The first part checks if any new data received. That\u2019s why the <strong><em>IF<\/em><\/strong> condition is checking if the RX buffer is empty or not. If it is not empty then new data must have arrived. The new data (a character here) is fetched and displayed on a LCD. Then we clear the RX buffer not empty flag to enable reception of new data. After that we are sending some data to the host PC over the UART.<\/p>\n<pre><span style=\"color: #0000ff\"><em>if(UART1_GetFlagStatus(UART1_FLAG_RXNE) == TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\r\n\u00a0\u00a0\u00a0ch = UART1_ReceiveData8();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto(7, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(ch);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0UART1_ClearFlag(UART1_FLAG_RXNE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0UART1_SendData8(i + 0x30);\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>In the second part, we are checking if the last data was sent from our STM8 micro. The data sent is then displayed on LCD.<em>\u00a0<\/em><\/p>\n<pre><span style=\"color: #0000ff\"><em>if(UART1_GetFlagStatus(UART1_FLAG_TXE) == FALSE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_goto(7, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0LCD_putchar(i + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0i++;\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>Please note that both of these flags are very important.<\/p>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UART.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13435\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UART-580x209.jpg\" alt=\"UART\" width=\"580\" height=\"209\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UART-580x209.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/UART.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Untitled.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13433\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Untitled-580x326.png\" alt=\"Untitled\" width=\"580\" height=\"326\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Untitled-580x326.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Untitled-1024x576.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Untitled.png 1366w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/uo2tYDUnMmE?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Serial Peripheral Interface (SPI)<\/h2>\n<p style=\"text-align: justify\">SPI communication is an onboard synchronous communication method and is used by a number of devices including sensors, TFT displays, GPIO expanders, PWM controller ICs, memory chips, addon support devices, etc.<\/p>\n<p style=\"text-align: justify\">There\u2019s always one master device in a SPI communication bus which generates clock and select slave(s). Master sends commands to slave(s). Slave(s) responds to commands sent by the master. The number of slaves in a SPI bus is virtually unlimited. Except the chip selection pin, all SPI devices in a bus can share the same clock and data pins.<\/p>\n<p style=\"text-align: justify\">Typical full-duplex SPI bus requires four basic I\/O pins:<\/p>\n<ul>\n<li style=\"text-align: justify\"><strong><em>Master-Out-Slave-In (MOSI)<\/em><\/strong> connected to <strong><em>Slave-Data-In (SDI)<\/em><\/strong>.<\/li>\n<li style=\"text-align: justify\"><strong><em>Master-In-Slave-Out (MIS0)<\/em><\/strong> connected to <strong><em>Slave-Data-Out (SDO)<\/em><\/strong>.<\/li>\n<li style=\"text-align: justify\"><strong><em>Serial Clock (SCLK)<\/em><\/strong> connected to <strong><em>Slave Clock (SCK)<\/em><\/strong>.<\/li>\n<li style=\"text-align: justify\"><strong><em>Slave Select (SS)<\/em><\/strong> connected to <strong><em>Chip Select (CS)<\/em><\/strong>.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13427\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi-580x168.png\" alt=\"spi\" width=\"580\" height=\"168\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi-580x168.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi.png 951w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>In general, if you wish to know more about SPI bus here are some cool links:<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.mikroe.com\/spi-bus\/\">https:\/\/learn.mikroe.com\/spi-bus\/<\/a><\/li>\n<li><a href=\"https:\/\/learn.sparkfun.com\/tutorials\/serial-peripheral-interface-spi\">https:\/\/learn.sparkfun.com\/tutorials\/serial-peripheral-interface-spi<\/a><\/li>\n<li><a href=\"http:\/\/ww1.microchip.com\/downloads\/en\/devicedoc\/spi.pdf\">http:\/\/ww1.microchip.com\/downloads\/en\/devicedoc\/spi.pdf<\/a><\/li>\n<li><a href=\"http:\/\/tronixstuff.com\/2011\/05\/13\/tutorial-arduino-and-the-spi-bus\/\">http:\/\/tronixstuff.com\/2011\/05\/13\/tutorial-arduino-and-the-spi-bus\/<\/a><\/li>\n<li><a href=\"https:\/\/embeddedmicro.com\/tutorials\/mojo\/serial-peripheral-interface-spi\">https:\/\/embeddedmicro.com\/tutorials\/mojo\/serial-peripheral-interface-spi<\/a><\/li>\n<li><a href=\"http:\/\/www.circuitbasics.com\/basics-of-the-spi-communication-protocol\/\">http:\/\/www.circuitbasics.com\/basics-of-the-spi-communication-protocol\/<\/a><\/li>\n<\/ul>\n<p>STM8s have SPI hardware that are more capable than the SPI hardware found in other micros. An additional feature of STM8\u2019s SPI is the hardware CRC. This feature ensures reliable data communication between devices.<\/p>\n<p>&nbsp;<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi_cube.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13428\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/spi_cube.png\" alt=\"spi_cube\" width=\"499\" height=\"611\" \/><\/a><\/p>\n<h4><\/h4>\n<h4><span style=\"text-decoration: underline\">Code Example<\/span><\/h4>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"MAX72XX.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void SPI_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main()<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0unsigned char i = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 unsigned char j = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 unsigned char temp[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 const unsigned char text[96] =<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7E, 0x04, 0x08, 0x08, 0x04, 0x7E, 0x00,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/M<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x42, 0x42, 0x7E, 0x7E, 0x42, 0x42, 0x00,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/I<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x24, 0x00,\u00a0\u00a0\u00a0\u00a0\u00a0   \/\/C<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7E, 0x1A, 0x1A, 0x1A, 0x2A, 0x44, 0x00,\u00a0\u00a0\u00a0 \u00a0   \/\/R<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00,\u00a0\u00a0\u00a0\u00a0\u00a0   \/\/O<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7C, 0x12, 0x12, 0x12, 0x12, 0x7C, 0x00,\u00a0\u00a0\u00a0\u00a0 \u00a0  \/\/A<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7E, 0x1A, 0x1A, 0x1A, 0x2A, 0x44, 0x00,\u00a0\u00a0\u00a0 \u00a0   \/\/R<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7E, 0x7E, 0x4A, 0x4A, 0x4A, 0x42, 0x00,\u00a0\u00a0\u00a0\u00a0    \/\/E<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x00,\u00a0 \u00a0\u00a0\u00a0\u00a0  \/\/N<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00, 0x7C, 0x12, 0x12, 0x12, 0x12, 0x7C, 0x00,\u00a0\u00a0\u00a0\u00a0\u00a0   \/\/A<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 };<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0SPI_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0MAX72xx_init();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(i = 0; i &lt; sizeof(temp); i++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0temp[i] = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(i = 0; i &lt; sizeof(text); i++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0for(j = 0; j &lt; sizeof(temp); j++)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0temp[j] = text[(i + j)];<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0MAX72xx_write((1 + j), temp[j]);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0delay_ms(9);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_Init(GPIOC, ((GPIO_Pin_TypeDef)GPIO_PIN_5 | GPIO_PIN_6), \r\n               GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void SPI_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0SPI_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0SPI_Init(SPI_FIRSTBIT_MSB, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_BAUDRATEPRESCALER_2, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_MODE_MASTER, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_CLOCKPOLARITY_HIGH, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_CLOCKPHASE_1EDGE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_DATADIRECTION_1LINE_TX, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_NSS_SOFT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x00);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 SPI_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p><em>\u00a0<\/em><\/p>\n<p><strong><em><u>MAX72xx.h<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define CS_pin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GPIO_PIN_4<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define CS_port                        \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIOC<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define NOP\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0    \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x02<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x03<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x04<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x05<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x06<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG6\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x07<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define DIG7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0               \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x08<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define decode_mode_reg\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x09<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define intensity_reg\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0      \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x0A<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define scan_limit_reg\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x0B<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define shutdown_reg\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0     \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x0C<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define display_test_reg\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x0F<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define shutdown_cmd\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define run_cmd\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define no_test_cmd\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0       \u00a0 0x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define test_cmd\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  0x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_only\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x02<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x03<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x04<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x05<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_6\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x06<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define digit_0_to_7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x07<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define No_decode_for_all\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define Code_B_decode_digit_0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define Code_B_decode_digit_0_to_3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x0F<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define Code_B_decode_for_all\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00xFF<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void MAX72xx_init(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void MAX72xx_write(unsigned char address, unsigned char value);<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em><u>MAX72xx.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"MAX72xx.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void MAX72xx_init(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(CS_port, CS_pin, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 MAX72xx_write(shutdown_reg, run_cmd);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 MAX72xx_write(decode_mode_reg, 0x00);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0\u00a0MAX72xx_write(scan_limit_reg, 0x07);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 MAX72xx_write(intensity_reg, 0x04);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 MAX72xx_write(display_test_reg, test_cmd);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 delay_ms(10);\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 MAX72xx_write(display_test_reg, no_test_cmd);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void MAX72xx_write(unsigned char address, unsigned char value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(SPI_GetFlagStatus(SPI_FLAG_BSY));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(CS_port, CS_pin);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0SPI_SendData(address);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(!SPI_GetFlagStatus(SPI_FLAG_TXE));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0SPI_SendData(value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0while(!SPI_GetFlagStatus(SPI_FLAG_TXE));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0GPIO_WriteHigh(CS_port, CS_pin);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><u>Explanation<\/u><\/p>\n<p>This time we are again using the max peripheral and CPU clock:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE);<\/em><\/span><\/pre>\n<p>We also need to set the GPIOs:<\/p>\n<pre><span style=\"color: #0000ff\"><em>#define CS_pin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIO_PIN_4<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define CS_port\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GPIOC<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_DeInit(GPIOC);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(CS_port, CS_pin, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOC, ((GPIO_Pin_TypeDef)GPIO_PIN_5 | GPIO_PIN_6), \r\n          GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Note we can use definitions to make things meaningful. The GPIOs should be configured as fast I\/Os because SPI communication is faster than simple GPIO operations.<\/p>\n<p style=\"text-align: justify\">Now for the SPI configuration part. Assuming you know how to interpret timing diagrams and understand device datasheets, SPI configuration should not be a problem. Here in the case of MAX7219, we have configured the SPI port as to send MSB first, we have also selected a fast peripheral clock, we have made the STM8 SPI act like a master with proper SPI mode and we have set the sort of duplex. The last two parameters are not important as we are not using hardware slave select option and CRC feature.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void SPI_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0SPI_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0SPI_Init(SPI_FIRSTBIT_MSB, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_BAUDRATEPRESCALER_2, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_MODE_MASTER, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_CLOCKPOLARITY_HIGH, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_CLOCKPHASE_1EDGE, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_DATADIRECTION_1LINE_TX, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SPI_NSS_SOFT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x00);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 SPI_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p>The timing diagram of MAX7219 suggests that CS should be low in order for MAX7219 to receive data.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing-Diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13429\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing-Diagram-580x250.png\" alt=\"Timing Diagram\" width=\"580\" height=\"250\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing-Diagram-580x250.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Timing-Diagram.png 848w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Then it suggests that when idle, clock must be high, data transfer is done on every rising edge of the clock. All these are what required for setting up the SPI hardware.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void MAX72xx_write(unsigned char address, unsigned char value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(SPI_GetFlagStatus(SPI_FLAG_BSY));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteLow(CS_port, CS_pin);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 SPI_SendData(address);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(!SPI_GetFlagStatus(SPI_FLAG_TXE));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 SPI_SendData(value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(!SPI_GetFlagStatus(SPI_FLAG_TXE));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_WriteHigh(CS_port, CS_pin);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">Before sending data to MAX7219, we must check if the SPI hardware is busy for some reason. We set CS low by setting STM8\u2019s slave select pin (PC4) low. Then we send address and data. Every time we send something we must wait until it has completely been sent out. Finally, we set CS high to latch sent data. This function is what we will need to set MAX7219 things up and also to update displays.<\/p>\n<p style=\"text-align: justify\">The demo here is that of a MAX7219- based scrolling dot-matrix display. Letters of <strong><em>MICROARENA<\/em><\/strong> \u2013 the name of my Facebook page is scrolled.<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SPI.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13439\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SPI-580x638.jpg\" alt=\"SPI\" width=\"580\" height=\"638\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SPI-580x638.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/SPI.jpg 582w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/MAX7219.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13440\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/MAX7219.gif\" alt=\"MAX7219\" width=\"400\" height=\"225\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/O7mre-bzsGE?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Inter-Integrated Circuit (I2C)<\/h2>\n<p style=\"text-align: justify\">I2C is another popular form of on board synchronous serial communication developed by NXP. It just uses two wires for communication and so it is also referred as <strong><em>Two Wire Interface (TWI)<\/em><\/strong>. Just like SPI, I2C is widely used in interfacing real-time clocks (RTC), digital sensors, memory chips and so on. It is as much as popular as SPI but compared to SPI it is slower and have some limitations. Up to 127 devices can coexist in an I2C bus. In an I2C bus however it is not possible, by conventional means to interface devices with same device IDs or devices with different logic voltage levels without logic level converters and so on. Still however, I2C is very popular because these issues rarely arise and because of its simplicity. Unlike other communications, there\u2019s no pin\/wire swapping as two wires connect straight to the bus \u2013 SDA to SDA and SCL to SCL.<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13425\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c-580x143.png\" alt=\"i2c\" width=\"580\" height=\"143\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c-580x143.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c.png 936w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Just like SPI, an I2C bus must contain one master device (usually a microcontroller) and one or more slaves. The master is solely responsible for generating clock signals and initiating communication. Communication starts when master sends out a slave\u2019s ID with read\/write command. The slave reacts to this command by processing the request from the master and sending out data.<\/p>\n<p style=\"text-align: justify\">To know more about I2C interface visit the following links:<\/p>\n<ul style=\"text-align: justify\">\n<li><a href=\"https:\/\/learn.mikroe.com\/i2c-everything-need-know\/\">https:\/\/learn.mikroe.com\/i2c-everything-need-know\/<\/a><\/li>\n<li><a href=\"https:\/\/learn.sparkfun.com\/tutorials\/i2c\">https:\/\/learn.sparkfun.com\/tutorials\/i2c<\/a><\/li>\n<li><a href=\"http:\/\/www.ti.com\/lsds\/ti\/interface\/i2c-overview.page\">http:\/\/www.ti.com\/lsds\/ti\/interface\/i2c-overview.page<\/a><\/li>\n<li><a href=\"http:\/\/www.robot-electronics.co.uk\/i2c-tutorial\">http:\/\/www.robot-electronics.co.uk\/i2c-tutorial<\/a><\/li>\n<li><a href=\"https:\/\/www.i2c-bus.org\/i2c-bus\/\">https:\/\/www.i2c-bus.org\/i2c-bus\/<\/a><\/li>\n<li><a href=\"http:\/\/i2c.info\/\">http:\/\/i2c.info\/<\/a><\/li>\n<\/ul>\n<p style=\"text-align: justify\">Other protocols like SMBus and I2S have similarities with I2C and so learning about I2C advances learning these too.<\/p>\n<h4>Hardware Connection<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c_cube.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13426\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/i2c_cube.png\" alt=\"i2c_cube\" width=\"469\" height=\"611\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Code Example<\/h4>\n<p style=\"text-align: justify\">This code demonstrates how to interface BH1750 I2C digital light sensor with STM8S003K3. A LCD is used to display the light sensor\u2019s output in lux.<\/p>\n<p>&nbsp;<\/p>\n<p><strong><em><u>main.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"BH1750.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#include \"lcd.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void I2C_setup(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void main()<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  unsigned int LX = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  unsigned int tmp = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  clock_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  GPIO_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  I2C_setup();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0  LCD_init();\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0   BH1750_init();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_clear_home(); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_goto(0, 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_putstr(\"STM8 I2C\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_goto(0, 1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 LCD_putstr(\"Lx\");<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 delay_ms(10);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0while(TRUE)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tmp = get_lux_value(cont_L_res_mode, 20);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0if(tmp &gt; 10)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0LX = tmp;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0else<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0LX = get_lux_value(cont_H_res_mode1, 140);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>         lcd_print(3, 1, LX);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  delay_ms(200);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 };<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>      CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_LSICmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 \u00a0\u00a0CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>      CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>      CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>      CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void GPIO_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\r\n<\/em><\/span><span style=\"color: #0000ff\"><em>    GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void I2C_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 I2C_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 I2C_Init(100000, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0BH1750_addr, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_DUTYCYCLE_2, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_ACK_CURR, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_ADDMODE_7BIT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(CLK_GetClockFreq() \/ 1000000));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 I2C_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 char tmp[5] = {0x20, 0x20, 0x20, 0x20, 0x20} ;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 tmp[0] = ((value \/ 10000) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 tmp[1] = (((value \/ 1000) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 tmp[2] = (((value \/ 100) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 tmp[3] = (((value \/ 10) % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 tmp[4] = ((value % 10) + 0x30);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_goto(x_pos, y_pos);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 LCD_putstr(tmp);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<p>\u00a0 <strong><em><u>BH1750.h<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"STM8S.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0\u00a0 BH1750_addr\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a00x46<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 power_down\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 power_up\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x01<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 reset\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x07 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 cont_H_res_mode1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x10 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 cont_H_res_mode2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0   \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x11\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 cont_L_res_mode\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x13\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 one_time_H_res_mode1\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a00x20 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 one_time_H_res_mode2\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x21<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define\u00a0 one_time_L_res_mode\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a00x23\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void BH1750_init(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void BH1750_write(unsigned char cmd);\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int BH1750_read_word(void);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int get_lux_value(unsigned char mode, unsigned int delay_time);<\/em><\/span><\/pre>\n<p><em>\u00a0<\/em><\/p>\n<p><strong><em><u>BH1750.c<\/u><\/em><\/strong><\/p>\n<pre><span style=\"color: #0000ff\"><em>#include \"BH1750.h\"<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void BH1750_init(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{ <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 delay_ms(10);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 BH1750_write(power_down);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>void BH1750_write(unsigned char cmd)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_GenerateSTART(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_Send7bitAddress(BH1750_addr, I2C_DIRECTION_TX); <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_SendData(cmd);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_GenerateSTOP(ENABLE);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int BH1750_read_word(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned long value = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char num_of_bytes = 0x02;\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char bytes[2] = {0x00, 0x00};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_GenerateSTART(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_Send7bitAddress(BH1750_addr, I2C_DIRECTION_RX);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(num_of_bytes)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(num_of_bytes == 0)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 I2C_AcknowledgeConfig(I2C_ACK_NONE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 I2C_GenerateSTOP(ENABLE);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bytes[(num_of_bytes - 1)] = I2C_ReceiveData();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 num_of_bytes--;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 };\u00a0\u00a0 \u00a0\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 value = ((bytes[1] &lt;&lt; 8) | bytes[0]);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 return value;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>} <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>unsigned int get_lux_value(unsigned char mode, unsigned int delay_time)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned long lux_value = 0x00;\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char dly = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char s = 0x08;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(s)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(power_up);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(mode);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lux_value += BH1750_read_word();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for(dly = 0; dly &lt; delay_time; dly += 1)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(power_down);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 s--;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 lux_value &gt;&gt;= 3;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 return ((unsigned int)lux_value);<\/em><\/span><\/pre>\n<pre><em><span style=\"color: #0000ff\">}\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/pre>\n<p><em>\u00a0<\/em><\/p>\n<h4>Explanation<\/h4>\n<p style=\"text-align: justify\">Firstly both the CPU and peripheral clocks are set. Note the CPU is slower than last few examples. This has no significance.<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV2);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u2026.<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">I2C I\/Os are set as open drain outputs because they have external pull-up resistors that terminate the bus I\/Os to VDD lines. <strong><em>SCL<\/em><\/strong> pin is always an output from host microcontroller\u2019s end however <strong><em>SDA<\/em><\/strong> pin\u2019s direction varies with reading and writing operations. This is automatically done by the I2C hardware.<\/p>\n<pre><span style=\"color: #0000ff\"><em>GPIO_DeInit(GPIOB);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_FAST);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">I2C setup has many parameters to set, firstly the I2C bus clock speed, then its own ID, clock duty cycle, address mode, acknowledgement type and clock speed of the peripheral. Here the own ID and slave ID are both set same because we are not using our STM8 as a slave. It doesn\u2019t matter. You can also set something else.<\/p>\n<pre><span style=\"color: #0000ff\"><em>void I2C_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 \u00a0I2C_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 I2C_Init(100000, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0BH1750_addr, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_DUTYCYCLE_2, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_ACK_CURR, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0I2C_ADDMODE_7BIT, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(CLK_GetClockFreq() \/ 1000000));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 I2C_Cmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">If you have used compilers with built-in I2C library before then you may get some hiccups studying the following part. This is because those built-in libraries accomplish many tasks in the background that you never felt necessary. Flags and acknowledgments are such stuffs that are mostly automatically dealt by the compiler and ignore by most users. Personally, I had to struggle with these before settling this code. Another big difference is fact that the SPL\u2019s functions, their operations and nomenclatures for I2C are different than most I2C libraries one has seen before. Lastly, I2C examples with STM\u2019s SPL on the internet are rare and most of them demonstrate I2C example with 24 series EEPROMs only. I wanted to do something different and so I used BH1750 I2C digital sensor instead of repeating another EEPROM example.<\/p>\n<pre><span style=\"color: #0000ff\"><em>unsigned int BH1750_read_word(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned long value = 0x0000;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char num_of_bytes = 0x02;\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char bytes[2] = {0x00, 0x00};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_GenerateSTART(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 I2C_Send7bitAddress(BH1750_addr, I2C_DIRECTION_RX);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(num_of_bytes)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(num_of_bytes == 0)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 I2C_AcknowledgeConfig(I2C_ACK_NONE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 I2C_GenerateSTOP(ENABLE);\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bytes[(num_of_bytes - 1)] = I2C_ReceiveData();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 num_of_bytes--;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 };\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 value = ((bytes[1] &lt;&lt; 8) | bytes[0]);\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 return value;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>} <\/em><\/span><\/pre>\n<p style=\"text-align: justify\">As with SPI, we need to check first if I2C hardware is free. We, then, initiate a I2C start condition and check master\/slave mode selection. Next, we send out slave device\u2019s ID or address with read command, signalling that we wish to read from the slave. Again, a flag is checked before continuing. Here the sensor gives 16-bit light output data and so we need to extract two 8-bit data values. This is done in the <strong><em>while<\/em><\/strong> loop. At the end of data extraction process, we must generate stop as well as take care of acknowledgement. Finally, the two bytes are joined to form a word value representing light output.<\/p>\n<p style=\"text-align: justify\">The following function simplifies the task of determining lux value from the sensor. It selects mode of operation and latency. We will call this function in the main loop to extract average light value in lux.<\/p>\n<pre><span style=\"color: #0000ff\"><em>unsigned int get_lux_value(unsigned char mode, unsigned int delay_time)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned long lux_value = 0x00;\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char dly = 0x00;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 unsigned char s = 0x08;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 while(s)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(power_up);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(mode);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lux_value += BH1750_read_word();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for(dly = 0; dly &lt; delay_time; dly += 1)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_ms(1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BH1750_write(power_down);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 s--;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 }<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 lux_value &gt;&gt;= 3;<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0 return ((unsigned int)lux_value);<\/em><\/span><\/pre>\n<pre><em><span style=\"color: #0000ff\">}\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/pre>\n<p>&nbsp;<\/p>\n<h4>Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/I2C.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13438\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/I2C-580x543.jpg\" alt=\"I2C\" width=\"580\" height=\"543\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/I2C-580x543.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/I2C.jpg 640w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/bpwki1RCOXU?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><br \/>\n<!--nextpage--><\/p>\n<h2>Some Useful Tips<\/h2>\n<p style=\"text-align: justify\">When using a new compiler, I evaluate some certain things. For instance, how do I include my own written library files, interrupt management, what conventions I must follow and what dos and don\u2019ts must be observed.<\/p>\n<h3>Creation &amp; Addition of libraries<\/h3>\n<p style=\"text-align: justify\">At some point in working with any microcontroller, you\u2019ll need two basic libraries more than anything else. These are LCD and delay libraries. LCDs are great tools for quickly projecting or presenting data apart from debugging a code with a debugger. Similarly, time-wasting delay loops help us slow down things at our liking. Humans are not as fast as machines. Delays can be avoided in many novel ways but delays keep things simple and so are necessities in some areas.<\/p>\n<p style=\"text-align: justify\">The Standard Peripheral Library only provides libraries for hardware peripherals and surely not for anything else. It is also practically impossible to provide library for all hardware on available on the planet. Thus, whenever when we will be needing new hardware integrations with STM8s, we will have to code and tag our libraries with our projects. So how can we do so?<\/p>\n<p style=\"text-align: justify\">Earlier in this article I discussed about alphanumeric LCDs and delays. If you check the datasheet of such LCDs, you\u2019ll find initialization sequences in some while in others you may also find ready-made codes. These sequences are needed to be translated in code just like what we do with I2C or SPI-based devices.\u00a0 Shown below is such an example:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-Sequence.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13444\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LCD-Sequence.png\" alt=\"LCD Sequence\" width=\"407\" height=\"524\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Creating new libraries is simple. Just need to follow the following steps:<\/p>\n<ul style=\"text-align: justify\">\n<li>There should be a header file and a source file for every new module. For example, <strong><em>h<\/em><\/strong> and <strong><em>lcd.c<\/em><\/strong>.<\/li>\n<li>Every header file should start with the inclusion of <strong><em>h<\/em><\/strong> header file (<strong><em>#include &#8220;stm8s.h&#8221;<\/em><\/strong>). This header is needed because it allows the access to the internal hardware modules available in a STM8 micro. For example, we will need access to GPIOs to develop our LCD library.<\/li>\n<li>A good practice is that the header files only contain function prototypes, definitions, constants, enumerations and global variables.<\/li>\n<li>The corresponding source file must only include its header file in beginning.<\/li>\n<li>The source file should contain the body of codes for all functions declared in the header file.<\/li>\n<li>When one library is dependent on the functions of another\u2019s, the one that will be required in the new library must be included first. For example, we will need delay library in coding the LCD library because there are <strong><em>delay_ms<\/em><\/strong> functions in some parts of the library and so delay library should be included first. This should be the systematic order:<\/li>\n<\/ul>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><strong><em>#include \u201cstm8s_delay.h\u201d<\/em><\/strong><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><strong><em>#include \u201clcd.h\u201d<\/em><\/strong><\/span><\/pre>\n<p style=\"text-align: justify\">You can include these files at the bottom part of the <strong><em>stm8s_conf.h<\/em><\/strong> header file complying with right precedence as shown below:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-13443\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion1-580x386.png\" alt=\"File Inclusion\" width=\"580\" height=\"386\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion1-580x386.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/File-Inclusion1.png 632w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p>Alternatively, you can add them after the first line <strong><em>#include \u201cstm8s.h\u201d<\/em><\/strong> in your main source code.<\/p>\n<p>&nbsp;<\/p>\n<h3>Peripheral Clock Configurations<\/h3>\n<p style=\"text-align: justify\">In most codes revealed so far, I made clock configurations every time. The reasons behind so are<\/p>\n<ul>\n<li style=\"text-align: justify\">Selection of right clock source.<\/li>\n<li style=\"text-align: justify\">Adjustment of peripheral and system clocks as per requirement. Again, it is mainly intended to balance off both power consumption and overall performance.<\/li>\n<li style=\"text-align: justify\">Disabling any unused hardware. This reduces power consumption and help us avoid certain hardware conflicts.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #0000ff\"><em>void clock_setup(void)<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>{<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_LSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0 DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0 CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<pre><\/pre>\n<p>The following lines select clock sources:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_DeInit();<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSECmd(DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_LSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSICmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">What these lines do are enabling\/disabling clock sources and wait for the sources to stabilize.<\/p>\n<p style=\"text-align: justify\">Then the following lines select clock prescalers and switching:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_ClockSwitchCmd(ENABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);<\/em><\/span><\/pre>\n<p>Finally, the last segment enables\/disables peripheral clocks:<\/p>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0 <\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);<\/em><\/span><\/pre>\n<pre><em><span style=\"color: #0000ff\">CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);<\/span> <\/em><\/pre>\n<p style=\"text-align: justify\">This segment is very important and should always be rechecked. Different chips have different internal hardware peripheral and so this segment will be different. For instance, STM8S105 has no UART1 module but it has UART2 instead. Research which hardware are available in your target micro and then code this segment. I ended up with several wasted hours of finding trouble in various cases only to find that I didn\u2019t enable the required hardware.<\/p>\n<h3>Configuring Similar Stuffs Quickly<\/h3>\n<p style=\"text-align: justify\">Sometimes you may end up doing the same stuff over and over again while you could have done it simply with one or two lines of code. For example, in the LCD library, the GPIOs that connect with the LCD share the same configurations. All are fast push-pull outputs.<\/p>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_RS, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_EN, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_DB4, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_DB5, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_DB6, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\"><em>\u00a0GPIO_Init(LCD_PORT, LCD_DB7, GPIO_MODE_OUT_PP_HIGH_FAST);<\/em><\/span><\/pre>\n<p style=\"text-align: justify\">This can be done in a more simplistic manner with just one line of code:<\/p>\n<pre style=\"text-align: justify\"><span style=\"color: #0000ff\">GPIO_Init(LCD_PORT, ((GPIO_Pin_TypeDef)(LCD_RS | LCD_EN | LCD_DB4 | LCD_DB5 \r\n                     | LCD_DB6 | LCD_DB7)), GPIO_MODE_OUT_PP_HIGH_FAST);<\/span><\/pre>\n<p>As you can see it is just a bunch of logical OR operation. The same method is applicable for other peripherals that share the same initialization function.<\/p>\n<p>&nbsp;<\/p>\n<h3>Some Stuffs About Cosmic C and SPL<\/h3>\n<ul>\n<li style=\"text-align: justify\">Functions, variables and definitions in Cosmic C are case sensitive.<\/li>\n<li style=\"text-align: justify\">Functions with no arguments must not have empty argument areas. For example, you cannot write:\n<pre><em style=\"color: #0000ff;background-color: #eeeeee;font-family: 'Courier 10 Pitch', Courier, monospace;font-size: 0.9em\">void setup (); <\/em><\/pre>\n<p>You should write it as:<\/p>\n<pre><span style=\"color: #0000ff\"><em style=\"font-size: 0.95em\">void setup (void);<\/em><\/span><\/pre>\n<\/li>\n<\/ul>\n<ul style=\"text-align: justify\">\n<li>Definitions and constants can be declared as with any C compiler.<\/li>\n<li>Wherever there are flags, you need to be careful. You should check and clear flags even if it is cleared by hardware. For instance, when reading ADC, the ADC<strong><em> End-Of-Conversion (EOC)<\/em><\/strong> flag is automatically cleared but still in the code you should check and clear it.\u00a0<em style=\"color: #0000ff;background-color: #eeeeee;font-family: 'Courier 10 Pitch', Courier, monospace;font-size: 0.9em\">ADC1_ClearFlag(ADC1_FLAG_EOC);\u00a0<\/em>Flags are so important that unless you check and clear them appropriately, you may not get the right result from your code. Personally, I didn\u2019t care much until I got myself into trouble.<\/li>\n<\/ul>\n<ul style=\"text-align: justify\">\n<li>You can mix assembly codes with your C code to enhance performance and optimization. However, you need to have sound knowledge of the assembly instructions. This is a rare requirement. The delay library, for instance, uses no operation assembly instruction to achieve delays. This is written as shown:\n<pre><span style=\"color: #0000ff\"><em>_asm (\"nop\");\u00a0<\/em><\/span><\/pre>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify\">Empty loops are ignored by the compiler as a part of code optimization.<\/li>\n<li style=\"text-align: justify\">Long ago, Atmel (now Microchip) published a document regarding ways to efficiently optimize C coding. This document holds true for most microcontrollers. For example, in that document it is stated that a decrementing <strong><em>do-while<\/em><\/strong> loop is much more faster and code efficient than an incrementing<strong><em> do-while<\/em><\/strong> You can apply the methods presented there and other similar tricks with STM8 microcontrollers too. The document can be found here:<br \/>\n<a href=\"http:\/\/www.atmel.com\/images\/doc8453.pdf\">http:\/\/www.atmel.com\/images\/doc8453.pdf<\/a><\/li>\n<li style=\"text-align: justify\">Though I don\u2019t feel it as a necessity and don\u2019t recommend it, you can avoid using the SPL and still code by raw register level access. For example, you can blink a LED with the following code:\n<pre><span style=\"color: #0000ff\"><em>#include \"stm8s.h\"\r\n\r\n\r\n<\/em><em>void main (void)\r\n<\/em><em>{\r\n\u00a0 \u00a0 \u00a0GPIOD-&gt;DDR |= 0x01;\u00a0\r\n<\/em><em>\u00a0 \u00a0 \u00a0GPIOD-&gt;CR1 |= 0x01;\r\n\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>     for(;;) \r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>     {<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0GPIOD-&gt;ODR ^= (1 &lt;&lt; 0);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0delay_ms(100);<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>\u00a0 \u00a0 \u00a0};<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>}<\/em><\/span><\/pre>\n<\/li>\n<\/ul>\n<ul style=\"text-align: justify\">\n<li>Don\u2019t mess with configuration (fuse) bits unless needed. Most of the times you will never have to deal with them. <strong><em>AFRs <\/em><\/strong>are used when remapping is needed or to enable special GPIO functionality. These will be of most importance.<\/li>\n<\/ul>\n<ul>\n<li>Bitwise and logic operations are useful. Not only they are fast, they just deal with the designated bits only. SPL has support for such operations but it is still better to know them. Here are some common operations:<\/li>\n<\/ul>\n<pre><span style=\"color: #0000ff\"><em>#define bit_set(reg, bit_val)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 reg |= (1 &lt;&lt; bit_val)\u00a0\u00a0\u00a0\r\n\/\/For setting a bit of a register\u00a0\u00a0\u00a0\u00a0 \r\n\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define bit_clr(reg, bit_val)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 reg &amp;= (~(1 &lt;&lt; bit_val))\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n\/\/For clearing a bit of a register\r\n\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define bit_tgl(reg, bit_val)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 reg ^= (1 &lt;&lt; bit_val)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n\/\/For toggling a bit of a register\r\n\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define get_bit(reg, bit_val)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(reg &amp; (1 &lt;&lt; bit_val))\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n\/\/For extracting the bit state of a register\r\n\r\n<\/em><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><em>#define get_reg(reg, msk)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  (reg &amp; msk)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n\/\/For extracting the states of masked bits of a register\r\n<\/em><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h3>Unlocking a Locked STM8 Chip<\/h3>\n<p style=\"text-align: justify\">If you have accidentally locked a STM8 chip by setting the <strong><em>Readout Protection<\/em><\/strong> configuration bit and no longer able to use it, you can unlock it easily.<\/p>\n<p style=\"text-align: justify\">When you lock a chip, the programmer interface will give you a warning notification. If you retry to reprogram\/erase a locked chip you\u2019ll get an error like this:<\/p>\n<p style=\"text-align: justify\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LOCKED.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13445\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/LOCKED.png\" alt=\"LOCKED\" width=\"526\" height=\"407\" \/><\/a><\/p>\n<p style=\"text-align: justify\">No matter what you do, you won\u2019t be able to use it.<\/p>\n<p style=\"text-align: justify\">To unlock, go to the light programmer interface of STVD and check the<strong><em> Unlock Device<\/em><\/strong> checkbox as shown below:<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Unlock.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13446\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2017\/04\/Unlock.png\" alt=\"Unlock\" width=\"529\" height=\"407\" \/><\/a><\/p>\n<p style=\"text-align: justify\">Also select <strong><em>Erase before Programming<\/em><\/strong> radio button because it is highly likely that your target chip is not empty. Now once you retry to reprogram, it will get unlocked.<\/p>\n<h3>Mastering C Language<\/h3>\n<p style=\"text-align: justify\">You need not to be a C whiz to work with microcontrollers but certain things will surely help you to resolve some critical problems with simple codes. You must check supported data types whenever you begin working in a new development environment and should always use unsigned-signed designations to avoid unnecessary mistakes. Likewise, variable size is also important. Pointer, structures, unions and arrays are helpful features of C-language. You must learn how to use and apply them successfully. Without these you can still work but things will look really dirty. When coding for a new work, you must try to settle what you wish from your system and how should it behave. There should be an organized workflow and thereby your code will automatically be formulated in a state-of-machine algorithm or as a real-time system. You must try to avoid delays and loops wherever possible. Try to avoid polling and use interrupt-based systems. This will make your device behave in real-time with zero latency. However, you must be careful in handling interrupts because interrupts within interrupts will cause your system to crash miserably. Functions make things modular and thus easy to modify or debug. Repeated tasks should be placed in functions. A blinking LED code may look simple and stupid but sometimes very useful for testing stuffs. Some basic knowledge on mathematics and algorithms are also requirements for becoming a good embedded-system specialist.<\/p>\n<h2>Epilogue<\/h2>\n<p style=\"text-align: justify\">In the end, I would like to share that my tiny raw-level knowledge and experiences with STM32s (<a href=\"http:\/\/embedded-lab.com\/blog\/stm32-tutorials\/\">http:\/\/embedded-lab.com\/blog\/stm32-tutorials\/<\/a>) earlier paid off handsomely. Due to that I was able to compiler this article decently and quickly. Personally, I feel that whosoever knows STM8 micros well will master STM32s and vice-versa because except the cores all hardware in both architectures are not just similar but same sometimes. This is for the first time I have admired STM\u2019s SPL. My experiences with STM32 SPL was not well as so I decided to go on my own. However, this time things were different. Things were joyful and less difficult.<\/p>\n<p style=\"text-align: justify\">I would like to thank a few people who influenced me in composing this article:<\/p>\n<ul style=\"text-align: justify\">\n<li>Firstly, my friends and acquaintances. I wanted to help them out and that drove me to dig things deep.<\/li>\n<li><strong> Ben Ryves<\/strong> (<a href=\"http:\/\/benryves.com\/tutorials\/stm8s-discovery\/\">benryves.com\/tutorials\/stm8s-discovery\/<\/a>).<\/li>\n<\/ul>\n<p style=\"text-align: justify\">Though his methods are different than mine, his article guided me a lot in the beginning. It is perhaps the most popular site for tutorials on STM8s and well organized. He used STM8S105 Discovery.<\/p>\n<ul style=\"text-align: justify\">\n<li><strong>Mark Stevens<\/strong> (<a href=\"http:\/\/blog.mark-stevens.co.uk\">http:\/\/blog.mark-stevens.co.uk<\/a>)<\/li>\n<\/ul>\n<p style=\"text-align: justify\">His tutorials on STM8 are not based on SPL. He showed stuffs with raw-level register access and with IAR compiler. Still his blog is informative.<\/p>\n<ul style=\"text-align: justify\">\n<li><a href=\"http:\/\/www.emcu.it\/\">http:\/\/www.emcu.it\/<\/a>. This Italian site was helpful in getting some early info.<\/li>\n<li>STMicroelectronics team for releasing the STM8CubeMX during my writeup.<\/li>\n<li>Cosmic team for freeing up their C compiler.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">I spent nearly three months straight putting together all these things and at present, I must say that I have great expectations from STM8 microcontrollers.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>A sequel of this post can be found <a href=\"http:\/\/embedded-lab.com\/blog\/continuing-stm8-microcontroller-expedition\/\" target=\"_blank\">here<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Happy coding.<\/p>\n<p style=\"text-align: justify\"><em>Author: Shawon M. Shahryiar<\/em><\/p>\n<p style=\"text-align: justify\"><a href=\"https:\/\/www.facebook.com\/groups\/microarena\/\"><em>https:\/\/www.facebook.com\/groups\/microarena<\/em><\/a><\/p>\n<p style=\"text-align: justify\"><a href=\"https:\/\/www.facebook.com\/MicroArena?ref=hl\"><em>https:\/\/www.facebook.com\/MicroArena<\/em><\/a><em>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 24.04.2017<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>STM8 microcontrollers are 8-bit general purpose microcontrollers from STMicroelectronics (STM). STM is famous mainly for its line of 32-bit ARM Cortex microcontrollers \u2013 the STM32s. STM8 microcontrollers are rarely discussed in that context. However, STM8 MCUs are robust and most importantly they come packed with lots of hardware features. Except for the ARM core, 32-bit architecture, performance and some minor differences, STM8s have many peripheral similarities with STM32s. In my opinion, STM8s are equally or sometimes more matched than the popular PICs and AVRs in all areas. Unlike PICs and AVRs however, I have seen STM8s mostly in various SMD<\/p>\n","protected":false},"author":5,"featured_media":13305,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[367,1638,1466],"tags":[1646,1645,1644,850],"class_list":["post-13303","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mcu-develeopment-tools","category-stm8","category-tutorials","tag-8-bit-microcontroller","tag-stm8","tag-stm8s","tag-stmicroelectronics"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/13303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=13303"}],"version-history":[{"count":66,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/13303\/revisions"}],"predecessor-version":[{"id":14238,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/13303\/revisions\/14238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/13305"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=13303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=13303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=13303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}