{"id":14763,"date":"2021-12-03T04:15:37","date_gmt":"2021-12-03T09:15:37","guid":{"rendered":"https:\/\/embedded-lab.com\/blog\/?p=14763"},"modified":"2023-09-06T01:36:09","modified_gmt":"2023-09-06T05:36:09","slug":"exploring-stc-8051-microcontrollers-coding","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/exploring-stc-8051-microcontrollers-coding\/","title":{"rendered":"Exploring STC 8051 Microcontrollers &#8211; Coding"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About STC8A8K64S4A12\nMicrocontroller and its Development Board<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"text-align:left\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is the continuation of my first post on STC 8051 Microcontrollers <a href=\"https:\/\/embedded-lab.com\/blog\/exploring-stc-8051-microcontrollers\/\">here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Many Chinese microcontroller manufacturers develop awesome and cheap general-purpose MCUs using the popular 8051 architecture. There are many reasons for that but most importantly the 8051 architecture is a very common one that has been around for quite a long time. Secondly, manufacturing MCUs with 8051 DNA allows manufacturers to focus less on developing their own proprietary core and to give more effort in adding features. Holtek, Nuvoton, STC, etc are a few manufacturers to name. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"250\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Untitled.jpg\" alt=\"\" class=\"wp-image-14769\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Untitled.jpg 250w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Untitled-150x150.jpg 150w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Untitled-90x90.jpg 90w\" sizes=\"auto, (max-width: 250px) 100vw, 250px\" \/><\/figure><\/div>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Rather than mastering a good old 8051-based microcontroller like the AT89C52 or similar, it is better to learn something new that has many similarities with that architecture. As mentioned earlier, STC has various flavour of microcontrollers based on 8051 cores. STC8A8K64S4A12 of the STC8 family is one such example. Here for this documentation, I will be using this MCU specifically. In short, it is a beast as it offers lot of additional hardware that are usually not seen in regular 8051s. Some key features are listed below. The red box highlights the STC8A8K64S4A12 micro in particular.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"680\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image.png\" alt=\"\" class=\"wp-image-14764\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-580x420.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-768x556.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">I chose STC8A8K64S4A12 for this tutorial for all of its rich features. My favourite features include 12-bit ADC, multiple timers, reduced EMI feature and PCA module.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"617\" height=\"739\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-1.png\" alt=\"\" class=\"wp-image-14765\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-1.png 617w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-1-543x650.png 543w\" sizes=\"auto, (max-width: 617px) 100vw, 617px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see the naming convention of STC microcontrollers. The figure below shows us what the name of a STC8 micro means:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"565\" height=\"499\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-2.png\" alt=\"\" class=\"wp-image-14766\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The name STC8A8K64S4A12 is quite a mouthful\nand given the nomenclature info, STC8A8K64SA412 is actually a STC8 series micro\nwith on-chip 12-bit ADC, 8kB SRAM, 64kB code space and 4 hardware serial (UART)\nports. Apart from these hardware thingies, the naming convention does not\nreveal other cool features, for if it had been so, the device name would be\neven longer.&nbsp; &nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Initially I wanted to make this tutorial with the STC15F(L)204EA microcontroller but later I changed my mind because STC8A8K64S4A12 is much richer in hardware peripheral terms than STC15F(L)204EA, not to mention several similar hardware are present in both models of microcontroller. Since I planned to use STC8A8K64S4A12, I waited for the arrival of the board shown below before completing this work. Although this development board is an official board, it has been smartly designed for fast learning and rapid deployment of projects. As a matter of fact, if someone learns about this micro with this board, he\/she will rule over all of STC\u2019s 8051-based line-up.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"931\" height=\"602\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-3.png\" alt=\"\" class=\"wp-image-14767\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-3.png 931w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-3-580x375.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-3-768x497.png 768w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This board has the following schematic and it will be needed throughout this tutorial. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"624\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-4.png\" alt=\"\" class=\"wp-image-14768\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-4.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-4-580x385.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-4-768x510.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">On board, we have connectors for OLED display, GLCD, LCD, TFT Display, nRF24L01 transceiver, ESP8266 Wi-Fi module, etc. We also have on board W25x16 flash, 24C04 EEPROM, RS485 communication bridge and a CH340G USB-serial converter that doubles as an on-board programmer. <\/p>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">My Customized BSP<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To deal with the vast array of peripherals of STC8A8K64S4A12,\nI needed something to quickly deploy projects without going through the\nregisters every time. Having gotten the idea of <strong>Board Support Package<\/strong>\n(BSP) while working with Nuvoton N76E003, it was time for me to develop\nsomething similar for STC micros here as officially STC does not have such\nbeautiful software implementation for their microcontrollers. However, STC does\nprovide lot of both C and assembly language examples in their reference manuals\nand programmer GUI unlike other manufacturers. Those examples, though helpful,\ndo not fit in all possible scenarios and often incomplete in terms of meaning.\nBy having a BSP, we can use our micro\u2019s hardware peripherals more efficiently\nwith ease and in a wide variety of ways. We would no longer need to create and\ncall functions for hardware peripherals every time. Nuvoton, TI,\nSTMicroelectronics, Silicon Labs and many other mainstream microcontroller\nmanufacturers are tooling various methods to reduce coding efforts and aid in\nrapid code development. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is not an easy task to go through an\nentire reference manual, reading and trying out everything one-by-one. However,\nI had to do it no matter how painstaking job it was. This is because firstly, I\nhate setting registers repetitively every single time when I want to make a new\nproject and secondly, I want to make work easy so that less time, resource and\neffort are spent. I also have a tendency to forget things quickly. This solution will be as such that it can be\nmodified easily and ported for other STC microcontrollers as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I have developed my BSP for STC8A8K64S4A12 in an orderly fashion. There are header files for each hardware peripherals that contain all necessary functions and definitions. An example of STC8A8K64S4A12\u2019s watchdog timer\u2019s header file is shown below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> &nbsp;&nbsp;&nbsp;&nbsp;Watchdog&nbsp;Overflow&nbsp;Time&nbsp;=&nbsp;((12&nbsp;*&nbsp;32768&nbsp;*&nbsp;2^(WDT_PS&nbsp;+&nbsp;1))&nbsp;\/&nbsp;Sysclk)<br> *\/<br> #define&nbsp;WDT_div_factor_2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;WDT_div_factor_4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;WDT_div_factor_8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> #define&nbsp;WDT_div_factor_16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x03<br> #define&nbsp;WDT_div_factor_32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04<br> #define&nbsp;WDT_div_factor_64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x05<br> #define&nbsp;WDT_div_factor_128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x06<br> #define&nbsp;WDT_div_factor_256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x07<br> &nbsp;<br> #define&nbsp;WDT_set_prescalar(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_CONTR&nbsp;&amp;=&nbsp;0xF8;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_CONTR&nbsp;|=&nbsp;value;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> \/\/CNT_mode<br> #define&nbsp;WDT_stop_counting_in_idle_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;WDT_continue_counting_in_idle_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x08<br> &nbsp;<br> #define&nbsp;WDT_start&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(WDT_CONTR,&nbsp;5)<br> &nbsp;<br> #define&nbsp;WDT_get_overflow_flag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_bit(WDT_CONTR,&nbsp;7)<br> #define&nbsp;WDT_clear_overflow_flag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(WDT_CONTR,&nbsp;7)<br> &nbsp;<br> #define&nbsp;WDT_reset&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(WDT_CONTR,&nbsp;4)<br> &nbsp;<br> #define&nbsp;WDT_clear&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_CONTR&nbsp;=&nbsp;0x00;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;WDT_setup(CNT_mode,&nbsp;PS)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_clear;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_CONTR&nbsp;|=&nbsp;CNT_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_set_prescalar(PS);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0) <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see what the registers and their settings look like:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"230\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-5.png\" alt=\"\" class=\"wp-image-14771\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-5.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-5-580x142.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-5-768x188.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"465\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-6.png\" alt=\"\" class=\"wp-image-14772\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-6.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-6-580x287.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-6-768x380.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"133\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-7.png\" alt=\"\" class=\"wp-image-14773\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-7.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-7-580x82.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-7-768x109.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As we can see there are\na whole bunch of settings that need attention while using. This is perhaps the\neasiest way to show what I wanted to achieve.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Please note that I have tested most of the\nstuffs that STC8A8K64S4A12 could offer. I tested them rigorously and with\nconfidence I can say all of these functions have been found to be okay. Being the sole\ndeveloper, I did my checks as much as possible but there could be unforeseen\nbugs that I may have overlooked. A typical case could be wrong function naming.\nThis is so because during development of these BSP files I made several changes\nwhen new issues appeared. Therefore, I would like to request readers to report\nany issue when discovered and I would also like readers to read the reference\nmanual of STC8 series completely if possible. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The examples presented in this document are based on my custom BSP and I believe that the journey with STC microcontroller supported by my BSP would be a joyful one. <\/p>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">General Purpose Input-Output (GPIO)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The very first thing to do with a new microcontroller is to play with its GPIOs and this is what we will begin with. STC micros are based on 8051 architecture and so it is no surprise that the GPIOs will have similarities with typical 8051s. GPIOs of STC micros are essentially same as those of Nuvoton N76E003. Those who have seen my past <a href=\"http:\/\/embedded-lab.com\/blog\/category\/nuvoton\/\">Nuvoton tutorials<\/a> will find similarities. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"423\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-8.png\" alt=\"\" class=\"wp-image-14774\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-8.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-8-580x261.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-8-768x346.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"748\" height=\"261\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-9.png\" alt=\"\" class=\"wp-image-14775\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-9.png 748w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-9-580x202.png 580w\" sizes=\"auto, (max-width: 748px) 100vw, 748px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">BSP<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/P00<br> #define&nbsp;P00_quasi_bidirectional_mode&nbsp;&nbsp;&nbsp;&nbsp;do{bit_clr(P0M1,&nbsp;0);&nbsp;bit_clr(P0M0,&nbsp;0);}while(0)&nbsp;<br> #define&nbsp;P00_push_pull_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P00_quasi_bidirectional_mode;&nbsp;bit_clr(P0M1,&nbsp;0);&nbsp;bit_set(P0M0,&nbsp;0);}while(0)<br> #define&nbsp;P00_input_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P00_quasi_bidirectional_mode;&nbsp;bit_set(P0M1,&nbsp;0);&nbsp;bit_clr(P0M0,&nbsp;0);}while(0)<br> #define&nbsp;P00_open_drain_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P00_quasi_bidirectional_mode;&nbsp;bit_set(P0M1,&nbsp;0);&nbsp;bit_set(P0M0,&nbsp;0);}while(0)<br> &nbsp;<br> #define&nbsp;P00_pull_up_enable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{bit_set(P_SW2,&nbsp;7);&nbsp;bit_set(P0PU,&nbsp;0);&nbsp;bit_clr(P_SW2,&nbsp;7);}while(0)&nbsp;<br> #define&nbsp;P00_pull_up_disable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{bit_set(P_SW2,&nbsp;7);&nbsp;bit_clr(P0PU,&nbsp;0);&nbsp;bit_clr(P_SW2,&nbsp;7);}while(0)&nbsp;<br> &nbsp;<br> #define&nbsp;P00_schmitt_trigger_enable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{bit_set(P_SW2,&nbsp;7);&nbsp;bit_set(P0NCS,&nbsp;0);&nbsp;bit_clr(P_SW2,&nbsp;7);}while(0)&nbsp;<br> #define&nbsp;P00_schmitt_trigger_disable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{bit_set(P_SW2,&nbsp;7);&nbsp;bit_clr(P0NCS,&nbsp;0);&nbsp;bit_clr(P_SW2,&nbsp;7);}while(0)&nbsp;<br> &nbsp;<br> #define&nbsp;P00_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P0,&nbsp;0)<br> #define&nbsp;P00_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P0,&nbsp;0)<br> #define&nbsp;P00_toggle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_tgl(P0,&nbsp;0)<br> #define&nbsp;P00_get_input&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_bit(P0,&nbsp;0) <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(P52_get_input&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_input_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_pull_up_enable;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"439\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-10.png\" alt=\"\" class=\"wp-image-14776\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-10.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-10-580x271.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-10-768x359.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Like always this first example is a simple variable flash rate LED flasher. Onboard LED connected to P5.5 and onboard push button connected to P5.2 are used. The board\u2019s schematic shows us that P5.2\u2019s push button must have an internal pull-up to properly function because it is not tied to any external pull-up resistor and P5.5\u2019s LED must be configured as an open-drain output. These are configured so in the setup function.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_input_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_pull_up_enable;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the main loop, P5.5\u2019s LED state is toggled every 200ms. If P5.2\u2019s push button is pressed, P5.2\u2019s state changes and so additional 400ms delay is added, making the total toggling delay 600ms.&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P55_toggle;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> if(P52_get_input&nbsp;==&nbsp;0)<br> {<br> &nbsp;&nbsp;&nbsp; delay_ms(400);<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> delay_ms(200); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note no clock settings are applied and the micro is running at default clock frequency of 24MHz.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"916\" height=\"653\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-11.png\" alt=\"\" class=\"wp-image-14777\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-11.png 916w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-11-580x413.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-11-768x547.png 768w\" sizes=\"auto, (max-width: 916px) 100vw, 916px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - GPIO Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/_uNaNCzJUwM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Clock System<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12\u2019s clock system is very straight forward. There are three available clock sources \u2013 two of which are internal. There is a high-precision 24MHz internal oscillator and a low accuracy internal 32kHz oscillator. Apart from these internal sources, we can also use external sources like external crystals or oscillators. The clock system block diagram is shown below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"323\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-12.png\" alt=\"\" class=\"wp-image-14779\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-12.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-12-580x200.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-12-768x264.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To set desired clock frequency, we have a\nclock divider block right after clock selection block. The final output from\nthe clock divider is the system clock that is feed to all peripherals. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can also get system clock output via another block of clock divider. The output can be turned off or extracted from either pin P5.4 or P1.6.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BSP<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define CLK_enable_IRC24_M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{ \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRC24MCR&nbsp;=&nbsp;0x80;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((IRC24MCR&nbsp;&amp;&nbsp;0x01)&nbsp;==&nbsp;FALSE);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_disable_IRC24_M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRC24MCR&nbsp;=&nbsp;0x00;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_enable_IRC32_k&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRC32KCR&nbsp;=&nbsp;0x80;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((IRC32KCR&nbsp;&amp;&nbsp;0x01)&nbsp;==&nbsp;FALSE);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_disable_IRC32_k&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IRC32KCR&nbsp;=&nbsp;0x00;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_enable_EXT_clock_signal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XOSCCR&nbsp;=&nbsp;0x80;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((XOSCCR&nbsp;&amp;&nbsp;0x01)&nbsp;==&nbsp;FALSE);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_disable_EXT_clock_signal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XOSCCR&nbsp;=&nbsp;0x00;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_enable_EXT_crystal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XOSCCR&nbsp;=&nbsp;0xC0;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((XOSCCR&nbsp;&amp;&nbsp;0x01)&nbsp;==&nbsp;FALSE);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;CLK_disable_EXT_crystal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_disable_EXT_clock_signal<br> &nbsp;<br> \/\/sys_div&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;CLK_sys_clk_scalar(div)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLKDIV&nbsp;=&nbsp;div<br> &nbsp;<br> \/\/src&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;IRC_24M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;EXT_xtal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;EXT_clk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<br> #define&nbsp;IRC_32k&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3<br> &nbsp;<br> #define&nbsp;CLK_set_sys_clk_source_and_div(clk_src,&nbsp;div)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(clk_src&nbsp;==&nbsp;IRC_32k)&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_enable_IRC32_k;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(clk_src&nbsp;==&nbsp;EXT_clk)&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_enable_EXT_clock_signal;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(clk_src&nbsp;==&nbsp;EXT_xtal)&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_enable_EXT_crystal;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_enable_IRC24_M;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_sys_clk_scalar(div);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CKSEL&nbsp;=&nbsp;clk_src;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> \/\/mclk_div<br> #define&nbsp;MCLK_SYSCLK_no_output&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;MCLK_SYSCLK_div_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10<br> #define&nbsp;MCLK_SYSCLK_div_2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x30<br> #define&nbsp;MCLK_SYSCLK_div_4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x50<br> #define&nbsp;MCLK_SYSCLK_div_8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x70<br> #define&nbsp;MCLK_SYSCLK_div_16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x90<br> #define&nbsp;MCLK_SYSCLK_div_32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xB0<br> #define&nbsp;MCLK_SYSCLK_div_64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD0<br> #define&nbsp;MCLK_SYSCLK_div_128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xF0<br> &nbsp;<br> #define&nbsp;CLK_MCLK_scalar(div)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CKSEL&nbsp;|=&nbsp;div<br> &nbsp;<br> \/\/mclk_pin_id<br> #define&nbsp;MCLK_out_P54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;MCLK_out_P16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> &nbsp;<br> #define&nbsp;CLK_set_MCLK(div,&nbsp;pin_id)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_MCLK_scalar(div);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(pin_id&nbsp;==&nbsp;MCLK_out_P16)&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(CKSEL,&nbsp;3);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(CKSEL,&nbsp;3);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;CLK_set_sys_clk(sys_src,&nbsp;sys_div,&nbsp;mclk_div,&nbsp;mclk_pin_id)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk_source_and_div(sys_src,&nbsp;sys_div);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_set_MCLK(mclk_div,&nbsp;mclk_pin_id);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0) <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;toggle(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;4,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;6,&nbsp;MCLK_SYSCLK_div_8,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;24,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_32k,&nbsp;1,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle();<br> }<br> &nbsp;<br> void&nbsp;toggle(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;10;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"930\" height=\"481\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-13.png\" alt=\"\" class=\"wp-image-14780\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-13.png 930w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-13-580x300.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-13-768x397.png 768w\" sizes=\"auto, (max-width: 930px) 100vw, 930px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is yet another oversimplified example. Again,\nonboard LED toggling code is presented here. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firstly, we need a LED toggling function because we want to visually observe what is happening. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void toggle(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;10;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">P5.5\u2019s LED is toggled 10 times. Note that although a 60ms delay is used between toggles, it will not be 60ms always as delays are dependent on system clock frequency. This will do the trick.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, different clock settings are applied and the LED toggling is observed.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M, 4, MCLK_SYSCLK_div_1, MCLK_out_P54);<br> toggle();<br> &nbsp;&nbsp;&nbsp;<br> CLK_set_sys_clk(IRC_24M,&nbsp;6,&nbsp;MCLK_SYSCLK_div_8,&nbsp;MCLK_out_P54);<br> toggle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> CLK_set_sys_clk(IRC_24M,&nbsp;24,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> toggle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> CLK_set_sys_clk(IRC_32k,&nbsp;1,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> toggle(); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With different system clock speeds, the onboard LED toggling rates change. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"428\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-14.png\" alt=\"\" class=\"wp-image-14781\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-14.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-14-580x269.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-14-768x357.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Clock System Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/jNwxc3bJ1C8?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Interfacing 2&#215;16 LCD<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After having both clock system and GPIO mastered, the next important thing to do is to drive an ordinary alphanumerical LCD or simply text LCD. This is very important as text LCDs are great tools for quickly and visually displaying information.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"703\" height=\"536\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Img-1.jpg\" alt=\"\" class=\"wp-image-14783\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Img-1.jpg 703w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Img-1-580x442.jpg 580w\" sizes=\"auto, (max-width: 703px) 100vw, 703px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">LCD.h <\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define LCD_GPIO_init()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P35_push_pull_mode; \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P36_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P37_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P04_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P05_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P06_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P07_push_pull_mode;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> #define&nbsp;LCD_RS_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P35_high<br> #define&nbsp;LCD_RS_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P35_low<br> &nbsp;<br> #define&nbsp;LCD_RW_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P36_high<br> #define&nbsp;LCD_RW_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P36_low<br> &nbsp;<br> #define&nbsp;LCD_EN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P37_high<br> #define&nbsp;LCD_EN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P37_low<br> &nbsp;<br> #define&nbsp;LCD_DB4_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P04_high<br> #define&nbsp;LCD_DB4_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P04_low<br> &nbsp;<br> #define&nbsp;LCD_DB5_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P05_high<br> #define&nbsp;LCD_DB5_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P05_low<br> &nbsp;<br> #define&nbsp;LCD_DB6_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P06_high<br> #define&nbsp;LCD_DB6_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P06_low<br> &nbsp;<br> #define&nbsp;LCD_DB7_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P07_high<br> #define&nbsp;LCD_DB7_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P07_low<br> &nbsp;<br> #define&nbsp;clear_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;goto_home&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> &nbsp;<br> #define&nbsp;cursor_direction_inc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_direction_dec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x00)<br> #define&nbsp;display_shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x01)<br> #define&nbsp;display_no_shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x00)<br> &nbsp;<br> #define&nbsp;display_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x04)<br> #define&nbsp;display_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x00)<br> #define&nbsp;blink_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x01)<br> #define&nbsp;blink_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x00)<br> &nbsp;<br> #define&nbsp;_8_pin_interface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x10)<br> #define&nbsp;_4_pin_interface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> #define&nbsp;_2_row_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x08)<br> #define&nbsp;_1_row_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> #define&nbsp;_5x10_dots&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x40)<br> #define&nbsp;_5x7_dots&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> &nbsp;<br> #define&nbsp;DAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;<br> void&nbsp;LCD_init(void);<br> void&nbsp;LCD_send(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;mode);<br> void&nbsp;LCD_4bit_send(unsigned&nbsp;char&nbsp;lcd_data);<br> void&nbsp;LCD_putstr(char&nbsp;*lcd_string);<br> void&nbsp;LCD_putchar(char&nbsp;char_data);<br> void&nbsp;LCD_clear_home(void);<br> void&nbsp;LCD_goto(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos);<br> void&nbsp;toggle_EN_pin(void); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">LCD.c <\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"LCD.h\"<br> &nbsp;<br> void&nbsp;LCD_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_GPIO_init();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_RW_LOW;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_RS_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle_EN_pin();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(0x33,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(0x32,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((_4_pin_interface&nbsp;|&nbsp;_2_row_display&nbsp;|&nbsp;_5x7_dots),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((display_on&nbsp;|&nbsp;cursor_off&nbsp;|&nbsp;blink_off),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((clear_display),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((cursor_direction_inc&nbsp;|&nbsp;display_no_shift),&nbsp;CMD);<br> }<br> &nbsp;<br> void&nbsp;LCD_send(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;mode)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(mode)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;DAT:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_RS_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;CMD:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_RS_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_4bit_send(value);<br> }<br> &nbsp;<br> void&nbsp;LCD_4bit_send(unsigned&nbsp;char&nbsp;lcd_data)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x80)&nbsp;&gt;&gt;&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB7_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB7_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x40)&nbsp;&gt;&gt;&nbsp;6);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB6_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB6_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x20)&nbsp;&gt;&gt;&nbsp;5);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB5_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB5_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x10)&nbsp;&gt;&gt;&nbsp;4);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB4_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB4_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle_EN_pin();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x08)&nbsp;&gt;&gt;&nbsp;3);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB7_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB7_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x04)&nbsp;&gt;&gt;&nbsp;2);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB6_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB6_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x02)&nbsp;&gt;&gt;&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB5_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB5_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;((lcd_data&nbsp;&amp;&nbsp;0x01));<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(temp)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB4_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_DB4_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle_EN_pin();<br> }<br> &nbsp;<br> void&nbsp;LCD_putstr(char&nbsp;*lcd_string)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;do<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_send(*lcd_string++,&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;}while(*lcd_string&nbsp;!=&nbsp;'\\0');<br> }<br> &nbsp;<br> void&nbsp;LCD_putchar(char&nbsp;char_data)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(char_data,&nbsp;DAT);<br> }<br> &nbsp;<br> void&nbsp;LCD_clear_home(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(clear_display,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(goto_home,&nbsp;CMD);<br> }<br> &nbsp;<br> void&nbsp;LCD_goto(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(y_pos&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_send((0x80&nbsp;|&nbsp;x_pos),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_send((0x80&nbsp;|&nbsp;0x40&nbsp;|&nbsp;x_pos),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;toggle_EN_pin(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_EN_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(2);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_EN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(2);<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">lcd_print.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define no_of_custom_symbol&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;array_size_per_symbol&nbsp;&nbsp;&nbsp;8<br> #define&nbsp;array_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(array_size_per_symbol&nbsp;*&nbsp;no_of_custom_symbol)<br> &nbsp;<br> void&nbsp;load_custom_symbol(void);<br> void&nbsp;print_symbol(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;symbol_index);<br> void&nbsp;print_C(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;int&nbsp;value);<br> void&nbsp;print_I(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value);<br> void&nbsp;print_D(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;int&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points);<br> void&nbsp;print_F(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;float&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">lcd_print.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"lcd_print.h\"<br> &nbsp;<br> void&nbsp;load_custom_symbol(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;unsigned&nbsp;char&nbsp;custom_symbol[array_size]&nbsp;=<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x06,&nbsp;0x09,&nbsp;0x09,&nbsp;0x06,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(0x40,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;&nbsp;array_size;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_send(custom_symbol[s],&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(0x80,&nbsp;CMD);<br> }<br> &nbsp;<br> void&nbsp;print_symbol(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;symbol_index)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(symbol_index,&nbsp;DAT);<br> }<br> &nbsp;<br> void&nbsp;print_C(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;int&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;ch[5]&nbsp;=&nbsp;{0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;'\\0'};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[0]&nbsp;=&nbsp;0x2D;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;-value;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[0]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&gt;&nbsp;99)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;999))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;((value&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;9)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;99))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;0)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;9))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(ch);<br> }<br> &nbsp;<br> void&nbsp;print_I(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;ch[7]&nbsp;=&nbsp;{0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;'\\0'};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[0]&nbsp;=&nbsp;0x2D;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;-value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[0]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&gt;&nbsp;9999)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;((value&nbsp;\/&nbsp;10000)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;10000)\/&nbsp;1000)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[4]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[5]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;999)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;9999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;10000)\/&nbsp;1000)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[4]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[5]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;99)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[4]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[5]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;9)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;99))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;(((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[4]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[5]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[4]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[5]&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(ch);<br> }<br> &nbsp;<br> void&nbsp;print_D(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;int&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;ch[5]&nbsp;=&nbsp;{0x2E,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20,&nbsp;0x20};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ch[1]&nbsp;=&nbsp;((value&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(points&nbsp;&gt;&nbsp;1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[2]&nbsp;=&nbsp;(((value&nbsp;\/&nbsp;10)&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(points&nbsp;&gt;&nbsp;1)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch[3]&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(ch);<br> }<br> &nbsp;<br> void&nbsp;print_F(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;float&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;tmp&nbsp;=&nbsp;0x00000000;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;print_I(x_pos,&nbsp;y_pos,&nbsp;tmp);<br> &nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;((value&nbsp;-&nbsp;tmp)&nbsp;*&nbsp;1000);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;-tmp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;-value;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(0x2D);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(0x20);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&gt;=&nbsp;10000)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;100000))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_D((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;1000)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;10000))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_D((x_pos&nbsp;+&nbsp;5),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;100)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;1000))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_D((x_pos&nbsp;+&nbsp;4),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;10)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;100))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_D((x_pos&nbsp;+&nbsp;3),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(value&nbsp;&lt;&nbsp;10)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_D((x_pos&nbsp;+&nbsp;2),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;show_value(unsigned&nbsp;char&nbsp;value);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;txt1[]&nbsp;=&nbsp;{\"MICROARENA\"};<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;txt2[]&nbsp;=&nbsp;{\"SShahryiar\"};<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;txt3[]&nbsp;=&nbsp;{\"STC8A&nbsp;Series\"};<br> &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;txt4[]&nbsp;=&nbsp;{\"STC8A8K64S4A12\"};<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_clear_home();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(3,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(txt1);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(3,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(txt2);<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(4000);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_clear_home();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;&nbsp;12;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto((2&nbsp;+&nbsp;s),&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(txt3[s]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;&nbsp;14;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto((1&nbsp;+&nbsp;s),&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(txt4[s]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(4000);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_clear_home();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(3,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(txt1);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;show_value(s);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_init();<br> }<br> &nbsp;<br> void&nbsp;show_value(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ch&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;\/&nbsp;100)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;LCD_goto(6,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;LCD_putchar(ch);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(((value&nbsp;\/&nbsp;10)&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;LCD_goto(7,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;LCD_putchar(ch);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;&nbsp;LCD_goto(8,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;LCD_putchar(ch);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"301\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/LCD.png\" alt=\"\" class=\"wp-image-14784\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/LCD.png 741w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/LCD-580x236.png 580w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I have demoed this example in all of my past tutorials and so I won\u2019t be explaining it again. The only trick I would like to share is the fact that LCD datasheet documents state how to drive and initialize them. Thus, it is best to read datasheet and try to implement on own. It is very simple.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"563\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-15.png\" alt=\"\" class=\"wp-image-14785\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-15.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-15-580x354.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-15-768x469.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Alphanumerical LCD Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/-fOvuPexRKM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">External Interrupt (EXTI)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">STC microcontrollers have complex interrupt systems. Literally, all internal peripherals have interrupt capabilities. The block diagram of STC8A8K64S4A12\u2019s interrupt system shows this. In this section, we would see the use of external interrupt and in later examples we would see other interrupts.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">External interrupt has lot of uses in modern embedded systems. When coupled with low power consumption modes, external interrupts can be used to wake up a device and do certain task upon user\u2019s stimulated input via a button, keypad, touchpad, etc. External interrupts are what used in most portable battery-operated devices like computer mice, keyboards, remote controllers, etc. In such devices, precious battery energy is conserved by spending most time in low power modes and waiting for user interactions. When there is a user input, external interrupts are kicked in and some tasks are done quickly before returning to dormant low power modes.&nbsp;&nbsp;  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"488\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-16.png\" alt=\"\" class=\"wp-image-14787\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-16.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-16-580x301.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-16-768x399.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;<br> unsigned&nbsp;int&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;EXT_0_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;0&nbsp;<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;=&nbsp;9;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;EXT_1_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;2<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;=&nbsp;9;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;30000;&nbsp;i++);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;24,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;EXT_0_priority_0;<br> &nbsp;&nbsp;&nbsp;&nbsp;EXT_0_falling_edge_detection_only;<br> &nbsp;&nbsp;&nbsp;&nbsp;_enable_EXT_0_interrupt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;EXT_1_priority_1;<br> &nbsp;&nbsp;&nbsp;&nbsp;EXT_1_falling_edge_detection_only;<br> &nbsp;&nbsp;&nbsp;&nbsp;_enable_EXT_1_interrupt;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;_enable_global_interrupt;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"303\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic.png\" alt=\"\" class=\"wp-image-14788\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic.png 687w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-580x256.png 580w\" sizes=\"auto, (max-width: 687px) 100vw, 687px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First, let us see how we can enable external interrupt. Although external interrupts are GPIO input feature, we do not have to set external interrupt pins as inputs. This is done automatically and internally. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">8051 architecture allows prioritization of interrupts. This means that when there are simultaneous multiple interrupts, the interrupts are served in an orderly fashion according to the level of priority. STC8A8K64S4A12 has 22 interrupt sources and 4 levels of priority. Although it is not mandatory to set priority in most cases, some applications may need this feature. In this demo code, external interrupt 1 has higher priority than external interrupt 0 and so it would be processed first and then external interrupt 0 would be processed afterwards.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> EXT_0_priority_0;<br> EXT_0_falling_edge_detection_only;<br> _enable_EXT_0_interrupt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> EXT_1_priority_1;<br> EXT_1_falling_edge_detection_only;<br> _enable_EXT_1_interrupt;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> _enable_global_interrupt; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The next thing to do when setting external\ninterrupts is to let the MCU know which edges would trigger the interrupts.\nFinally, the interrupts are enabled along with global interrupt flag bit. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Like other examples onboard LED is used as an indicator. Inside each interrupt service routine, this LED is toggled but the rates of toggling are different. This would differentiate the interrupts.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void EXT_0_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> interrupt&nbsp;0&nbsp;<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;=&nbsp;9;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;EXT_1_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;2<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;=&nbsp;9;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;30000;&nbsp;i++);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When external interrupt 0 is triggered, the LED toggles fast and when external interrupt 1 is triggered, the LED toggles slowly. If external interrupt 0 is triggered while external interrupt 1 is being processed, external interrupt 0\u2019s task is processed after completing external interrupt 1\u2019s service routine. It is as if the MCU remembers the low priority interrupt after completing the higher priority interrupt. If external interrupt 1 is triggered while external interrupt 0 is being processed, the tasks in external interrupt 0 is temporarily suspended and external interrupt 1 is processed. After processing external interrupt 1, the suspended tasks of external interrupt 0 are resumed from where they were left.&nbsp; <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"1024\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-17-885x1024.png\" alt=\"\" class=\"wp-image-14789\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-17-885x1024.png 885w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-17-562x650.png 562w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-17-768x889.png 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-17.png 922w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12   External Interrupt Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/_dHcJr7-X0I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Analogue Comparator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Analogue comparator is not typically found in many microcontrollers but STC8A8K64S4A12 packs one analogue comparator. Though this comparator has limited options, it is still very useful and very easy to use. It can be used for low battery\/voltage detection, for comparing voltage levels, etc. The comparator can also be used to build simple switch mode power supplies and achieve feedback for various tasks. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"298\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-18.png\" alt=\"\" class=\"wp-image-14791\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-18.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-18-580x184.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-18-768x244.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The comparator block shows that P3.6 and P3.7 GPIO pins can be used as positive and negative inputs to the comparator unit. Alternatively, we can also use internal 1.344V voltage reference source or ADC input. The comparator output can be optionally filtered both using analogue and digital techniques. Lastly, we can retrieve comparator output via GPIO pins, flag and interrupts. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(CMP_get_comp_status&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;\\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MCLK_SYSCLK_no_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CMP_setup(CMP_positive_input_P37,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_negative_input_P36,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_output_disable,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_result_positive_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_enable_analog_filtering,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;CMP_enable;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"694\" height=\"296\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-1.png\" alt=\"\" class=\"wp-image-14792\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-1.png 694w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-1-580x247.png 580w\" sizes=\"auto, (max-width: 694px) 100vw, 694px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Analogue comparator is set up very easily by choosing the positive and negative input sources, output state, result state and filtering values. After setting all these, the comparator needs to be enabled. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">CMP_setup(CMP_positive_input_P37, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_negative_input_P36, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_output_disable, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_result_positive_output, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP_enable_analog_filtering, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04);<br> &nbsp;&nbsp;&nbsp; <br>CMP_enable; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here, we used the GPIO pins P3.6 and P3.7 as physical inputs to the comparator unit. We disabled the physical comparator output. The comparator will give output when positive input is larger than negative input. Lastly, 0.1\u00b5s analogue filtering is used along with some digital filtering by the addition of some latency. These filtering ensure that short-lived false signals are ignored. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the main loop, comparator\u2019s result flag status is continuously monitored. P5.5 onboard LED is turned on or off according to this flag\u2019s status.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> if(CMP_get_comp_status != 0x00)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> }<br> else<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"694\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-19.png\" alt=\"\" class=\"wp-image-14793\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-19.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-19-580x437.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-19-768x578.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Analogue Comparator Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/TuKMcBxPxf0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Analogue-to-Digital Converter (ADC)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12\u2019s 12-bit analogue-to-digital converter is an attractive feature. In the market, there are many enhanced 8051-core microcontrollers but most don\u2019t have any built-in ADC while some have low resolution ones. Like the analogue comparator, the ADC of STC8A8K64S4A12 is very simple and have limited basic options. The speed of this ADC can reach up to 800ksps. However, some care needs to be taken in order to maintain accuracy and consistency in measurements. For better results it is better to use well-calibrated external voltage reference source and additional filtering. These are well documented in STC8A8K64S4A12 reference manual and a sample diagram is shown below. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"889\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-20.png\" alt=\"\" class=\"wp-image-14796\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-20.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-20-580x549.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-20-768x727.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;ADC_count&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;float&nbsp;voltage&nbsp;=&nbsp;0.0;<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"CH0\/V:\");<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"CH1\/V:\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;ADC_count&nbsp;=&nbsp;ADC_get_result(CH0);<br> &nbsp;&nbsp;&nbsp;&nbsp;voltage&nbsp;=&nbsp;(((float)ADC_count&nbsp;*&nbsp;5.0)&nbsp;\/&nbsp;4095.0);<br> &nbsp;&nbsp;&nbsp;&nbsp;print_F(10,&nbsp;0,&nbsp;voltage,&nbsp;3);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ADC_count&nbsp;=&nbsp;ADC_get_result(CH1);<br> &nbsp;&nbsp;&nbsp;&nbsp;voltage&nbsp;=&nbsp;(((float)ADC_count&nbsp;*&nbsp;5.0)&nbsp;\/&nbsp;4095.0);<br> &nbsp;&nbsp;&nbsp;&nbsp;print_F(10,&nbsp;1,&nbsp;voltage,&nbsp;3);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;4,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P10_input_mode;<br> &nbsp;&nbsp;P11_input_mode;<br> &nbsp;<br> &nbsp;&nbsp;ADC_enable;<br> &nbsp;&nbsp;ADC_result_format_right_aligned;<br> &nbsp;&nbsp;ADC_set_conversion_speed(ADC_conv_256_CLKs);<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"325\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-21.png\" alt=\"\" class=\"wp-image-14797\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-21.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-21-580x201.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-21-768x266.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This ADC example utilizes polling method to\nget voltage reading from two ADC channels associated with pins P1.0 and P1.1. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">System clock setting is very important and this is so because AD conversion speed is dependent of this clock. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"338\" height=\"29\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-22.png\" alt=\"\" class=\"wp-image-14798\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">where <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"401\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-23.png\" alt=\"\" class=\"wp-image-14799\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-23.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-23-580x247.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-23-768x328.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;4,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In our case, the system clock is 6MHz and so\nFADC is 732Hz. Though the conversion speed is not pretty impressive, it\nis good enough for this example as sensing voltage variations are not rapid.\nNyquist criterion should always be kept in mind while sampling analogue signals.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">ADC Input pins need to declared as inputs.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P10_input_mode;<br> P11_input_mode; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ADC setup is pretty straight. All we need to do is to enable the ADC, select data output alignment and ADC clock speed prescalar.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ADC_enable;<br> ADC_result_format_right_aligned;<br> ADC_set_conversion_speed(ADC_conv_256_CLKs); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Data output can be either left-aligned or right-aligned. Right-aligned data is easy to read and that is why it my choice.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"433\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-24.png\" alt=\"\" class=\"wp-image-14800\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-24.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-24-580x267.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-24-768x354.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The ADC reading function reveals this fact.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned&nbsp;int&nbsp;ADC_get_result(unsigned&nbsp;char&nbsp;channel)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;unsigned&nbsp;int&nbsp;value&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ADC_set_channel(channel);<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ADC_start_conversion;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(!check_ADC_flag);<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_ADC_flag;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;((ADC_RES&nbsp;&lt;&lt;&nbsp;8)&nbsp;|&nbsp;ADC_RESL);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"> In the main, ADC channels 0 and 1 are read and their readings are converted to voltage. The voltages are shown on an LCD. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ADC_count = ADC_get_result(CH0);<br> voltage&nbsp;=&nbsp;(((float)ADC_count&nbsp;*&nbsp;5.0)&nbsp;\/&nbsp;4095.0);<br> print_F(10,&nbsp;0,&nbsp;voltage,&nbsp;3);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> ADC_count&nbsp;=&nbsp;ADC_get_result(CH1);<br> voltage&nbsp;=&nbsp;(((float)ADC_count&nbsp;*&nbsp;5.0)&nbsp;\/&nbsp;4095.0);<br> print_F(10,&nbsp;1,&nbsp;voltage,&nbsp;3);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> delay_ms(400); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ADC reading can be improved by applying\nseveral techniques like using filters, averaging technique and so on. Special\nattention is needed while designing PCBs in order to minimize cross-talk\nbetween channels and noise from onboard digital circuitry. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generally, AD conversion should be fast, ADC I\/O pins must be set in high impedance mode and AVCC to VCC voltage difference should not be more than 0.3V. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"384\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-25.png\" alt=\"\" class=\"wp-image-14801\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-25.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-25-580x242.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-25-768x320.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - ADC Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/i2MJ1OkbhwQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">IAP\/EEPROM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Storing calibration,\nconfiguration, setting data and some preset values are required in some devices\nand so they need to be stored in memories that can be later modified if needed\nor else left alone. For such cases, we would need either EEPROM or flash\nmemories. Like many modern microcontrollers, STC microcontrollers don\u2019t come\nequipped with built-in EEPROM memory but through coding we can store\naforementioned data in internal flash memory through IAP\/ISP technology. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Of course, there are ways to use external\nEEPROM and flash memories like AT24Cxx EERPOMS and W25X16 but that would\nrequire external wiring and the use of communication pins. Having flash\/EEPROM\nmemory embedded in the application chip allows us to simply avoid these and have\nour microcontroller ready for fast deployment. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this section, we would see how to use internal flash to store data.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"276\" height=\"312\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/EEPROM-Photo.jpg\" alt=\"\" class=\"wp-image-14803\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> # include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> #define&nbsp;BASE_ADDRESS&nbsp;&nbsp;0x0400<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"R&nbsp;Addr:\");<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"R&nbsp;Data:\");<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;i&nbsp;=&nbsp;IAP_read(BASE_ADDRESS);<br> &nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;print_I(11,&nbsp;0,&nbsp;BASE_ADDRESS);<br> &nbsp;&nbsp;print_C(14,&nbsp;1,&nbsp;i);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(2000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;if(i&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(0,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"Performing&nbsp;Erase\");<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"....\");<br> &nbsp;&nbsp;&nbsp;&nbsp;IAP_erase(BASE_ADDRESS);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1000);<br> &nbsp;&nbsp;}&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"W&nbsp;Addr:\");<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"W&nbsp;Data:\");<br> &nbsp;<br> &nbsp;&nbsp;i&nbsp;=&nbsp;(P1&nbsp;&amp;&nbsp;0x03);<br> &nbsp;&nbsp;IAP_write(BASE_ADDRESS,&nbsp;i);<br> &nbsp;&nbsp;print_I(11,&nbsp;0,&nbsp;BASE_ADDRESS);&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;print_C(14,&nbsp;1,&nbsp;i);<br> &nbsp;&nbsp;delay_ms(2000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"R&nbsp;Addr:\");<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"R&nbsp;Data:\");<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;i&nbsp;=&nbsp;IAP_read(BASE_ADDRESS);<br> &nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;print_I(11,&nbsp;0,&nbsp;BASE_ADDRESS);<br> &nbsp;&nbsp;print_C(14,&nbsp;1,&nbsp;i);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(2000);<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P10_input_mode;<br> &nbsp;&nbsp;P11_input_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"804\" height=\"294\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-2.png\" alt=\"\" class=\"wp-image-14804\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-2.png 804w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-2-580x212.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-2-768x281.png 768w\" sizes=\"auto, (max-width: 804px) 100vw, 804px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The code in this rudimentary\ndemo works by reading a single fixed location of internal flash, here 0x0400. An\nLCD display is used to show the read location and its content. If the content\nis 0 then an erase is performed because it is assumed to be empty. After\nperforming erase, the same location is written. The write value is generated by\nreading the logic states of the lowermost bits (i.e., bit 0 and 1) of P1 port.\nAfter writing, the location is read again as to check if the data is properly\nsaved. If the micro is reset or if there is a power-down, the saved data is retained,\nconfirming that indeed data has been preserved in the internal flash memory. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">IAP functionality utilizes the following three functions. As can be seen that these functions must follow a sequence operation in order to enable access to internal flash. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned char IAP_read(unsigned int address)<br> {<br> &nbsp; unsigned char value = 0x00;<br> &nbsp;<br> &nbsp; IAP_CONTR = IAP_WT;<br> &nbsp; IAP_CMD = IAP_read_command;<br> &nbsp; IAP_address(address);<br> &nbsp; IAP_trigger;<br> &nbsp; _nop_();<br> &nbsp; value = IAP_DATA;<br> &nbsp; IAP_clear;<br> &nbsp;<br> &nbsp; return value;<br> }<br> &nbsp;<br> void IAP_write(unsigned int address, unsigned char value)<br> {<br> &nbsp; IAP_CONTR = IAP_WT;<br> &nbsp; IAP_CMD = IAP_write_command;<br> &nbsp; IAP_address(address);<br> &nbsp; IAP_DATA = value;<br> &nbsp; IAP_trigger;<br> &nbsp; _nop_();<br> &nbsp; IAP_clear;<br> }<br> &nbsp;<br> void IAP_erase(unsigned int address)<br> {<br> &nbsp; IAP_CONTR = IAP_WT;<br> &nbsp; IAP_CMD = IAP_erase_command;<br> &nbsp; IAP_address(address);<br> &nbsp; IAP_trigger;<br> &nbsp; _nop_();<br> &nbsp; IAP_clear;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Some key points to\nnote while using internal flash as EEPROM:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>The flash\nmemory of STC micro can be divided into sectors of 512 bytes.<\/li><li>Byte write\nor byte erase operations are not possible as these are done at sector level.\nThis means that to change one byte of a sector, we would have to totally erase\nand write that sector.<\/li><li>Basing on\npoint 2, it is better to use two sectors for one set of data. We can, then,\nmaintain wear-leveling and memory ring buffer.&nbsp;\n<\/li><li>We must\nuse those locations of internal flash that won\u2019t have any part of application\ncode. As with other microcontrollers, STC micros begin executing code from\n0x0000 location of memory. Thus, it is better to use locations at the last\nportion of internal flash memory. <\/li><li>Flash\nmemory has an endurance of 100,000 cycles. Thus, frequent writes\/erases must be\navoided. It is better to use a RAM buffer for applications that require\nfrequent data storage. By using such a technique, flash memory is only modified\nbefore a reset or power down event. This is just like saving all your files\nbefore shutting down your PC. Most modern solid-state drives (SSD) come with a\nDRAM cache and this has almost similar usage. <\/li><li>IAP size\ncan be set by using STC programmer GUI.<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"422\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-26.png\" alt=\"\" class=\"wp-image-14805\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-26.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-26-580x265.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-26-768x352.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"422\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-27.png\" alt=\"\" class=\"wp-image-14806\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-27.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-27-580x265.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-27-768x352.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - IAP EEPROM Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/sxiDfofhr2E?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Timing-Related Hardware Overview<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When it comes to timer-counters and time-related hardware, STC microcontrollers pack lot of punch. There are five 16-bit timer-counters, a Programmable Counter Array (PCA) and an enhanced PWM hardware peripheral. The timers are similar to the timers of standard 8051 microcontrollers. The rest of the hardware peripherals are bonus features that are not typically available in traditional 8051s.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Timer-Counters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Timer-Counters T0 \u2013 T4 are the five 16-bit timer-counters. As with the\ntimers of any MCU, timers of STC microcontrollers can be employed for a number\nof tasks including time-base, timing events and outputs, measuring intervals,\netc. Timers of 8051\narchitecture-based microcontrollers are usually also\nresponsible for internal serial port (UART) hardware baud-rate generations and\nso is the case with STC microcontrollers. Thus, these timers are very\nversatile. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The typical structure of timers of traditional 8051s looks like the block diagram shown below but it is not completely the same for STC microcontrollers. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"875\" height=\"234\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-28.png\" alt=\"\" class=\"wp-image-14808\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-28.png 875w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-28-580x155.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-28-768x205.png 768w\" sizes=\"auto, (max-width: 875px) 100vw, 875px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>THx<\/em><\/strong> and\n<strong><em>TLx<\/em><\/strong> are cascaded counters that can be clocked using internal\nperipheral clock or externally via specific timer input GPIO pins. The clock\nthat would drive the counters can be optionally scaled but unlike other\nmicrocontrollers the scaling is restricted to 1T or 12T, i.e., the driving\nsource clock is either divided by one or divided by a factor of 12. When a\ntimer is internally clocked, it is said to be acting like a timer and when it\nis clocked externally, it is said to be operating as a counter. All timers have\ninterrupt capabilities and always count to top value from either 0 or some\npredefined value. Timers T0 and T1 are special timers while the rest are\ngeneral purpose timers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The timers can be operated in the following modes of operations:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"715\" height=\"197\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-29.png\" alt=\"\" class=\"wp-image-14809\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-29.png 715w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-29-580x160.png 580w\" sizes=\"auto, (max-width: 715px) 100vw, 715px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">These modes of operations have similarities\nwith standard 8051s but there are also some minor differences.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>16-bit Auto Reload Mode (Mode 0)<\/em><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In\nauto-reload mode, a timer\u2019s internal counter (<em>TLx<\/em> and <em>THx<\/em>) is\nloaded with some user-defined value at\nthe beginning and the timer is started. It will count\nfrom that set value to the top value of 65535 (0xFFFF) and then overflow. After\nthe overflow event, the user-defined value is automatically reloaded to the timer\u2019s\ncounter and the process repeats. The overflow event can generate an interrupt.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>16-bit Non-auto Reload Mode (Mode 1)<\/em><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Mode 1\nis same as Mode 0 but the only difference between them is reloading feature. In\nMode 1, a timer\u2019s internal counter (<em>TLx<\/em> and <em>THx<\/em>) needs to be\nreloaded manually through coding. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>8-bit Auto Reload Mode (Mode 2)<\/em><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Mode 2\nis similar to Mode 0. The differences are resolution and how the timer is\nreloaded. In this mode, <em>TLx<\/em> is used as counter and <em>THx<\/em> is used as\nthe buffer that with reload <em>TLx <\/em>when overflow occurs. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>16-bit Auto Reload Mode with Interrupt (Mode 3)<\/em><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This\nmode is same as Mode 0 but in this mode, interrupt cannot be disabled. In Mode\n0, we have the option to either use timer interrupt or have it disabled.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>Stop Mode<\/em><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Stop mode is only valid for Timer 1. Actually, all timers can be stopped somehow but entering this mode will disable Timer 1. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Enhanced PWM Module<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The enhanced PWM module of STC8A8K64S4A12 provides 8 channel 15-bit PWM outputs. This module allows lot of advanced PWM features like complementary PWMs with dead-times, PWMs with initial level settings, etc. There are options to use this module with internal ADC and there are options to detect faults. This module is best suited for power control applications like inverters, battery chargers, switch-mode power supplies (SMPS), etc. Lastly, this module can operate independently without the need of help from other internal timer modules. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Programmable Counter Array (PCA)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12\u2019s programmable array counter is an interesting and rare hardware peripheral. PCA is not seen in most microcontrollers. PCA basically extends PWM capabilities of STC8A8K64S4A12 while including input capture peripherals, special outputs and robust interrupt capabilities. PCA-based PWMs are of either 6-bit, 7-bit, 8-bit and 10-bit resolution and can be considered as general-purpose PWMs. The PCA module can be considered as an additional built-in timer peripheral as it can operate independently just like the PWM module. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"592\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-30.png\" alt=\"\" class=\"wp-image-14810\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-30.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-30-580x366.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-30-768x484.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In STC8A8K64S4A12, there are four PCA groups \u2013 CCP0, CCP1, CCP2 and CCP3 that are dependent on a central 16-bit counter and configuration assets. CCP0, CCP1, CCP2 and CCP3 can be inputs or outputs depending on the mode of operation of PCA module itself. The counter can be clocked with a number of clock sources as shown in the block diagram. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Other Timers<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apart from all aforementioned peripherals, STC8A8K64S4A12 packs a wakeup timer and a watchdog timer. Wakeup timer can bring out a STC8A8K64S4A12 micro from low power sleep mode after fixed time intervals. Watchdog timer in STC8A8K64S4A12 is just like the watchdog timer of any other microcontroller and is mainly intended for resetting should there be an unforeseen software loop\/error. These timers do not have alternative usage. <\/p>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using Timer 4 as Time-base Generator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The very basic use of a timer is to use it for time-base generation. By time-base generation, I mean that we use a timer as a free-running timer and without using any of its interrupts.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"789\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/timer-4-1024x789.jpg\" alt=\"\" class=\"wp-image-14811\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/timer-4-1024x789.jpg 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/timer-4-580x447.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/timer-4-768x592.jpg 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/timer-4.jpg 1062w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TMR4_get_counter()&nbsp;&gt;=&nbsp;0x9E58)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;24,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR4_setup(TMR4_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR4_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR4_no_clk_out);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR4_load_counter_16(0x3CB0);<br> &nbsp;&nbsp;TMR4_start;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"930\" height=\"481\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-31.png\" alt=\"\" class=\"wp-image-14812\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-31.png 930w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-31-580x300.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-31-768x397.png 768w\" sizes=\"auto, (max-width: 930px) 100vw, 930px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For this demo, onboard LED is used as the\ndemo is a simple LED blinking. The desired LED blink rate is 1.67Hz (about\n600ms). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 1MHz. Everything related to internal hardware timing is dependent on system clock and so its selection is very important. The system clock is set to 1MHz as the required blink rate is very small. Every system clock tick is, therefore, 1\u00b5s.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M, 24, MCLK_SYSCLK_no_output, MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see how the timer is configured. Firstly, timer 4 is used as it is one of the simplest timers. Obviously, this timer is working in 16-bit auto-reload mode (Mode 0) as no other mode of operation is available for it. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> TMR4_setup(TMR4_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR4_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR4_no_clk_out);<br> &nbsp;&nbsp;<br> TMR4_load_counter_16(0x3CB0);<br> TMR4_start; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As we can see the timer is fed with internal system clock (1MHz). This is further scaled down by a factor of 12, i.e., the timer is ticking at:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"203\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-32.png\" alt=\"\" class=\"wp-image-14813\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">All 16-bit timers start counting from a bottom value to a fixed top value of 65535 (0xFFFF) counts. A timer\u2019s internal counter overflows after exceeding the top value and then rolls over or repeats counting from its bottom value. The bottom value is 0 (0x0000) unless some other value is assigned in the code. Thus, unlike the top value, the bottom value can be changed. In this example, the bottom value is 15536 (0x3CB0). This, in effect, help us achieve 50000 counts. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"text-align:center\">65536 \u2013 15536 = 50000 counts<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we want to equally divide the on and off times of the LED and so the 50000 counts are divided into two halves, each 25000 counts individually. Thus, in the main loop, the timer\u2019s counter count is polled.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> if(TMR4_get_counter()&nbsp;&gt;=&nbsp;0x9E58)<br> {<br> &nbsp;&nbsp;P55_high;<br> }<br> else<br> {<br> &nbsp;&nbsp;P55_low;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the count is greater than or equal to 40536 (0x9E58), P55 is held high or else it is held low. Thus, from 15536 count to 40535 count (40535 \u2013 15536 = 24999), the pin\u2019s state is low and from 40536 count to 65535 count (65535 \u2013 40536 = 24999), the pin state is high. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"883\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-33.png\" alt=\"\" class=\"wp-image-14814\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-33.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-33-580x555.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-33-768x736.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Timer 4 Example - Time Base Generation\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/yAiFfGea_Ac?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Timer 1 as a Counter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Apart from timing events, the other role of timers is to count pulses. Pulse counting has number of applications like motor speed control, object counting, frequency measurements, encoder counting, etc.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"667\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-34.png\" alt=\"\" class=\"wp-image-14816\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-34.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-34-580x420.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-34-768x556.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(TMR1_get_counter()&nbsp;&gt;=&nbsp;32768)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P34_push_pull_mode;<br> &nbsp;<br> &nbsp;&nbsp;P35_input_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR1_setup(TMR1_16_bit_non_auto_reload,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_ext_T1_P35_clk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_int_gate,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_P34_clk_out);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR1_load_counter_8(0x00,&nbsp;0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR1_start;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"690\" height=\"294\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM1.png\" alt=\"\" class=\"wp-image-14817\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM1.png 690w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM1-580x247.png 580w\" sizes=\"auto, (max-width: 690px) 100vw, 690px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This example is same as the previous timer\nexample, the only difference is the clock source of the timer involved here.\nTimer 1 is used and it is externally clocked by using a signal generator. In\nthis example, the blinking rate of the onboard LED changes with the clock speed\nof the timer. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First let\u2019s see how the timer is set up.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> TMR1_setup(TMR1_16_bit_non_auto_reload,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_ext_T1_P35_clk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_int_gate,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR1_P34_clk_out);<br> &nbsp;&nbsp;<br> TMR1_load_counter_8(0x00,&nbsp;0x00);<br> &nbsp;&nbsp;<br> TMR1_start; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here, we can, firstly, see that the timer is set in non-auto reload mode. This means that timer needs periodic reloads after overflow or else it will restart counting from 0. In our case, this won\u2019t matter because we want the timer to count from 0 after overflow. Secondly, we can see that the timer is externally clocked and this is achieved by feeding clock pulses to P3.5 (T1) GPIO pin. Since the timer is externally clocked, it doesn\u2019t matter what system clock settings are. The next thing to note is the timer\u2019s clock prescalar. This is needed because we want to visually see the outcome with LEDs. If the LEDs blink too fast, we won\u2019t not be able to realize what is going on. Lastly, internal gating is used because we don\u2019t the timer to depend on other hardware events and we want to get timer output. Timer 1 will toggle the logic state of P3.4 (T1CLKO) GPIO pin when it overflows. Both GPIO pins P3.4 and P3.5 need to configured. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P34_push_pull_mode;<br> &nbsp;<br> P35_input_mode; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">State of P5.5 LED changes according to the value of timer\u2019s internal counter. For one half of the 16-bit count the LED is held low and for the other half it is held high. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> if(TMR1_get_counter()&nbsp;&gt;=&nbsp;32768)<br> {<br> &nbsp;&nbsp;P55_high;<br> }<br> &nbsp;<br> else<br> {<br> &nbsp;&nbsp;P55_low;<br> }&nbsp;&nbsp;&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Thus, in the main, this is only job done. Rate of blinking depends on external clock speed. The higher the clock frequency, the higher is the blinking rate. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"450\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-35.png\" alt=\"\" class=\"wp-image-14818\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-35.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-35-580x283.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-35-768x375.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Timer 1 Example - Timer as Counter\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/GIA7gT3RxY4?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using Timer 2 to Multiplex Seven Segment Displays<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rather than polling, a better way to use timers is to use their interrupts. Timer overflow interrupt is particularly useful for timing event accurately. Timer overflow interrupt will periodically interrupt main tasks and can perform certain things inside the interrupt and then get back to main tasks. In this way, several tasks will apparently seem to occur concurrently. Multiplexing seven segment displays is one such example. These displays need periodic scanning, multiplexing and updating. If these tasks are done swiftly and in short duration, human eyes can be tricked. If a CPU is occupied doing these tasks alone then it would not be able to do other tasks. If the tasks of seven segment displays are put inside a timer interrupt, the CPU can do other tasks in other interrupts and main code as seven segment displays need only periodic attention and not all code processing is spent on the displays alone.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"726\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-36.png\" alt=\"\" class=\"wp-image-14819\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-36.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-36-580x448.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-36-768x593.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;DAT_pin_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P41_high<br> #define&nbsp;DAT_pin_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P41_low<br> &nbsp;<br> #define&nbsp;CLK_pin_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P42_high<br> #define&nbsp;CLK_pin_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P42_low<br> &nbsp;<br> #define&nbsp;refresh_time_in_us&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;315<br> #define&nbsp;max_tmr_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFFFF<br> #define&nbsp;tmr_val&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(max_tmr_cnt&nbsp;-&nbsp;refresh_time_in_us)<br> <br> const&nbsp;unsigned&nbsp;char&nbsp;pos[0x08]&nbsp;=<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;0x01,&nbsp;0x02,&nbsp;0x04,&nbsp;0x08,&nbsp;0x10,&nbsp;0x20,&nbsp;0x40,&nbsp;0x80<br> };<br> &nbsp;<br> const&nbsp;unsigned&nbsp;char&nbsp;num[0x0A]&nbsp;=<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;0x03,&nbsp;0x9F,&nbsp;0x25,&nbsp;0x0D,&nbsp;0x99,&nbsp;0x49,&nbsp;0x41,&nbsp;0x1F,&nbsp;0x01,&nbsp;0x09<br> };<br> &nbsp;<br> unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;<br> signed&nbsp;int&nbsp;value_1&nbsp;=&nbsp;0;<br> signed&nbsp;int&nbsp;value_2&nbsp;=&nbsp;0;<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;Write_74HC164(unsigned&nbsp;char&nbsp;val,&nbsp;unsigned&nbsp;char&nbsp;seg);<br> &nbsp;<br> void&nbsp;ADC_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;5<br> {<br> &nbsp;&nbsp;value_1&nbsp;=&nbsp;((ADC_RES&nbsp;&lt;&lt;&nbsp;8)&nbsp;|&nbsp;ADC_RESL);<br> &nbsp;&nbsp;value_2&nbsp;=&nbsp;((value_1&nbsp;*&nbsp;5000.0)&nbsp;\/&nbsp;4096.0);<br> &nbsp;&nbsp;clear_ADC_flag;<br> }<br> &nbsp;<br> void&nbsp;TMR_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;12<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(i)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;0:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_1&nbsp;\/&nbsp;1000)],&nbsp;pos[3]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164((num[((value_1&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)]),&nbsp;pos[2]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[((value_1&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)],&nbsp;pos[1]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_1&nbsp;%&nbsp;10)],&nbsp;pos[0]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;4:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_2&nbsp;\/&nbsp;1000)]&nbsp;&amp;&nbsp;0xFE,&nbsp;pos[7]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;5:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164((num[((value_2&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)]),&nbsp;pos[6]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;6:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[((value_2&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)],&nbsp;pos[5]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;7:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_2&nbsp;%&nbsp;10)],&nbsp;pos[4]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;i++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(i&nbsp;&gt;=&nbsp;8)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_TMR_2_overflow_flag;<br> }&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC_set_channel(CH15);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ADC_start_conversion;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P41_push_pull_mode;<br> &nbsp;&nbsp;P42_push_pull_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;ADC_enable;<br> &nbsp;&nbsp;ADC_result_format_right_aligned;<br> &nbsp;&nbsp;ADC_set_conversion_speed(ADC_conv_128_CLKs);<br> &nbsp;&nbsp;_enable_ADC_interrupt;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR2_setup(TMR2_sysclk,&nbsp;TMR2_clk_prescalar_12T);<br> &nbsp;&nbsp;TMR2_load_counter_16(tmr_val);<br> &nbsp;&nbsp;TMR2_start;<br> &nbsp;&nbsp;_enable_TMR_2_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> }<br> void&nbsp;Write_74HC164(unsigned&nbsp;char&nbsp;val,&nbsp;unsigned&nbsp;char&nbsp;seg)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x10;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;temp&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;(unsigned&nbsp;int)seg;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;&lt;&lt;=&nbsp;8;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;|=&nbsp;(unsigned&nbsp;int)val;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((temp&nbsp;&amp;&nbsp;0x0001)&nbsp;!=&nbsp;0x0000)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAT_pin_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAT_pin_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_pin_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;&gt;&gt;=&nbsp;1;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_pin_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1015\" height=\"397\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM2-1.png\" alt=\"\" class=\"wp-image-14959\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM2-1.png 1015w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM2-1-580x227.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM2-1-768x300.png 768w\" sizes=\"auto, (max-width: 1015px) 100vw, 1015px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For demonstrating timer interrupt and seven\nsegment displays, I used a simple dual 4-digit seven segment displays. It is\nmade with a set of 74HC164 Serial-In-Parallel-Out (SPIO) shift register. In\norder to use it in real-time, its displays need to be scanned and updated at a\nfast rate without affecting other tasks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This demo is a very important one as here multiple interrupts are employed and literally there is nothing inside the main loop. Things are done in such a way as if everything is parallelly done and in real-time.&nbsp;&nbsp;  Firstly, the system clock and GPIOs are set. The system clock is set to 12 MHz. P4.1 and P4.2 are GPIOs that are used for driving the display. These drive data and clock lines of the display respectively.&nbsp;  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> P41_push_pull_mode;<br> P42_push_pull_mode; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ADC setup is as simple as the past ADC example. The conversion rate is set to about 3 kHz and the ADC interrupt is enabled. Note no external ADC pin is used as the goal here is to read the internal reference voltage source, i.e., ADC Channel 15. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ADC_enable;<br> ADC_result_format_right_aligned;<br> ADC_set_conversion_speed(ADC_conv_128_CLKs);<br> _enable_ADC_interrupt; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ADC interrupt is triggered when a conversion is completed. Inside this interrupt all we have to do is to read the ADC and clear the AD conversion completion flag. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;ADC_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;5<br> {<br> &nbsp;&nbsp;value_1&nbsp;=&nbsp;((ADC_RES&nbsp;&lt;&lt;&nbsp;8)&nbsp;|&nbsp;ADC_RESL);<br> &nbsp;&nbsp;value_2&nbsp;=&nbsp;((value_1&nbsp;*&nbsp;5000.0)&nbsp;\/&nbsp;4096.0);<br> &nbsp;&nbsp;clear_ADC_flag;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Timer 2 is used in this example and so let us now see how it is configured. There are eight seven segment displays and we would want them to be multiplexed quickly in order to make them appear to update simultaneously. We cannot afford to stay long for each display. Thus, this task should be completed within 2 \u2013 3ms time. Due to this reason, the timer is set to interrupt every 315\u00b5s. The total time for all displays is therefore about 2.52ms (8 \u00d7 0.315ms).<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;refresh_time_in_us&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;315<br> #define&nbsp;max_tmr_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFFFF<br> #define&nbsp;tmr_val&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(max_tmr_cnt&nbsp;-&nbsp;refresh_time_in_us)<br> &nbsp;<br> ....<br> &nbsp;<br> TMR2_setup(TMR2_sysclk,&nbsp;TMR2_clk_prescalar_12T);<br> TMR2_load_counter_16(tmr_val);<br> TMR2_start;<br> _enable_TMR_2_interrupt; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Timer 2 is a 16-bit timer with auto-reload feature. In this demo, it is clocked internally with the 12 MHz system clock. This clock is further scaled down by a factor of 12 and so the timer\u2019s ticks have a frequency of 1 MHz, i.e., the timer ticks are 1\u00b5s apart. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"623\" height=\"296\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-121.png\" alt=\"\" class=\"wp-image-14960\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-121.png 623w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-121-580x276.png 580w\" sizes=\"auto, (max-width: 623px) 100vw, 623px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, the timer is started with its interrupt enabled. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the timer interrupt the displays are updated by writing to the 74HC164 chips and clearing the timer overflow interrupt flag. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;TMR_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;12<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(i)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;0:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_1&nbsp;\/&nbsp;1000)],&nbsp;pos[3]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164((num[((value_1&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)]),&nbsp;pos[2]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[((value_1&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)],&nbsp;pos[1]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_1&nbsp;%&nbsp;10)],&nbsp;pos[0]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;4:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_2&nbsp;\/&nbsp;1000)]&nbsp;&amp;&nbsp;0xFE,&nbsp;pos[7]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;5:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164((num[((value_2&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100)]),&nbsp;pos[6]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;6:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[((value_2&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10)],&nbsp;pos[5]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;7:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Write_74HC164(num[(value_2&nbsp;%&nbsp;10)],&nbsp;pos[4]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;i++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(i&nbsp;&gt;=&nbsp;8)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_TMR_2_overflow_flag;<br> }&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The function below is the function for writing the 74HC164 shift-register ICs. Since the shift-registers are cascaded and we need them to work simultaneously, it is better to bit-bang seven segment data as 16-bit chunks \u2013 each word consisting of segment position and segment value data. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;Write_74HC164(unsigned&nbsp;char&nbsp;val,&nbsp;unsigned&nbsp;char&nbsp;seg)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x10;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;temp&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;(unsigned&nbsp;int)seg;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;&lt;&lt;=&nbsp;8;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;|=&nbsp;(unsigned&nbsp;int)val;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((temp&nbsp;&amp;&nbsp;0x0001)&nbsp;!=&nbsp;0x0000)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAT_pin_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAT_pin_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_pin_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;&gt;&gt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLK_pin_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note interrupt priorities are not changed and\nare left in their default conditions.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, the channel to be read is selected and AD conversion is triggered. This operation is cycled every 400ms. Channel 15 is read here. Channel 15 is the internal reference voltage source. The internal reference voltage source has a typical value of 1.344V. The seven segment displays show ADC counts and voltage value.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> ADC_set_channel(CH15);<br> delay_ms(10);<br> ADC_start_conversion;<br> delay_ms(400); <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"655\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR2.jpg\" alt=\"\" class=\"wp-image-14962\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR2.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR2-580x644.jpg 580w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Timer 2 Example - Reading Internal 1.33V Source and Showing on 7 Segment Displays\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/gFKg9aYkMrM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Timer 3 as Real Time Clock &amp; Calendar (RTCC)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since timers can time event precisely, we can use timers for time keeping too. Although there is no dedicated real-time clock-calendar (RTCC) hardware in STC8A8K64S4A12, we can make one by using a timer and some coding.&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"170\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/rtcc.jpg\" alt=\"\" class=\"wp-image-14823\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> &nbsp;<br> #define&nbsp;required_time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1000<br> #define&nbsp;max_tmr_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFFFF<br> #define&nbsp;tmr_val&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(max_tmr_cnt&nbsp;-&nbsp;required_time)<br> &nbsp;<br> #define&nbsp;PM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;AM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> &nbsp;<br> #define&nbsp;ETR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;INC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<br> #define&nbsp;DEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<br> #define&nbsp;ESC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<br> #define&nbsp;NON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;<br> #define&nbsp;ETR_button&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P10_get_input<br> #define&nbsp;INC_button&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P11_get_input<br> #define&nbsp;DEC_button&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P12_get_input<br> #define&nbsp;ESC_button&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P13_get_input<br> &nbsp;<br> unsigned&nbsp;char&nbsp;dow&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;hr&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;min&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;date&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;month&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;toggle&nbsp;=&nbsp;0;<br> unsigned&nbsp;char&nbsp;leap_year&nbsp;=&nbsp;0;<br> unsigned&nbsp;char&nbsp;ampm&nbsp;=&nbsp;AM;<br> &nbsp;<br> unsigned&nbsp;int&nbsp;ms&nbsp;=&nbsp;0;<br> unsigned&nbsp;int&nbsp;year&nbsp;=&nbsp;2000;<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;LCD_print_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;value);<br> void&nbsp;LCD_print_int_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;int&nbsp;value);<br> void&nbsp;display_time(void);<br> void&nbsp;AM_PM_disp(unsigned&nbsp;char&nbsp;state);<br> void&nbsp;dow_disp(unsigned&nbsp;char&nbsp;dow);<br> unsigned&nbsp;char&nbsp;get_buttons(void);<br> unsigned&nbsp;char&nbsp;set_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;max,&nbsp;unsigned&nbsp;char&nbsp;min,&nbsp;unsigned&nbsp;char&nbsp;type);<br> void&nbsp;setup_RTC(void);<br> &nbsp;<br> void&nbsp;TMR_3_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;19<br> {<br> &nbsp;&nbsp;ms++;<br> &nbsp;&nbsp;if(ms&nbsp;&gt;&nbsp;999)<br> &nbsp;&nbsp;{&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;ms&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle&nbsp;^=&nbsp;0x01;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_toggle;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;if(s&nbsp;&gt;&nbsp;59)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;min++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(min&nbsp;&gt;&nbsp;59)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(hr&nbsp;&gt;&nbsp;12)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((hr&nbsp;==&nbsp;12)&nbsp;&amp;&amp;&nbsp;(min&nbsp;==&nbsp;0)&nbsp;&amp;&amp;&nbsp;(s&nbsp;==&nbsp;0))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;^=&nbsp;1;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ampm&nbsp;==&nbsp;AM)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(dow&nbsp;&gt;&nbsp;7)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((month&nbsp;==&nbsp;1)&nbsp;||&nbsp;(month&nbsp;==&nbsp;3)&nbsp;||&nbsp;(month&nbsp;==&nbsp;5)&nbsp;||&nbsp;(month&nbsp;==&nbsp;7)&nbsp;||&nbsp;(month&nbsp;==&nbsp;8)&nbsp;||&nbsp;(month&nbsp;==&nbsp;10)&nbsp;||&nbsp;(month&nbsp;==&nbsp;12))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;31)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((month&nbsp;==&nbsp;4)&nbsp;||&nbsp;(month&nbsp;==&nbsp;6)&nbsp;||&nbsp;(month&nbsp;==&nbsp;9)&nbsp;||&nbsp;(month&nbsp;==&nbsp;11))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;30)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;4)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;100)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;400)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;29))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((!leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;28))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(month&nbsp;&gt;&nbsp;12)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;year++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;clear_TMR_3_overflow_flag;<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(get_buttons()&nbsp;==&nbsp;ESC)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(get_buttons()&nbsp;==&nbsp;ESC);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setup_RTC();<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display_time();<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P10_input_mode;<br> &nbsp;&nbsp;P11_input_mode;<br> &nbsp;&nbsp;P12_input_mode;<br> &nbsp;&nbsp;P13_input_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P54_push_pull_mode;<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;<br> &nbsp;&nbsp;TMR3_setup(TMR3_sysclk,&nbsp;TMR3_clk_prescalar_12T,&nbsp;TMR3_no_clk_out);<br> &nbsp;&nbsp;TMR3_load_counter_16(tmr_val);<br> &nbsp;&nbsp;TMR3_start;<br> &nbsp;&nbsp;_enable_TMR_3_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> }<br> &nbsp;<br> void&nbsp;LCD_print_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;LCD_putchar((value&nbsp;\/&nbsp;10)&nbsp;+&nbsp;0x30);<br> &nbsp;&nbsp;LCD_goto((x_pos&nbsp;+&nbsp;1),&nbsp;y_pos);<br> &nbsp;&nbsp;LCD_putchar((value&nbsp;%&nbsp;10)&nbsp;+&nbsp;0x30);<br> }<br> &nbsp;<br> void&nbsp;LCD_print_int_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;int&nbsp;value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(value&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;LCD_print_value(x_pos,&nbsp;y_pos,&nbsp;temp);<br> &nbsp;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(value&nbsp;%&nbsp;100);<br> &nbsp;&nbsp;LCD_print_value((x_pos&nbsp;+&nbsp;2),&nbsp;y_pos,&nbsp;temp);<br> &nbsp;<br> }<br> &nbsp;<br> void&nbsp;display_time(void)<br> {<br> &nbsp;&nbsp;LCD_print_value(2,&nbsp;0,&nbsp;hr);<br> &nbsp;&nbsp;LCD_print_value(5,&nbsp;0,&nbsp;min);<br> &nbsp;&nbsp;LCD_print_value(8,&nbsp;0,&nbsp;s);<br> &nbsp;<br> &nbsp;&nbsp;switch(toggle)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(4,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(':');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(7,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(':');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(4,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar('&nbsp;');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(7,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar('&nbsp;');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;AM_PM_disp(ampm);<br> &nbsp;&nbsp;dow_disp(dow);<br> &nbsp;<br> &nbsp;&nbsp;LCD_print_value(6,&nbsp;1,&nbsp;date);<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(8,&nbsp;1);<br> &nbsp;&nbsp;LCD_putchar('.');<br> &nbsp;&nbsp;LCD_print_value(9,&nbsp;1,&nbsp;month);<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(11,&nbsp;1);<br> &nbsp;&nbsp;LCD_putchar('.');<br> &nbsp;&nbsp;LCD_print_int_value(12,&nbsp;1,&nbsp;year);<br> }<br> &nbsp;<br> void&nbsp;dow_disp(unsigned&nbsp;char&nbsp;dow)<br> {<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;<br> &nbsp;&nbsp;switch(dow)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"MON\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"TUE\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"WED\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;4:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"THR\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;5:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"FRI\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;6:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"SAT\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;7:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"SUN\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;AM_PM_disp(unsigned&nbsp;char&nbsp;state)<br> {<br> &nbsp;&nbsp;LCD_goto(12,&nbsp;0);<br> &nbsp;<br> &nbsp;&nbsp;switch(state)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;AM:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"AM\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"PM\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;get_buttons(void)<br> {<br> &nbsp;&nbsp;if(ETR_button)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ETR;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else&nbsp;if(INC_button)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;INC;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else&nbsp;if(DEC_button)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;DEC;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else&nbsp;if(ESC_button)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ESC;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NON;<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;set_value(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;max,&nbsp;unsigned&nbsp;char&nbsp;min,&nbsp;unsigned&nbsp;char&nbsp;type)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;tgl&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;tgl&nbsp;^=&nbsp;0x01;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(90);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(get_buttons()&nbsp;==&nbsp;INC)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value++;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&gt;&nbsp;max)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;min;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(get_buttons()&nbsp;==&nbsp;DEC)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;min)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;max;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(type)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(tgl)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_print_value(x_pos,&nbsp;y_pos,&nbsp;value);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(x_pos,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(tgl)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AM_PM_disp(value);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(tgl)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow_disp(value);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow_disp(0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((get_buttons()&nbsp;==&nbsp;ETR)&nbsp;&amp;&amp;&nbsp;(tgl&nbsp;==&nbsp;1))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup_RTC(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;yr1&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;yr2&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;TMR3_stop;<br> &nbsp;&nbsp;_disable_TMR_3_interrupt;<br> &nbsp;<br> &nbsp;&nbsp;yr1&nbsp;=&nbsp;(year&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;yr2&nbsp;=&nbsp;(year&nbsp;%&nbsp;100);<br> &nbsp;<br> &nbsp;&nbsp;hr&nbsp;=&nbsp;set_value(2,&nbsp;0,&nbsp;hr,&nbsp;12,&nbsp;1,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;min&nbsp;=&nbsp;set_value(5,&nbsp;0,&nbsp;min,&nbsp;59,&nbsp;0,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;s&nbsp;=&nbsp;set_value(8,&nbsp;0,&nbsp;s,&nbsp;59,&nbsp;0,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;ampm&nbsp;=&nbsp;set_value(12,&nbsp;0,&nbsp;ampm,&nbsp;1,&nbsp;0,&nbsp;2);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;dow&nbsp;=&nbsp;set_value(0,&nbsp;1,&nbsp;dow,&nbsp;7,&nbsp;1,&nbsp;0);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;date&nbsp;=&nbsp;set_value(6,&nbsp;1,&nbsp;date,&nbsp;31,&nbsp;1,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;month&nbsp;=&nbsp;set_value(9,&nbsp;1,&nbsp;month,&nbsp;12,&nbsp;1,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;yr1&nbsp;=&nbsp;set_value(12,&nbsp;1,&nbsp;yr1,&nbsp;99,&nbsp;0,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;yr2&nbsp;=&nbsp;set_value(14,&nbsp;1,&nbsp;yr2,&nbsp;99,&nbsp;0,&nbsp;1);<br> &nbsp;&nbsp;delay_ms(200);<br> &nbsp;<br> &nbsp;&nbsp;year&nbsp;=&nbsp;((yr1&nbsp;*&nbsp;100)&nbsp;+&nbsp;yr2);<br> &nbsp;<br> &nbsp;&nbsp;if((month&nbsp;==&nbsp;1)&nbsp;||&nbsp;(month&nbsp;==&nbsp;3)&nbsp;||&nbsp;(month&nbsp;==&nbsp;5)&nbsp;||&nbsp;(month&nbsp;==&nbsp;7)&nbsp;||&nbsp;(month&nbsp;==&nbsp;8)&nbsp;||&nbsp;(month&nbsp;==&nbsp;10)&nbsp;||&nbsp;(month&nbsp;==&nbsp;12))<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;31)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else&nbsp;if((month&nbsp;==&nbsp;4)&nbsp;||&nbsp;(month&nbsp;==&nbsp;6)&nbsp;||&nbsp;(month&nbsp;==&nbsp;9)&nbsp;||&nbsp;(month&nbsp;==&nbsp;11))<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;30)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;else<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;4)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;100)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;400)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;29))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((!leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;28))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;ms&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;TMR3_setup(TMR3_sysclk,&nbsp;TMR3_clk_prescalar_12T,&nbsp;TMR3_no_clk_out);<br> &nbsp;&nbsp;TMR3_load_counter_16(tmr_val);<br> &nbsp;&nbsp;TMR3_start;<br> &nbsp;&nbsp;_enable_TMR_3_interrupt;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"293\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM3.png\" alt=\"\" class=\"wp-image-14824\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM3.png 872w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM3-580x195.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM3-768x258.png 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM3-420x140.png 420w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For making a RTCC, we would need a display and a set of buttons for displaying and setting time respectively. The system clock in this example is set to 12MHz. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M, 2, MCLK_SYSCLK_no_output, MCLK_out_P54);<br> &nbsp;<br> P10_input_mode;<br> P11_input_mode;<br> P12_input_mode;<br> P13_input_mode;<br> &nbsp;&nbsp;<br> P54_push_pull_mode;<br> &nbsp;<br> LCD_init();<br> LCD_clear_home(); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Timer 3 is used in example. It is driven with the 12MHz system clock and this clock is precaled by 12. Thus, the timer is ticking at 1MHz speed.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> TMR3_setup(TMR3_sysclk, TMR3_clk_prescalar_12T, TMR3_no_clk_out);<br> TMR3_load_counter_16(tmr_val);<br> TMR3_start;<br> _enable_TMR_3_interrupt;<br> _enable_global_interrupt; <\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"736\" height=\"336\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-39.png\" alt=\"\" class=\"wp-image-14826\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-39.png 736w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-39-580x265.png 580w\" sizes=\"auto, (max-width: 736px) 100vw, 736px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, the timer is started with its\ninterrupt enabled. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In order to ensure accuracy of timing the\nfollowing should be maintained as much as possible:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Clock source must be as precise\nas possible. I recommend using a temperature-compensated crystal oscillator\n(TCXO).<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Precalar should be as less as\npossible. This is not possible here with STC8A8K64S4A12 though due to hardware\nlimitations. <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Accuracy can be increased by\nsynchronizing time with GPS at periodic interval. This can be achieved by\nadding extra codes and synchronizing\nwith a GPS receiver or NTP server.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Since the timer is now ticking at 0.001ms rate and 1 second equals 1000ms, a variable called <strong><em>\u201cms\u201d<\/em><\/strong> is incremented at every timer overflow interrupt. When this get larger than 999, one second is registered. In similar way, minute, hour, day, month and year are increased. The process is just like a software timer implementation. At the end of the interrupt, timer overflow flag is cleared. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;TMR_3_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;19<br> {<br> &nbsp;&nbsp;ms++;<br> &nbsp;&nbsp;if(ms&nbsp;&gt;&nbsp;999)<br> &nbsp;&nbsp;{&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;ms&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;toggle&nbsp;^=&nbsp;0x01;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_toggle;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;if(s&nbsp;&gt;&nbsp;59)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;min++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(min&nbsp;&gt;&nbsp;59)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(hr&nbsp;&gt;&nbsp;12)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((hr&nbsp;==&nbsp;12)&nbsp;&amp;&amp;&nbsp;(min&nbsp;==&nbsp;0)&nbsp;&amp;&amp;&nbsp;(s&nbsp;==&nbsp;0))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;^=&nbsp;1;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ampm&nbsp;==&nbsp;AM)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(dow&nbsp;&gt;&nbsp;7)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dow&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((month&nbsp;==&nbsp;1)&nbsp;||&nbsp;(month&nbsp;==&nbsp;3)&nbsp;||&nbsp;(month&nbsp;==&nbsp;5)&nbsp;||&nbsp;(month&nbsp;==&nbsp;7)&nbsp;||&nbsp;(month&nbsp;==&nbsp;8)&nbsp;||&nbsp;(month&nbsp;==&nbsp;10)&nbsp;\\\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ||&nbsp;(month&nbsp;==&nbsp;12))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;31)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((month&nbsp;==&nbsp;4)&nbsp;||&nbsp;(month&nbsp;==&nbsp;6)&nbsp;||&nbsp;(month&nbsp;==&nbsp;9)&nbsp;||&nbsp;(month&nbsp;==&nbsp;11))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(date&nbsp;&gt;&nbsp;30)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;4)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;100)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((year&nbsp;%&nbsp;400)&nbsp;==&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leap_year&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;29))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((!leap_year)&nbsp;&amp;&amp;&nbsp;(date&nbsp;&gt;&nbsp;28))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(month&nbsp;&gt;&nbsp;12)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;month&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;year++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;clear_TMR_3_overflow_flag;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, either we can set time or read it. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> if(get_buttons()&nbsp;==&nbsp;ESC)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;while(get_buttons()&nbsp;==&nbsp;ESC);<br> &nbsp;&nbsp;&nbsp;&nbsp;setup_RTC();<br> }<br> else<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;display_time();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"590\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR3.jpg\" alt=\"\" class=\"wp-image-14971\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR3.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR3-150x150.jpg 150w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR3-580x580.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/TMR3-90x90.jpg 90w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Timer 3 Example - Using Timer as Real Time Clock Calendar (RTCC)\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/DwMn9KGtnKs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">NEC IR Remote Decoding with Timer 0\nand External Interrupt <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In many projects, we need to control\ndevices remotely, for example a remote-controlled appliance and so it becomes\nnecessary to incorporate some form of remote controller. Infrared (IR) remote\ncontrollers are cheap and are widely used as remote controllers in many devices.\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Data to be sent from a remote IR transmitter to a receiver is transmitted by modulating it with a carrier wave having frequency between 30kHz to 40kHz. Modulation technique ensures safety from data corruption over long-distance transmissions. An IR receiver at the receiving end picks up and demodulates the sent out modulated data and outputs a stream of pulses. These pulses can vary in terms of pulse widths\/timing\/position\/phase and these variable properties carry the data. Pulse properties are defined by a set of rules called protocol. Decoding the pulses as per protocol help in retrieving information. In most micros, there is no dedicated hardware for decoding IR remote protocols. A micro that needs to decode IR remote data also does not know when it will be receiving an IR burst. Thus, a combination of external interrupt and timer is needed for decoding IR data. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"945\" height=\"555\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-41.png\" alt=\"\" class=\"wp-image-14829\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-41.png 945w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-41-580x341.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-41-768x451.png 768w\" sizes=\"auto, (max-width: 945px) 100vw, 945px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In this segment, we will see how we can use an external interrupt and a timer to easily decode a NEC IR remote. This same method can be applied to any IR remote controller. At this stage, I recommend studying NEC IR protocol from <a href=\"https:\/\/www.sbprojects.net\/knowledge\/ir\/nec.php\">here<\/a>. SB-Project\u2019s website is an excellent page for IR remote-related info.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> #define&nbsp;sync_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5850&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;4500us<br> #define&nbsp;sync_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3150&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;4500us<br> #define&nbsp;one_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2200&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;(2250&nbsp;-&nbsp;562.5)us<br> #define&nbsp;one_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1180&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;(2250&nbsp;-&nbsp;562.5)us&nbsp;&nbsp;<br> #define&nbsp;zero_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;732&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;(1125&nbsp;-&nbsp;562.5)us<br> #define&nbsp;zero_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;394&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;(1125&nbsp;-&nbsp;562.5)us<br> &nbsp;<br> unsigned&nbsp;char&nbsp;bits&nbsp;=&nbsp;0x00;&nbsp;<br> unsigned&nbsp;char&nbsp;received&nbsp;=&nbsp;0x00;&nbsp;<br> &nbsp;<br> unsigned&nbsp;int&nbsp;frames[33];<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;erase_frames(void);<br> unsigned&nbsp;char&nbsp;decode(unsigned&nbsp;char&nbsp;start_pos,&nbsp;unsigned&nbsp;char&nbsp;end_pos);<br> void&nbsp;decode_NEC(unsigned&nbsp;char&nbsp;*addr,&nbsp;unsigned&nbsp;char&nbsp;*cmd);<br> &nbsp;<br> void&nbsp;EXT_0_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;0<br> {<br> &nbsp;&nbsp;frames[bits]&nbsp;=&nbsp;TMR0_get_counter();&nbsp;<br> &nbsp;&nbsp;bits++;&nbsp;<br> &nbsp;&nbsp;TMR0_start;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;if(bits&nbsp;&gt;=&nbsp;33)&nbsp;<br> &nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;received&nbsp;=&nbsp;1;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;_disable_global_interrupt;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TMR0_stop;&nbsp;<br> &nbsp;&nbsp;}&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR0_load_counter_16(0x0000);&nbsp;<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;addr&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;cmd&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(1,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"NEC&nbsp;IR&nbsp;Decoder\");&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"Adr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cmd\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(received&nbsp;!=&nbsp;FALSE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decode_NEC(&amp;addr,&nbsp;&amp;cmd);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_C(3,&nbsp;1,&nbsp;addr);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_C(12,&nbsp;1,&nbsp;cmd);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erase_frames();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_enable_global_interrupt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_SYSCLK_no_output);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;erase_frames();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR0_setup(TMR0_16_bit_non_auto_reload,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_ext_gate,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_no_clk_out);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;EXT_0_priority_0;<br> &nbsp;&nbsp;EXT_0_falling_edge_detection_only;<br> &nbsp;&nbsp;_enable_EXT_0_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> }<br> &nbsp;<br> void&nbsp;erase_frames(void)<br> {<br> &nbsp;&nbsp;for(bits&nbsp;=&nbsp;0;&nbsp;bits&nbsp;&lt;&nbsp;33;&nbsp;bits++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;frames[bits]&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;TMR0_load_counter_16(0x0000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;received&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;bits&nbsp;=&nbsp;0;<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;decode(unsigned&nbsp;char&nbsp;start_pos,&nbsp;unsigned&nbsp;char&nbsp;end_pos)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;for(bits&nbsp;=&nbsp;start_pos;&nbsp;bits&nbsp;&lt;=&nbsp;end_pos;&nbsp;bits++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;one_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;one_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;zero_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;zero_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;sync_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;sync_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0xFF;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;value;<br> }<br> &nbsp;<br> void&nbsp;decode_NEC(unsigned&nbsp;char&nbsp;*addr,&nbsp;unsigned&nbsp;char&nbsp;*cmd)<br> {<br> &nbsp;&nbsp;*addr&nbsp;=&nbsp;decode(2,&nbsp;9);<br> &nbsp;&nbsp;*cmd&nbsp;=&nbsp;decode(18,&nbsp;25);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"301\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM0.png\" alt=\"\" class=\"wp-image-14830\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM0.png 741w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-TIM0-580x236.png 580w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A NEC transmission sends out a total of 33 pulses. The first one is a sync pulse and the rest 32 contain address and command info. These 32 address and command bits can be divided into 2 groups. The first 16 bits is one group that contain address and inverted address while the second group of 16-bits contain command and inverted command. The non-inverted signals can be used against the inverted ones for checking data integrity.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We already know that IR data is received as a steam of pulses. Pulses represent sync bit or ones and zeros. In case of NEC IR protocol, the pulses have variable widths. Sync bit is characterized by a pulse of 9ms high and 4.5ms low \u2013 the total pulse time is 13.5ms. Check the timing diagram shown below. Please note that in this timing diagram the blue pulses are from the transmitter and the yellow ones are those received by the receiver. Clearly the pulse streams are inverted. This inversion is done at the IR receiver side.  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"767\" height=\"488\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-42.png\" alt=\"\" class=\"wp-image-14831\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-42.png 767w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-42-580x369.png 580w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Logic one is represented by a pulse of 560\u03bcs high time and 2.25ms of low time \u2013 the total pulse time is 2.81ms. Likewise, logic zero is represented by a pulse of 560\u03bcs high time and 1.12ms of low time \u2013 the total pulse time is 1.68ms.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"398\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-43.png\" alt=\"\" class=\"wp-image-14832\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-43.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-43-580x246.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-43-768x325.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">These timings can vary up to 30% of their\nideal values due to a number of factors like medium, temperature, reflections,\netc. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s look at the coding. Firstly, the system clock is set to 12MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_SYSCLK_no_output); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">External interrupt is set up to detect falling edges. This is a crucial part in detecting IR pulses because using this interrupt allows us to do other tasks and leave the MCU free for other tasks. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> EXT_0_priority_0;<br> EXT_0_falling_edge_detection_only;<br> _enable_EXT_0_interrupt;<br> _enable_global_interrupt; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike past timer examples, we will need an advanced timer here and so Timer 0 is used. This timer is clocked with the 12MHz system clock that has been divided by a prescalar of 12. Thus, the timer is operating at 1MHz speed, i.e., 1 timer tick = 1\u00b5s. We don\u2019t want any output from the timer and so this feature is disabled. The only different thing here that sets this setup apart from the other timer examples is the <em>\u201cgate\u201d<\/em> feature. <em>Gate<\/em> tells Timer 0 when and when not to run. There are two possible cases with gating &#8211; either the timer runs just like other timers when instructed to run via software or it runs when it is coded to run <em>and<\/em> INT0 pin is in logic high state. The latter feature is required in this example.&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> TMR0_setup(TMR0_16_bit_non_auto_reload, \\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_clk_prescalar_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_ext_gate,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR0_no_clk_out); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note timer interrupt is not needed. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As soon as there is an external interrupt, the timer immediately stops because of the falling edge that triggered the interrupt and the subsequent low level at INT0 pin. Timer\u2019s count is captured and stored in an array. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;EXT_0_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;0<br> {<br> &nbsp;&nbsp;frames[bits]&nbsp;=&nbsp;TMR0_get_counter();&nbsp;<br> &nbsp;&nbsp;bits++;&nbsp;<br> &nbsp;&nbsp;TMR0_start;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;if(bits&nbsp;&gt;=&nbsp;33)&nbsp;<br> 1`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;{&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;received&nbsp;=&nbsp;1;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;_disable_global_interrupt;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TMR0_stop;&nbsp;<br> &nbsp;&nbsp;}&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TMR0_load_counter_16(0x0000);&nbsp;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The captured counts are compared against maximum and minimum interval limits because as stated, pulse widths may slightly vary from their ideal figures. From captured counts, we can sort pulses and decode pulses. This decoded information can be used to deduce command and address.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;sync_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5850&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;4500us<br> #define&nbsp;sync_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3150&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;4500us<br> #define&nbsp;one_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2200&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;(2250&nbsp;-&nbsp;562.5)us<br> #define&nbsp;one_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1180&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;(2250&nbsp;-&nbsp;562.5)us&nbsp;&nbsp;<br> #define&nbsp;zero_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;732&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;1.3&nbsp;*&nbsp;(1125&nbsp;-&nbsp;562.5)us<br> #define&nbsp;zero_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;394&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/approx&nbsp;0.7&nbsp;*&nbsp;(1125&nbsp;-&nbsp;562.5)us<br> &nbsp;<br> . . . . <br> &nbsp;<br> unsigned&nbsp;char&nbsp;decode(unsigned&nbsp;char&nbsp;start_pos,&nbsp;unsigned&nbsp;char&nbsp;end_pos)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;for(bits&nbsp;=&nbsp;start_pos;&nbsp;bits&nbsp;&lt;=&nbsp;end_pos;&nbsp;bits++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;one_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;one_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;zero_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;zero_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((frames[bits]&nbsp;&gt;=&nbsp;sync_low)&nbsp;&amp;&amp;&nbsp;(frames[bits]&nbsp;&lt;=&nbsp;sync_high))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0xFF;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp; return&nbsp;value;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the main loop, address and command data are displayed on an LCD after receiving and decoding a NEC frame. After that the microcontroller is readied to receive new NEC frame.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> if(received&nbsp;!=&nbsp;FALSE)<br> {<br> &nbsp;&nbsp;decode_NEC(&amp;addr,&nbsp;&amp;cmd);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;print_C(3,&nbsp;1,&nbsp;addr);&nbsp;<br> &nbsp;&nbsp;print_C(12,&nbsp;1,&nbsp;cmd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(100);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;erase_frames();<br> &nbsp;_enable_global_interrupt;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"592\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-44.png\" alt=\"\" class=\"wp-image-14833\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-44.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-44-580x372.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-44-768x493.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Timer 0 Example - NEC IR Remote Decoder\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/9hWbi4iQIjo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using Single Channel Enhanced PWM\nto Drive a Servo Motor<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Servo motors have\nvarieties of applications both in industrial automation and robotics arena.\nThey are simple and can be digitally controlled with only one wire and over\nlong distances. However, this one wire digital control mechanism is somewhat\nunique and sometimes stressful because trains of low duty cycle pulses are\nneeded to be sent constantly in order to lock a particular angular position.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To resolve this issue, we can use GPIOs coupled with software delays or timers or PWMs module to control one or several servo motors. One key advantage of using PWM modules over GPIOs is the accuracy in timing since PWM modules use timer-counters for timing instead of software delays. In this section, we will see how we can use a PWM module to drive an ordinary servo motor. STC8A8K64S4A12\u2019s enhanced PWM module is used as the PWM generator here. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"499\" height=\"387\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/servo.jpg\" alt=\"\" class=\"wp-image-14835\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;servo_min_duty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;800<br> #define&nbsp;servo_max_duty&nbsp;&nbsp;&nbsp;&nbsp;2200<br> #define&nbsp;step_change&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;PWM_idle(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;i&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;servo_min_duty;&nbsp;i&nbsp;&lt;&nbsp;servo_max_duty;&nbsp;i&nbsp;+=&nbsp;step_change)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T1(i);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(4);<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;servo_max_duty;&nbsp;i&nbsp;&gt;&nbsp;servo_min_duty;&nbsp;i&nbsp;-=&nbsp;step_change)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T1(i);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(4);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_12);&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_counter(20000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P20,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM0_T1(1000);<br> &nbsp;&nbsp;PWM_set_PWM0_T2(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_start_counter;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"510\" height=\"299\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Servo.png\" alt=\"\" class=\"wp-image-14836\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Servo motors typically have timing diagrams as shown below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"483\" height=\"636\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-45.png\" alt=\"\" class=\"wp-image-14837\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Each pulse has a period of 20ms but the duty cycle\/pulse high time is varied from 5 &#8211; 10% to rotate from one direction to the other.\nThis clearly demonstrates why timing is very important for servo motors. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The demo program here is coded to run at 12MHz.&nbsp;&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">PWM0 hardware is configured to use P2.0 pin as servo control pin. The PWM hardware clock is set to 1MHz by using system clock as clock source and dividing it with a prescalar of 12. This is, however, not the PWM output frequency because the PWM counter is loaded with count value of 20000. The resultant PWM output frequency is 50Hz as shown in the following equation:&nbsp;&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"315\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-46.png\" alt=\"\" class=\"wp-image-14838\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-46.png 731w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-46-580x250.png 580w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The following codes does all mentioned so far. However, PWM setup is not just about timing only. PWM hardware also need an output. We have to mention which PWM we would be using and what would be its level and polarity.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_12);<br> &nbsp;&nbsp;<br> PWM_set_counter(20000);<br> &nbsp;&nbsp;<br> PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P20,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_set_PWM0_T1(1000);<br> PWM_set_PWM0_T2(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PWM_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After setting all these,\nwe just have to start the PWM hardware by starting the PWM counter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the main loop, the duty cycle of the PWM is slightly varied in steps. This results in smooth servo motion. Note that the maximum and minimum duty cycles are not 2000 and 1000 respectively as they ideally should have been. This is so because these values are typical ones and not always practical. Thus, the maximum and minimum duty cycles are set to 2200 and 800 respectively. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"147\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-47.png\" alt=\"\" class=\"wp-image-14839\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-47.png 730w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-47-580x117.png 580w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The 1% variation is needed because of non-ideality. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;servo_min_duty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;800<br> #define&nbsp;servo_max_duty&nbsp;&nbsp;&nbsp;&nbsp;2200<br> #define&nbsp;step_change&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5<br> &nbsp;<br> ....<br> &nbsp;<br> for(i&nbsp;=&nbsp;servo_min_duty;&nbsp;i&nbsp;&lt;&nbsp;servo_max_duty;&nbsp;i&nbsp;+=&nbsp;step_change)<br> {<br> &nbsp;&nbsp;PWM_set_PWM0_T1(i);&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(4);<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> for(i&nbsp;=&nbsp;servo_max_duty;&nbsp;i&nbsp;&gt;&nbsp;servo_min_duty;&nbsp;i&nbsp;-=&nbsp;step_change)<br> {<br> &nbsp;&nbsp;PWM_set_PWM0_T1(i);&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(4);<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The logic analyser data shown below verifies that whatever stated so far has been achieved.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"466\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-48.png\" alt=\"\" class=\"wp-image-14840\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-48.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-48-580x288.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-48-768x381.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"382\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/single-PWM.jpg\" alt=\"\" class=\"wp-image-14974\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/single-PWM.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/single-PWM-580x376.jpg 580w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Single Enhanced PWM Example - Driving a Servo Motor with PWM\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/TdHbkxH7ZWs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using Multi Channel Enhanced PWM to\nDrive an RGB LED<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since we now have seen how to use single channel enhanced PWM, we must also see how to use multichannel PWM. Multi-channel PWM has many applications. For example, multi-channel PWM is used in SMPSs, inverters, motor controllers, LED drivers, etc.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"995\" height=\"909\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/RGB-LED.jpg\" alt=\"\" class=\"wp-image-14843\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/RGB-LED.jpg 995w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/RGB-LED-580x530.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/RGB-LED-768x702.jpg 768w\" sizes=\"auto, (max-width: 995px) 100vw, 995px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;steps&nbsp;33<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;PWM_idle(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;<br> &nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;signed&nbsp;char&nbsp;j&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;const&nbsp;unsigned&nbsp;int&nbsp;duty1_value[steps]&nbsp;=&nbsp;{0,&nbsp;950,&nbsp;1892,&nbsp;2817,&nbsp;3717,&nbsp;4582,&nbsp;5407,&nbsp;6182,&nbsp;6901,&nbsp;7558,&nbsp;8146,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946};<br> &nbsp;<br> &nbsp;&nbsp;const&nbsp;unsigned&nbsp;int&nbsp;duty2_value[steps]&nbsp;=&nbsp;{8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;950,&nbsp;1892,&nbsp;2817,&nbsp;3717,&nbsp;4582,&nbsp;5407,&nbsp;6182,&nbsp;6901,&nbsp;7558,&nbsp;8146,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095};<br> &nbsp;<br> &nbsp;&nbsp;const&nbsp;unsigned&nbsp;int&nbsp;duty3_value[steps]&nbsp;=&nbsp;{8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;950,&nbsp;1892,&nbsp;2817,&nbsp;3717,&nbsp;4582,&nbsp;5407,&nbsp;6182,&nbsp;6901,&nbsp;7558,&nbsp;8146};<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;6;&nbsp;j++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;steps;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM1_T2(duty2_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM2_T2(duty3_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_idle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;6;&nbsp;j++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;steps;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM1_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM2_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_idle();<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_counter(10000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM1_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_1_pin_P11,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM2_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_2_pin_P12,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM0_T1(0);<br> &nbsp;&nbsp;PWM_set_PWM0_T2(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM1_T1(0);<br> &nbsp;&nbsp;PWM_set_PWM1_T2(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM2_T1(0);<br> &nbsp;&nbsp;PWM_set_PWM2_T2(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_start_counter;<br> }<br> &nbsp;<br> void&nbsp;PWM_idle(void)<br> {<br> &nbsp;&nbsp;PWM0_hold_level(PWM_HLD_L_low);<br> &nbsp;&nbsp;PWM1_hold_level(PWM_HLD_L_low);<br> &nbsp;&nbsp;PWM2_hold_level(PWM_HLD_L_low);&nbsp;<br> &nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;PWM0_hold_level(PWM_level_normal);<br> &nbsp;&nbsp;PWM1_hold_level(PWM_level_normal);<br> &nbsp;&nbsp;PWM2_hold_level(PWM_level_normal);&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(100);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"656\" height=\"386\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RGB.png\" alt=\"\" class=\"wp-image-14844\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RGB.png 656w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RGB-580x341.png 580w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In\nthis demo, a RGB LED is lit with multi-channel PWM. This results in smooth color\nshifting of the LED. The concepts are same as that of single channel PWM\nexample.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 12MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The PWM frequency is set to 600 Hz.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"76\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-50.png\" alt=\"\" class=\"wp-image-14845\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-50.png 722w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-50-580x61.png 580w\" sizes=\"auto, (max-width: 722px) 100vw, 722px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Since we are using a RGB LED, we need three PWM channels and so their GPIOs are also set. Lastly, the initial duty cycle is set 0 and the PWM counter is started.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);<br> &nbsp;&nbsp;<br> PWM_set_counter(10000);<br> &nbsp;&nbsp;<br> PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> PWM1_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_1_pin_P11,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> PWM2_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_2_pin_P12,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_set_PWM0_T1(0);<br> PWM_set_PWM0_T2(0);&nbsp;&nbsp;<br> PWM_set_PWM1_T1(0);<br> PWM_set_PWM1_T2(0);<br> PWM_set_PWM2_T1(0);<br> PWM_set_PWM2_T2(0);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To achieve smooth fading the duty cycle of each LED is mapped using a sine table and the duty cycles are varied according to the formula as have already seen. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"724\" height=\"81\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-51.png\" alt=\"\" class=\"wp-image-14846\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-51.png 724w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-51-580x65.png 580w\" sizes=\"auto, (max-width: 724px) 100vw, 724px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">However, there are phase shifts in all of these tables, meaning that the three PWM channels do not have the same duty cycle at the same time.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">const unsigned int duty1_value[steps] = {0, 950, 1892, 2817, 3717, 4582, 5407, 6182, 6901, 7558, 8146,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946};<br> &nbsp;<br> const&nbsp;unsigned&nbsp;int&nbsp;duty2_value[steps]&nbsp;=&nbsp;{8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;950,&nbsp;1892,&nbsp;2817,&nbsp;3717,&nbsp;4582,&nbsp;5407,&nbsp;6182,&nbsp;6901,&nbsp;7558,&nbsp;8146,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095};<br> &nbsp;<br> const&nbsp;unsigned&nbsp;int&nbsp;duty3_value[steps]&nbsp;=&nbsp;{8660,&nbsp;9096,&nbsp;9450,&nbsp;9718,&nbsp;9898,&nbsp;9988,&nbsp;9995,&nbsp;9897,&nbsp;9717,&nbsp;9449,&nbsp;9095,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8658,&nbsp;8144,&nbsp;7555,&nbsp;6898,&nbsp;6179,&nbsp;5403,&nbsp;4579,&nbsp;3713,&nbsp;2813,&nbsp;1888&nbsp;,946,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;950,&nbsp;1892,&nbsp;2817,&nbsp;3717,&nbsp;4582,&nbsp;5407,&nbsp;6182,&nbsp;6901,&nbsp;7558,&nbsp;8146}; <\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"400\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-52.png\" alt=\"\" class=\"wp-image-14847\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-52.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-52-580x247.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-52-768x327.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, the PWM channels are driven as per their respective sine tables.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;6;&nbsp;j++)<br> {<br> for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;steps;&nbsp;i++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM1_T2(duty2_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM2_T2(duty3_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;}<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_idle();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;6;&nbsp;j++)<br> {<br> &nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;steps;&nbsp;i++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM0_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM1_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_set_PWM2_T2(duty1_value[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;}<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_idle(); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note there is new function in this example unlike the last one. The <strong><em>PWM_idle <\/em><\/strong>function ensures that PWM channels are reset once it is called.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;PWM_idle(void)<br> {<br> &nbsp;&nbsp;PWM0_hold_level(PWM_HLD_L_low);<br> &nbsp;&nbsp;PWM1_hold_level(PWM_HLD_L_low);<br> &nbsp;&nbsp;PWM2_hold_level(PWM_HLD_L_low);&nbsp;<br> &nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;PWM0_hold_level(PWM_level_normal);<br> &nbsp;&nbsp;PWM1_hold_level(PWM_level_normal);<br> &nbsp;&nbsp;PWM2_hold_level(PWM_level_normal);&nbsp;&nbsp;<br> &nbsp;&nbsp;delay_ms(100);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"319\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Multi-Channel-PWM.jpg\" alt=\"\" class=\"wp-image-14975\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Multi-Channel-PWM.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Multi-Channel-PWM-580x314.jpg 580w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Multi-Channel Enhanced  PWM Example - Driving an RGB LED\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/4bA-ISSlyrQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Controlling a DC Motor with\nComplementary PWM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Complementary PWM is needed in many power system applications like three phase motor control, sine wave inverters, BLDC motor control, etc. STC8A8K64S4A12 fortunately adds features to generate complementary PWMs for the applications aforementioned. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"925\" height=\"653\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/C-PWM.jpg\" alt=\"\" class=\"wp-image-14851\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/C-PWM.jpg 925w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/C-PWM-580x409.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/C-PWM-768x542.jpg 768w\" sizes=\"auto, (max-width: 925px) 100vw, 925px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;dead_time_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;pwm_max_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;400&nbsp;<br> &nbsp;<br> #define&nbsp;PB_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P12_get_input<br> #define&nbsp;PB_2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!P13_get_input<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;set_PWM_duty(signed&nbsp;int&nbsp;value);<br> &nbsp;<br> void&nbsp;main(void)<br> {&nbsp;<br> &nbsp;&nbsp;signed&nbsp;int&nbsp;duty&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(PB_1)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;duty&nbsp;+=&nbsp;10;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(duty&nbsp;&gt;=&nbsp;pwm_max_cnt)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;duty&nbsp;=&nbsp;pwm_max_cnt;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(PB_2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;duty&nbsp;-=&nbsp;10;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(duty&nbsp;&lt;=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;duty&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(PB_1&nbsp;||&nbsp;PB_2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_PWM_duty(duty);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P12_input_mode;<br> &nbsp;&nbsp;P13_input_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_1);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_counter(pwm_max_cnt);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM1_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_1_pin_P11,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_start_counter;<br> }<br> &nbsp;<br> void&nbsp;set_PWM_duty(signed&nbsp;int&nbsp;value)<br> {&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM0_T1(value);<br> &nbsp;&nbsp;PWM_set_PWM0_T2(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM1_T1(pwm_max_cnt&nbsp;-&nbsp;dead_time_cnt);<br> &nbsp;&nbsp;PWM_set_PWM1_T2(value&nbsp;+&nbsp;dead_time_cnt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"543\" height=\"290\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Complementary-PWM.png\" alt=\"\" class=\"wp-image-14852\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Since complementary PWM is a requirement for proper motor drive, the demo here is a rudimentary DC motor drive example with STC\u2019s complementary PWM and a L293 motor driver. The motor\u2019s speed is governed by PWM duty cycle alternation. Pressing buttons assigned with pins P1.2 and P1.3 changes motor speed. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 12MHz. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same clock is used by the enhanced PWM module. Most of the stuffs in the setup are like the previous PWM examples.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;dead_time_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;pwm_max_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;400&nbsp;<br> &nbsp;<br> ....<br> &nbsp;<br> PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_1);<br> &nbsp;&nbsp;<br> PWM_set_counter(pwm_max_cnt);<br> &nbsp;&nbsp;<br> PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> PWM1_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_1_pin_P11,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PWM_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The math behind PWM generation is same as the ones we have already seen:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"188\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-54.png\" alt=\"\" class=\"wp-image-14853\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-54.png 731w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-54-580x149.png 580w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The logic analyser data proves that the above figures are correct:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"904\" height=\"616\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-55.png\" alt=\"\" class=\"wp-image-14854\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-55.png 904w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-55-580x395.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-55-768x523.png 768w\" sizes=\"auto, (max-width: 904px) 100vw, 904px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now imagine a SR flip-flop with outputs <strong><em>T1<\/em><\/strong> and <strong><em>T2<\/em><\/strong>. So far, we have seen that varying T1 and T2 alter PWM duty cycle. Thus, <strong><em>S<\/em><\/strong> and <strong><em>R<\/em><\/strong> can be imagined as logic transition counts. When the PWM counter reaches up to these values, high-to-low or low-to-high transition occurs in the PWM waveform. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"273\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-56.png\" alt=\"\" class=\"wp-image-14855\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To generate complementary PWM, we would need two PWM channels and so in this example PWM channels 0 and 1 are selected. The word \u201c<em>complementary<\/em>\u201d suggests that two things are opposite of the other and so in such PWM technique, there are two PWMs that have opposite logic polarities. This is the simplistic presentation of complementary PWM.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In ideal terms, if one PWM channel is running with 40% duty cycle, the other should be running at 60% (-40%) duty cycle. However, doing so practically would lead to some issues because when one PWM is going from high-to-low transition, the other is doing just the opposite and during these transition times at some point both PWMs are at same logic level. If these PWMs are fed to external devices like transistors or MOSFETs as shown below then quite possibly during the transition times both MOSFETs would be momentarily turn on, leading to temporary short-circuit and unnecessary overheating. The temporal short circuit may even cause the external devices to get damaged or cause momentary power shortages. To avoid this phenomenon, we have to apply dead-time technique to ensure that the transitions occur separately with some minute delay.&nbsp;&nbsp;  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"306\" height=\"360\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-57.png\" alt=\"\" class=\"wp-image-14856\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"621\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-58.png\" alt=\"\" class=\"wp-image-14857\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-58.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-58-580x383.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-58-768x507.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see how the PWM duty cycle is ensured while maintaining the needs so far discussed. The following code snippet is responsible for maintaining PWM duty cycles in complementary format. It may look confusing unlike the previous examples. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;dead_time_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;pwm_max_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;400&nbsp;<br> &nbsp;<br> ....<br> &nbsp;<br> void&nbsp;set_PWM_duty(signed&nbsp;int&nbsp;value)<br> {&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM0_T1(value); <br> &nbsp;&nbsp;PWM_set_PWM0_T2(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM1_T1(pwm_max_cnt&nbsp;-&nbsp;dead_time_cnt);<br> &nbsp;&nbsp;PWM_set_PWM1_T2(value&nbsp;+&nbsp;dead_time_cnt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The confusion will vanish after carefully looking at the math below. Imagine that we want to set the duty cycle to 75%. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"732\" height=\"180\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-59.png\" alt=\"\" class=\"wp-image-14858\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-59.png 732w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-59-580x143.png 580w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">As the math shows due to the application of dead-time, PWM1\u2019s duty cycle is slightly less than the ideal 25% mark. In this example, 1 count of dead time is equivalent to 0.25% duty cycle and since there are two such counts the total duty cycle is reduced by 0.5%. &nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"444\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-60.png\" alt=\"\" class=\"wp-image-14859\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-60.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-60-580x279.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-60-768x370.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 -Complementary Enhanced PWM with Dead Time Example - Controlling a DC Motor\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/vdJJhtsgocE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA to Measure Frequency<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Frequency measurement is often a challenging task as it requires good understanding of timers and input capture modules. Frequency measurement becomes very important while designing power electronics devices like generator controllers, inverters, power line measurement meters, etc. In STC8A8K64S4A12, there is no dedicated input capture hardware module but there is a PCA module that can be used to replenish this absence of a dedicated input capture peripheral. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"559\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/frequency-1024x559.jpg\" alt=\"\" class=\"wp-image-14861\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/frequency-1024x559.jpg 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/frequency-580x317.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/frequency-768x419.jpg 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/frequency.jpg 1064w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> unsigned&nbsp;int&nbsp;first_edge&nbsp;=&nbsp;0x0000;<br> unsigned&nbsp;int&nbsp;second_edge&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> unsigned&nbsp;long&nbsp;clks&nbsp;=&nbsp;0x00000000;<br> unsigned&nbsp;long&nbsp;ov_cnt&nbsp;=&nbsp;0x00000000;<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(check_PCA_Counter_overflow_flag)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ov_cnt++;;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_Counter_overflow_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;second_edge&nbsp;=&nbsp;PCA_get_CCAP0();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clks&nbsp;=&nbsp;((65536 * ov_cnt)&nbsp;+&nbsp;second_edge&nbsp;-&nbsp;first_edge);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ov_cnt&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first_edge&nbsp;=&nbsp;second_edge;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;second_edge&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;float&nbsp;f&nbsp;=&nbsp;0.0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"Period\/ms:\");<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"Freq.\/kHz:\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_stop_counter;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(s)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_1);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_3);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_start_counter;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;=&nbsp;(12000.0&nbsp;\/&nbsp;((float)clks));<br> &nbsp;&nbsp;&nbsp;&nbsp;print_I(11,&nbsp;0,&nbsp;clks);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;1,&nbsp;f,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(s&nbsp;&gt;&nbsp;3)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_counter(500);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_set_PWM0_T1(0);<br> &nbsp;&nbsp;PWM_set_PWM0_T2(200);&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PWM_start_counter;<br> &nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;PCA_load_counter(0x0000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_mode(PCA_16_bit_falling_edge_capture);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_PCA_0_interrupt;<br> &nbsp;&nbsp;_enable_PCA_counter_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"301\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Frequency-Measurement.png\" alt=\"\" class=\"wp-image-14862\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Frequency-Measurement.png 741w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Frequency-Measurement-580x236.png 580w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Measurement of frequency can easily be done by timing the time difference between two successive rising or falling edge captures. Input capture hardware along with a timer would scan and sample incoming waveform. Thus, input capture hardware must have at least twice the sampling frequency than the frequency of the waveform coming to the capture input. This is simply the Nyquist criterion.&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"212\" height=\"54\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-61.png\" alt=\"\" class=\"wp-image-14863\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To demonstrate frequency measurement with PCA, I have used two hardware. Firstly, I used a PWM generator to generate waveform of different frequencies and secondly, a PCA module to capture the PWM waveform. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To begin with, note that the micro is running at 12MHz.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"> The PWM peripheral is setup with P1.0 pin as PWM channel 0. The initial frequency of the PWM is 12kHz and the duty cycle is about 60%.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PWM0_setup(PWM_pin_is_PWM_output,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_init_lvl_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_0_pin_P10,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWM_level_normal);<br> &nbsp;&nbsp;<br> PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);&nbsp;&nbsp;<br> PWM_set_counter(500);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> PWM_set_PWM0_T1(0);<br> PWM_set_PWM0_T2(300);&nbsp;<br> &nbsp;&nbsp;<br> PWM_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The following equations show us how we fabricated this frequency and duty cycle:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"196\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-62.png\" alt=\"\" class=\"wp-image-14864\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-62.png 721w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-62-580x158.png 580w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"879\" height=\"360\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Capture.jpg\" alt=\"\" class=\"wp-image-14865\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Capture.jpg 879w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Capture-580x238.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Capture-768x315.jpg 768w\" sizes=\"auto, (max-width: 879px) 100vw, 879px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, the PWM frequency if changed four times and these frequencies are 24kHz, 12kHz, 8kHz and 6kHz. The change is done about every two seconds. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now let us see how we\nhave to setup the PCA\u2019s capture part. P1.7 pin (PCA0) is setup as the capture\npin that would look for falling edges. PCA hardware clock is running at full\nsystem clock speed of 12MHz. The Nyquist criterion is fulfilled because PWM out\nfrequency is not more than 24kHz. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_pin_option(0x00);<br> &nbsp;<br> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> PCA_load_counter(0x0000);<br> &nbsp;&nbsp;<br> PCA_0_mode(PCA_16_bit_falling_edge_capture);<br> &nbsp;&nbsp;<br> _enable_PCA_0_interrupt;<br> _enable_PCA_counter_interrupt;<br> _enable_global_interrupt;&nbsp;&nbsp;<br> &nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">PCA interrupt will be triggered when a falling edge is detected or when there is PCA counter overflows. Both of these events will be needed. Though under a same interrupt subroutine, these events are differentiated by two separate flags. The first will be needed to make sure that we took account of any PCA overflow in between two successive captures and the second will be needed to snap PCA counter count at the moment of falling-edge detection.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(check_PCA_Counter_overflow_flag)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ov_cnt++;;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_Counter_overflow_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;second_edge&nbsp;=&nbsp;PCA_get_CCAP0();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clks&nbsp;=&nbsp;((65536 * ov_cnt)&nbsp;+&nbsp;second_edge&nbsp;-&nbsp;first_edge);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ov_cnt&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first_edge&nbsp;=&nbsp;second_edge;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;second_edge&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When PCA interrupt occurs, two flags are checked. Firstly, the PCA counter overflow is checked and secondly, PCA0 interrupt flag is checked. If PCA counter overflow occurs then it is saved in a variable. This will mark that an overflow event occurred during a snap.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since frequency measurement is done by measuring the PCA counter\u2019s count difference between two consecutive falling edges, we need to assume that the first capture is basically the second capture instead of the first falling edge capture. When the second capture is recorded, it is measured against the first one. In this measurement, we also have to take note if any PCA overflow occurred during the captures. Note that no timer has been used so far and that is because the PCA module is doubling as a timer here. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, the PWM frequencies are changed periodically and the PWM frequencies are measured. The measured frequency is displayed on an LCD.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PWM_stop_counter;<br> &nbsp;<br> switch(s)<br> {<br> &nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_1);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;{<br> &nbsp; &nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_3);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> default:<br> &nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;PWM_clk_set(PWM_clk_sys_PS,&nbsp;PWM_clk_ps_sys_clk_div_2);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> PWM_start_counter;<br> delay_ms(1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> f&nbsp;=&nbsp;(12000.0&nbsp;\/&nbsp;((float)clks));<br> print_I(11,&nbsp;0,&nbsp;clks);&nbsp;&nbsp;<br> print_F(11,&nbsp;1,&nbsp;f,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> delay_ms(1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> s++;<br> if(s&nbsp;&gt;&nbsp;3)<br> {<br> &nbsp;&nbsp;s&nbsp;=&nbsp;0;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"> Variable <strong><em>clks <\/em><\/strong>represents the count difference between capture snaps and so dividing PCA clock frequency with this count gives capture waveform frequency in hertz. I have coded 12000 instead of 12000000 as clock frequency because I want measurements to be in kHz instead of Hz.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo <\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"452\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-63.png\" alt=\"\" class=\"wp-image-14866\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-63.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-63-580x284.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-63-768x377.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA Input Capture Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/2uYhZw7FXSE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA to Measure Pulse Width\nfrom HCSR-04 SONAR Module<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Apart from frequency measurement, we can apply the same input capture technique to measure pulse widths or PWM duty cycles. Pulse width measurement requires capturing PCA counts of two successive opposite edges unlike two successive same edges. In this segment, we will see how we can measure distance measured by a HCSR-04 SONAR sensor by measuring pulse width output from it. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"696\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-64.png\" alt=\"\" class=\"wp-image-14868\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-64.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-64-580x429.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-64-768x569.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> unsigned&nbsp;char&nbsp;state&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;int&nbsp;pulse_width&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;^=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;switch(state)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_load_counter(0x0000);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pulse_width&nbsp;=&nbsp;PCA_get_CCAP0();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;float&nbsp;range&nbsp;=&nbsp;0.0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"Range\/cm:\");&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;LCD_putstr(\"Pulse\/us:\");&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P16_high;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(10);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P16_low;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;range&nbsp;=&nbsp;((((float)pulse_width)&nbsp;\/&nbsp;58.0));&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;print_F(10,&nbsp;0,&nbsp;range,&nbsp;1);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;print_I(10,&nbsp;1,&nbsp;pulse_width);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(490);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P16_push_pull_mode;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_12);<br> &nbsp;&nbsp;PCA_load_counter(0x0000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_mode(PCA_16_bit_both_edge_capture);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_PCA_0_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"781\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PWM-Measurement.png\" alt=\"\" class=\"wp-image-14869\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PWM-Measurement.png 781w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PWM-Measurement-580x217.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PWM-Measurement-768x287.png 768w\" sizes=\"auto, (max-width: 781px) 100vw, 781px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">HC-SR04 SONAR sensor works by sending a stream of ultrasonic pulses and then timing how long it took for an echo to bounce back from a nearby object. Based on timing, the sensor gives a pulse of variable width. The pulse width is a representation of distance or object range. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"432\" height=\"261\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-65.png\" alt=\"\" class=\"wp-image-14870\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">There are two pins apart from the power supply pins and these are needed to communicate with the sensor. When the trigger pin of the sensor is pulled high for about 10\u03bcs, the sensor acknowledges this short duration pulse as a command from its host micro to measure and return range data. A pulse output from the echo pin is the representation of distance.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-66.png\" alt=\"\" class=\"wp-image-14871\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-66.png 756w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-66-580x224.png 580w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see how the code is working in this example. Firstly, the system clock is set to 12MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pins P1.6 and P1.7 are tied to trigger and echo pins of HC-SR04 sensor respectively.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The PCA hardware is setup by setting its clock to 1MHz. Thus, each of PCA counter\u2019s count is equal to 1\u03bcs tick. Default PCA pin configuration is used. The PCA counter is set to 0 count and 16-bit both edge capture mode is selected. Interrupt method is used and so PCA and global interrupts are enabled before starting the PCA counter.&nbsp;  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_pin_option(0x00);<br> &nbsp;&nbsp;<br> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_12);<br> PCA_load_counter(0x0000);<br> &nbsp;&nbsp;<br> PCA_0_mode(PCA_16_bit_both_edge_capture);<br> &nbsp;<br> _enable_PCA_0_interrupt;<br> _enable_global_interrupt;&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The PCA hardware is now ready to detect edge transitions. When transitions occur, PCA interrupt is triggered. During a low-to-high transition or rising edge, the PCA counter is reset to 0 count and left to continue counting. Upon detecting a high-to-low transition or falling edge, the PCA counter is read.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;^=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;switch(state)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_load_counter(0x0000);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pulse_width&nbsp;=&nbsp;PCA_get_CCAP0();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"734\" height=\"255\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-67.png\" alt=\"\" class=\"wp-image-14872\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-67.png 734w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-67-580x201.png 580w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Since the PCA counter is counting with 1\u00b5s resolution, the falling edge capture count is the pulse width period in microseconds.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"724\" height=\"77\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-68.png\" alt=\"\" class=\"wp-image-14873\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-68.png 724w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-68-580x62.png 580w\" sizes=\"auto, (max-width: 724px) 100vw, 724px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the main loop, the SONAR sensor is triggered and the result from the PCA interrupt is processed. Target object distance detected by the sensor is a function of pulse width measured in microseconds. Thus, as per datasheet of the sensor, pulse width divided by 58 is equal to distance in centimeters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"725\" height=\"96\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-69.png\" alt=\"\" class=\"wp-image-14874\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-69.png 725w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-69-580x77.png 580w\" sizes=\"auto, (max-width: 725px) 100vw, 725px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"> The range and the captured pulse width are displayed in an LCD after performing the aforementioned computations. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P55_low;<br> delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> P16_high;&nbsp;<br> delay_us(10);&nbsp;<br> P16_low;&nbsp;<br> P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> range&nbsp;=&nbsp;((((float)pulse_width)&nbsp;\/&nbsp;58.0));&nbsp;<br> print_F(10,&nbsp;0,&nbsp;range,&nbsp;1);&nbsp;<br> print_I(10,&nbsp;1,&nbsp;pulse_width);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> delay_ms(490); <br><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"441\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-70.png\" alt=\"\" class=\"wp-image-14875\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-70.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-70-580x277.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-70-768x367.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA Pulse Width Capture Example - Using PCA to Find Distance from a HCSR-04\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/h8NIdGpSZLI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA to Generate PWM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike enhanced PWM module, PCA module\ncan used to generate PWMs of different resolutions. However, PCA-generated PWMs\nare like general purpose PWMs and do not have additional functionalities. These\nPWMs can be used for simple tasks like driving LEDs, servo motors, simple motor\ncontrols, simple DC-DC converters, etc.&nbsp;&nbsp;\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The following block diagram shows PCA module in 8-bit PWM mode. The 9-bit internal comparator compares the values <em>CL<\/em> and <em>CCAPnL + EPCnL. <\/em>When <em>CL <\/em>is equal or greater than <em>CCAPnL + EPCnL<\/em>, the PWM output is set high and when<em> CL <\/em>is less than <em>CCAPnL + EPCnL<\/em>, the PWM output is set low. Thus, <em>CCAPnL + EPCnL <\/em>are responsible for the duty cycle of PWM because <em>CL<\/em> keeps counting with each tick of PCA clock. When <em>CL<\/em> overflows, <em>CCAPnL + EPCnL<\/em> are reloaded automatically with the contents of <em>CCAPnH + EPCnH. <\/em>Updating <em>CCAPnH + EPCnH<\/em>, results in the alternation of PWM duty cycle. The same concept is true for PCA PWMs of other resolutions. Similar strategies are applied for PCA PWMs of other resolutions.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"488\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-71.png\" alt=\"\" class=\"wp-image-14877\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-71.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-71-580x301.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-71-768x399.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;PWM_idle(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;signed&nbsp;int&nbsp;j&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;256;&nbsp;j++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_0_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_1_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_2_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_3_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(j&nbsp;=&nbsp;255;&nbsp;j&nbsp;&gt;&nbsp;-1;&nbsp;j--)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_0_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_1_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_2_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCA_3_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x10);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_n_PWM(0,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> &nbsp;&nbsp;PCA_n_PWM(1,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> &nbsp;&nbsp;PCA_n_PWM(2,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> &nbsp;&nbsp;PCA_n_PWM(3,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_8_bit_PWM_compare_value(0);&nbsp;<br> &nbsp;&nbsp;PCA_0_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_1_8_bit_PWM_compare_value(0);&nbsp;<br> &nbsp;&nbsp;PCA_1_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_2_8_bit_PWM_compare_value(0);&nbsp;<br> &nbsp;&nbsp;PCA_2_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_3_8_bit_PWM_compare_value(0);&nbsp;<br> &nbsp;&nbsp;PCA_3_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_load_counter(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"621\" height=\"376\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-PWM.png\" alt=\"\" class=\"wp-image-14878\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-PWM.png 621w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-PWM-580x351.png 580w\" sizes=\"auto, (max-width: 621px) 100vw, 621px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, four PCA PWM channels are simply\nused to drive LEDs of different colors. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 12MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pins P2.3 to P2.6 are used for PWM outputs. Each of these channels are set to 8-bit PWM mode and their compare and reload values are set to zero. Thus, initially all PWM channels are at same logic state. The PCA counter is set to run at system clock speed. All PWM channels will be running at same clock frequency as all are sharing the same PCA counter.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_pin_option(0x10);<br> &nbsp;<br> \/*<br> ECI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CCP0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CCP1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CCP2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CCP3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P1.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P2.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> P7.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;3<br> P3.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;4<br> *\/<br> &nbsp;<br> &nbsp;&nbsp;<br> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> PCA_n_PWM(0,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> PCA_n_PWM(1,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> PCA_n_PWM(2,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> PCA_n_PWM(3,&nbsp;PCA_PWM_without_interrupt,&nbsp;PCA_8_bit_PWM);<br> &nbsp;&nbsp;<br> PCA_0_8_bit_PWM_compare_value(0);&nbsp;<br> PCA_0_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PCA_1_8_bit_PWM_compare_value(0);&nbsp;<br> PCA_1_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PCA_2_8_bit_PWM_compare_value(0);&nbsp;<br> PCA_2_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PCA_3_8_bit_PWM_compare_value(0);&nbsp;<br> PCA_3_8_bit_PWM_reload_value(0);&nbsp;&nbsp;<br> &nbsp;&nbsp;<br> PCA_load_counter(0);<br> &nbsp;&nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The PWM frequency of PCA channels is calculated to be as follows.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"727\" height=\"216\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-72.png\" alt=\"\" class=\"wp-image-14879\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-72.png 727w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-72-580x172.png 580w\" sizes=\"auto, (max-width: 727px) 100vw, 727px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Thus, the period of the PWM is 21.33\u00b5s. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The logic analyser data confirms that the frequency is indeed around 46 kHz.  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"602\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-73.png\" alt=\"\" class=\"wp-image-14880\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-73.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-73-580x371.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-73-768x492.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The duty cycles of the PWMs are calculated using the following formula.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"715\" height=\"93\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-74.png\" alt=\"\" class=\"wp-image-14881\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-74.png 715w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-74-580x75.png 580w\" sizes=\"auto, (max-width: 715px) 100vw, 715px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the main loop, each of the channels are updated every 10ms by updating their reload values.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> for(j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;256;&nbsp;j++)<br> {<br> &nbsp;&nbsp;PCA_0_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;PCA_1_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;PCA_2_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;PCA_3_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;delay_ms(10);<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> for(j&nbsp;=&nbsp;255;&nbsp;j&nbsp;&gt;&nbsp;-1;&nbsp;j--)<br> {<br> &nbsp;&nbsp;PCA_0_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;PCA_1_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;PCA_2_8_bit_PWM_reload_value(255&nbsp;-&nbsp;j);<br> &nbsp;&nbsp;PCA_3_8_bit_PWM_reload_value(j);<br> &nbsp;&nbsp;delay_ms(10);<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"334\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-75.png\" alt=\"\" class=\"wp-image-14882\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-75.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-75-580x210.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-75-768x278.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA PWM Mode Example - Breathing LEDs\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/EqEjFmxBRSg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA as a High-Speed Pulse\nGenerator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In many cases, we need to generate high-frequency carrier waveform or pulse trains. For example, this is needed when we need to make an infrared (IR) remote transmitter. This job can easily be done by using a timer or software delays. However, in STC micros, we have PCA hardware to accomplish the same job much more easily. This lets us use general purpose timers for other tasks. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"349\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/High-Speed-Pulse-Mode.jpg\" alt=\"\" class=\"wp-image-14883\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/High-Speed-Pulse-Mode.jpg 693w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/High-Speed-Pulse-Mode-580x292.jpg 580w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;freq_change&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(12000000L&nbsp;\/&nbsp;2&nbsp;\/ 38400)<br> &nbsp;<br> unsigned&nbsp;int&nbsp;value&nbsp;=&nbsp;freq_change;<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;PCA0_load_value(value);<br> &nbsp;&nbsp;value&nbsp;+=&nbsp;freq_change;<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(P52_get_input&nbsp;==&nbsp;FALSE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P24_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P24_low;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_high;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P01_push_pull_mode;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P52_input_mode;<br> &nbsp;&nbsp;P52_pull_up_enable;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x10);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_mode(PCA_16_bit_high_speed_pulse_output);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_load_counter(0);<br> &nbsp;&nbsp;PCA0_load_value(value);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_PCA_0_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-High-Speed-Pulse-Mode.png\" alt=\"\" class=\"wp-image-14884\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-High-Speed-Pulse-Mode.png 644w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-High-Speed-Pulse-Mode-580x263.png 580w\" sizes=\"auto, (max-width: 644px) 100vw, 644px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, PCA high-speed pulse mode is used to make an IR remote transmitter.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since PCA is a time-dependent hardware peripheral, we need to be sure of the system clock settings. As with most examples, the system clock is set to 12MHz <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Four GPIO pins are required for this example and are set right after selecting the system clock. A button is connected with pin P5.2. Pressing the button would change the logic state of both the onboard LED (P5.5) and pin P2.4. Lastly, pin P2.3 is set as the PCA CCP0 pin. This pin is the high-speed pulse output pin. P2.3 and P2.4 are connected to an IR LED.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that P2.4 is not set like other GPIOs because it is already set by PCA hardware.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P01_push_pull_mode;<br> P55_open_drain_mode;<br> &nbsp;&nbsp;<br> P52_input_mode;<br> P52_pull_up_enable;<br> &nbsp;&nbsp;<br> PCA_pin_option(0x10); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see how the PCA hardware is set. Firstly, the PCA clock and counting mode are set. PCA clock is set to run at 12MHz, i.e., at system clock speed. Next, the PCA channel to be used and its mode of operation is set, here \u2013 16-bit high speed pulse output mode. The PCA counter is set 0 count and PCA0 channel is loaded with a count value. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> PCA_0_mode(PCA_16_bit_high_speed_pulse_output);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PCA_load_counter(0);<br> PCA0_load_value(value);<br> &nbsp;&nbsp;<br> _enable_PCA_0_interrupt;<br> _enable_global_interrupt;<br> &nbsp;&nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The loaded value is the count value required to generate the desired frequency of 38.4kHz (26\u00b5s period). <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"205\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-76.png\" alt=\"\" class=\"wp-image-14885\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-76.png 738w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-76-580x161.png 580w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, the PCA0 and global interrupts are enabled before starting the PCA counter.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"414\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-77.png\" alt=\"\" class=\"wp-image-14886\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-77.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-77-580x255.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-77-768x338.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Note that PCA counter keeps counting and is not reloaded anywhere in the whole code. It is left on its own and it will rollover after 65535 counts. When the PCA counter counts to 156 counts, PCA0 interrupt is triggered. Note that 156 counts equal 13\u00b5s because the PCA clock is running at 12MHz. On each interrupt, PCA0&#8217;s channel polarity is altered. This means 13\u00b5s is the pulse width of high-speed pulse output waveform.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"83\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-78.png\" alt=\"\" class=\"wp-image-14887\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-78.png 728w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-78-580x66.png 580w\" sizes=\"auto, (max-width: 728px) 100vw, 728px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">PCA interrupt is processed by clearing PCA0 interrupt flag and by loading PCA0 with a new count value (previous count + load value, i.e., 156 + 156 = 312) because after that new count (312) PCA0 interrupt will be triggered again and the process repeats over and over again.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;PCA0_load_value(value);<br> &nbsp;&nbsp;value&nbsp;+=&nbsp;freq_change;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the main loop, the push button pin is polled. If the button is pressed, the IR LED is enabled by setting P2.4 high or else it is disabled. Since P2.3 is the PCA 0 output, there is always 38.4 kHz square pulses present in that pin. Only when P2.4 is set is high, the IR LED lights up. It is just like a simple AND logic.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">if(P52_get_input == FALSE)<br> {<br>   P24_high;<br>   P55_low;<br> }<br> else<br> {<br>   P24_low;<br>   P55_high;<br> }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"376\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/PCA-High-Speed-Timer.jpg\" alt=\"\" class=\"wp-image-14890\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/PCA-High-Speed-Timer.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/PCA-High-Speed-Timer-580x370.jpg 580w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA High Speed Pulse Output Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/V9xbGAijxjQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA as a Software Timer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We have already seen how the PCA module doubles as timer in the capture examples. However, unlike actual hardware timers, we would have to use some software tricks and keep certain things in mind. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"631\" height=\"317\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/sw-tmr.jpg\" alt=\"\" class=\"wp-image-14892\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/sw-tmr.jpg 631w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/sw-tmr-580x291.jpg 580w\" sizes=\"auto, (max-width: 631px) 100vw, 631px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> #define&nbsp;T_Load&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1000000L&nbsp;\/&nbsp;12&nbsp;\/&nbsp;2)<br> &nbsp;<br> unsigned&nbsp;int&nbsp;value&nbsp;=&nbsp;T_Load;<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;PCA0_load_value(value);<br> &nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;value&nbsp;+=&nbsp;T_Load;<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;24,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x10);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_12);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_mode(PCA_16_bit_software_timer);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_load_counter(0);<br> &nbsp;&nbsp;PCA0_load_value(T_Load);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_PCA_0_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"308\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Software-Timer.png\" alt=\"\" class=\"wp-image-14893\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Software-Timer.png 595w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Software-Timer-580x300.png 580w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This example uses the same\nconcepts as in the high-speed pulse output example and yes, again it is a\nsimple onboard LED blinking example. Between the two examples almost everything\nis same. &nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 1MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">CLK_set_sys_clk(IRC_24M, 24, MCLK_SYSCLK_no_output, MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">PCA is setup with just as in the past example except for the clock prescalar and mode of operation. In this example, the PCA clock is set to 83.3kHz and software timer mode is selected. Note that since no PCA input-output channel is needed in this example, it doesn\u2019t matter which pin arrangement is initialized. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_pin_option(0x10);<br> &nbsp;&nbsp;<br> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_12);<br> &nbsp;&nbsp;<br> PCA_0_mode(PCA_16_bit_software_timer);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PCA_load_counter(0);<br> PCA0_load_value(T_Load); <br> &nbsp;&nbsp;<br> _enable_PCA_0_interrupt;<br> _enable_global_interrupt;<br> &nbsp;&nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The desired LED blinking frequency is 1Hz and so the PCA0 is loaded with the following count value.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"285\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-80.png\" alt=\"\" class=\"wp-image-14894\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-80.png 728w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-80-580x227.png 580w\" sizes=\"auto, (max-width: 728px) 100vw, 728px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Since we are toggling the onboard LED, every half second, it will change its state and so the toggling frequency is 1 Hz. &nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"377\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-81.png\" alt=\"\" class=\"wp-image-14895\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-81.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-81-580x233.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-81-768x308.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Note there is no operation in the main loop.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"658\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-82.png\" alt=\"\" class=\"wp-image-14896\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-82.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-82-580x414.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-82-768x548.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA Software Timer Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/QuXtghib1KQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Using PCA to Extend External Interrupt Capability<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An alternative way of using the hardware PCA module is to use it to extend external interrupt capability of our STC micro.&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"571\" height=\"319\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/exti.jpg\" alt=\"\" class=\"wp-image-14898\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_low;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;if(check_PCA_1_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_1_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_high;<br> &nbsp;&nbsp;}&nbsp;&nbsp;<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P54_push_pull_mode;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_pin_option(0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_0_mode(PCA_16_bit_falling_edge_capture);<br> &nbsp;&nbsp;PCA_1_mode(PCA_16_bit_falling_edge_capture);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_load_counter(0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_PCA_0_interrupt;<br> &nbsp;&nbsp;_enable_PCA_1_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;PCA_start_counter;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-Interrupt.png\" alt=\"\" class=\"wp-image-14899\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-Interrupt.png 644w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-PCA-Interrupt-580x263.png 580w\" sizes=\"auto, (max-width: 644px) 100vw, 644px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Perhaps this is the one and only PCA module example that doesn\u2019t require precise selection of timing parameters and so we will directly go to PCA settings. In this example, a LED connected to pin P5.4 is either turned on or off using two buttons. These buttons are attached to default PCA channel 0 and 1 pins.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> PCA_pin_option(0x00);<br> &nbsp;&nbsp;<br> PCA_setup(PCA_continue_counting_in_idle_mode,&nbsp;PCA_clk_sys_clk_div_1);<br> &nbsp;&nbsp;<br> PCA_0_mode(PCA_16_bit_falling_edge_capture);<br> PCA_1_mode(PCA_16_bit_falling_edge_capture);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> PCA_load_counter(0);<br> &nbsp;&nbsp;<br> _enable_PCA_0_interrupt;<br> _enable_PCA_1_interrupt;<br> _enable_global_interrupt;<br> &nbsp;&nbsp;<br> PCA_start_counter; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both PCA channel input pins are set to\ncapture falling edges. It is not mandatory to use falling edge capture. In this\ncase however, I used so because the buttons have external pullup resistors and\nso pressing them would lead to a high-to-low pin transition or falling edge. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The whole PCA setup seem to look like PCA\ncapture mode setup but the exception is the fact that we won\u2019t be needing the\ncapture counts this time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The state of the P5.4 LED is altered inside PCA interrupt subroutine and everything will appear as if the things are being done with external interrupts. Note that though this external interrupt technique works just like ordinary external interrupts, there is no way of setting interrupt priorities amongst PCA channels themselves.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;PCA_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;7<br> {<br> &nbsp;&nbsp;if(check_PCA_0_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_0_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_low;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;if(check_PCA_1_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;clear_PCA_1_flag;<br> &nbsp;&nbsp;&nbsp;&nbsp;P54_high;<br> &nbsp;&nbsp;}&nbsp;&nbsp;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The only task that is done in the main loop is a simple onboard LED blinking. This is not a must but this is only needed to show that PCA operations are done without blocking anything of the main loop.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P55_toggle;<br> delay_ms(400); <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"366\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-83.png\" alt=\"\" class=\"wp-image-14900\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-83.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-83-580x230.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-83-768x305.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - PCA External Interrupt Capability Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/w9Ys7HBVvPQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Watchdog Timer (WDT)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As with any other microcontroller, reset has many sources and watchdog timer is one of them. STC8A8K64S4A12\u2019s watchdog timer is a typical independent watchdog timer that will reset the MCU core in the event of an unforeseen software failure. The watchdog timer of STC8A8K64S4A12 has no alternative use. In some other microcontroller families like TI MSP430s, watchdog timer can be used like an ordinary timer.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"249\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wdt-1024x249.jpg\" alt=\"\" class=\"wp-image-14901\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wdt-1024x249.jpg 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wdt-580x141.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wdt-768x187.jpg 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wdt.jpg 1078w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P11_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(P52_get_input&nbsp;==&nbsp;FALSE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;=&nbsp;9;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(200);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WDT_reset;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_input_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P52_pull_up_enable;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P10_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P11_push_pull_mode;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;WDT_setup(WDT_continue_counting_in_idle_mode,&nbsp;WDT_div_factor_32);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WDT.png\" alt=\"\" class=\"wp-image-14902\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WDT.png 644w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WDT-580x263.png 580w\" sizes=\"auto, (max-width: 644px) 100vw, 644px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For demoing WDT functionality, a simple LED blinking code is used. Two LEDs are used \u2013 one with pin P1.0 and the other with P1.1. P5.2 pin is used for a push button and the system clock is set at 12MHz.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M, 2, MCLK_SYSCLK_no_output, MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> P52_input_mode;<br> P52_pull_up_enable;<br> &nbsp;&nbsp;<br> P10_push_pull_mode;<br> P11_push_pull_mode;&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12\u2019s WDT is dependent on system\nclock and this is an old concept. I say it is primitive concept because many\nmicrocontrollers nowadays use a totally independent clock for WDT. Having an\nindependent clock for WDT reduces the chance of WDT getting affected by issues\nwith main or system clock. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">WDT is setup according to the following formula:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"795\" height=\"112\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-84.png\" alt=\"\" class=\"wp-image-14903\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-84.png 795w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-84-580x82.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-84-768x108.png 768w\" sizes=\"auto, (max-width: 795px) 100vw, 795px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"> From the formula, we can clearly see that WDT overflow timing is dependent on WDT prescalar and system clock. The following table shows some typical values.  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"465\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-85.png\" alt=\"\" class=\"wp-image-14904\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-85.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-85-580x287.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-85-768x380.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In this code, a prescalar value of 32 is set with 12MHz system clock. Thus, the WDT will reset after about one second if not refreshed or reset. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> WDT_setup(WDT_continue_counting_in_idle_mode,&nbsp;WDT_div_factor_32); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the main loop, a LED connected to pin P1.1 is toggled every 200ms while P1.0 LED is kept turned on. The WDT is kept resetting continuously under this condition and it does not overflow.&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> P11_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> if(P52_get_input&nbsp;==&nbsp;FALSE)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;=&nbsp;9;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1);<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> delay_ms(200);&nbsp;&nbsp;&nbsp;<br> WDT_reset;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If, however, P5.2 push button is pressed, the code enters a new loop which simulates an undesired condition. In this condition the state of P1.1 LED seems to get stuck. P1.0 LED flashes briefly, suggesting the code entered undesired loop and WDT is not being reset. Thus, after one second the CPU resets and P1.1 LED again starts to toggle. This suggests that the WDT has triggered a reset due to its overflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly before signing off from this topic, please note the following setting in programmer GUI. These can also be set in the GUI too apart from coding.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"509\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-86.png\" alt=\"\" class=\"wp-image-14905\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-86.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-86-580x314.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-86-768x416.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"394\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-87.png\" alt=\"\" class=\"wp-image-14906\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-87.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-87-580x248.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-87-768x328.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Watchdog Timer Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/0EyRSlsJx-g?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Wakeup Timer and Low Power Mode<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wakeup timer is an interesting feature that is not seen in most microcontrollers. It allows us to automatically wakeup a microcontroller from sleep or low power mode after a fixed interval. It is especially useful in cases where we need to take periodic short measurements and then keep our device in low power state to conserve power. A good example is a refrigerator temperature controller. The temperature controller would periodically check interior temperature and decide when to operate the compressor for cooling. Since the compressor would work for short times, the control system of the refrigerator need not to be kept active all the times. Periodic short measurements are all that are needed. This, in turn, would help in energy saving. This tactic becomes even more vital if refrigerator of the discussion is battery-operated.&nbsp; &nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"918\" height=\"92\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wkt.jpg\" alt=\"\" class=\"wp-image-14908\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wkt.jpg 918w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wkt-580x58.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/wkt-768x77.jpg 768w\" sizes=\"auto, (max-width: 918px) 100vw, 918px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WKT_disable;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;=&nbsp;15;&nbsp;i++)&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WKT_enable;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Go_to_Power_Down_State;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;WKT_set_interval(9000);<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"308\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WKT.png\" alt=\"\" class=\"wp-image-14909\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WKT.png 595w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-WKT-580x300.png 580w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, two features of\nSTC8A8k64S4A12 have been shown. Firstly, low power mode is demoed and secondly,\nthe wakeup timer. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, let\u2019s see how the wakeup timer is set. Wakeup timer is clocked with internal 32kHz oscillator. This keeps it independent from the system clock. However, the internal 32KHz oscillator is not very accurate and so there could be some deviations. To set the wakeup timer, all we need to do is to load its internal 15-bit counter with some value so that we get our desired wakeup time. The wakeup time is calculated according to the following formula:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"190\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-88.png\" alt=\"\" class=\"wp-image-14910\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-88.png 731w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-88-580x151.png 580w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the code, the counter value is set to 9000. This would roughly give a wake-up time of 4.5s once the core goes to low-power state. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> WKT_set_interval(9000); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note that although the counter is loaded the wake-up time is not\nstarted. This is so because we want to wake the micro after it enters low-power\nmode.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the main loop, the wake-up timer is disabled. The onboard LED is flashed a few times to indicate that the code in the main loop is running. After flashing the LED, the wake-up timer is started and low-power mode is entered. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> WKT_disable;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;=&nbsp;15;&nbsp;i++)&nbsp;&nbsp;<br> {<br> &nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;delay_ms(100);<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> WKT_enable;<br> Go_to_Power_Down_State; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Entering low power mode is easy. Just add the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> Go_to_Power_Down_State; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"> After entering low-power mode, the LED seems to freeze and there seems no activity at all for some time. After about 4.5s, the LED repeats flashing just like before. This time the LED flashing not only indicates main loop code execution but it also indicates that the wake timer ran and woke up the CPU core from low-power sleep mode. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"677\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-89.png\" alt=\"\" class=\"wp-image-14911\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-89.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-89-580x426.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-89-768x564.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Wakeup Timer &amp; Low Power Mode Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/slPWU7c_idM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Communication Hardware Overview<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12 packs all kinds of common communication hardware peripheral that most modern microcontrollers can offer. The following are available in STC8A8K64S4A12\u2019s arsenal:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"718\" height=\"265\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-91.png\" alt=\"\" class=\"wp-image-14914\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-91.png 718w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-91-580x214.png 580w\" sizes=\"auto, (max-width: 718px) 100vw, 718px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">As always, we also have options for\nsoftware-based communications. Using\nsome coding, we can implement software-based SPI, I2C\nand other forms of communications. One wire communication is a good example.\nOne wire communication is fully implemented in software. Using a combination of\nhardware and software, we can also implement methods to decode IR\ncommunication. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Though software methods will rarely be needed, these methods allow us to understand the working principle of different communication methods and in this way build confidence for coding devices that do not follow standard I2C, SPI or UART methods. The downside of software communications<a> <\/a>is their relative processing speed when compared with their hardware counterparts because software-based communications are made virtually in codes rather than in physical hardware.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I won\u2019t be discussing much about the software techniques because in all of my past tutorials, I have been discussing about them briefly and most of these stuffs are mere confirmation of implementation and repetition.&nbsp; <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UART offers long-distance serial communication and can also be employed for simple SPI-like serial and industry-standard RS-485 communications. STC8A8K64S4A12 has four UART hardware with independent interrupts. UART1 is the most advanced UART of all. All UART hardware peripheral need a timer for baud rate generation. Timer 2 is common to all of these UARTs and so it is wise to leave it for UARTs. All of these UART have multiple alternative pins associated with them. These pin mapping is summarized below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"723\" height=\"307\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-92.png\" alt=\"\" class=\"wp-image-14915\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-92.png 723w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-92-580x246.png 580w\" sizes=\"auto, (max-width: 723px) 100vw, 723px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"671\" height=\"805\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-94.png\" alt=\"\" class=\"wp-image-14917\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-94.png 671w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-94-542x650.png 542w\" sizes=\"auto, (max-width: 671px) 100vw, 671px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">I2C hardware available in STC8A8K64S4A12 is very simple but it offers lot of flexibilities. The I2C block can be used in both I2C master or slave roles. Just like UART it has lot of alternative pin pair options as the table below shows. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"173\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-93.png\" alt=\"\" class=\"wp-image-14916\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-93.png 730w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-93-580x137.png 580w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"712\" height=\"853\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-95.png\" alt=\"\" class=\"wp-image-14918\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-95.png 712w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-95-543x650.png 543w\" sizes=\"auto, (max-width: 712px) 100vw, 712px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">SPI hardware is also fully implemented in STC8A8K64S4A12. Using the SPI hardware is very simple and like other communication peripherals, we have options to use various alternative GPIO pin groups. Both SPI and I2C blocks are fully independent blocks unlike UARTs as UART blocks are dependent on internal hardware timers.&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"732\" height=\"129\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-96.png\" alt=\"\" class=\"wp-image-14919\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-96.png 732w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-96-580x102.png 580w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"864\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-97.png\" alt=\"\" class=\"wp-image-14920\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-97.png 721w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-97-542x650.png 542w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/figure><\/div>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">I2C<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Inter Integrated Circuit (I2C)<\/em><\/strong> was pioneered by Philips (now NXP) about three decades ago. I2C, just like SPI, is meant for short-distance synchronous onboard communications. I2C is very simple to use as only two wires are needed for communication and this is why often I2C is alternatively called two-wire communication (TWI). In an I2C communication bus, there can be one master or host device and one or several slave devices. The maximum number of devices that can coexist in an I2C bus at a time is 127. Usually, the communication master or host is a microcontroller that is responsible for initiating communications while slave devices can be anything from another microcontroller to sensors, memory devices, digital peripherals, etc. Only master and slave data transactions are possible because only a master can request data from or write to a slave device. Slave-slave communication is not possible. In an I2C bus, only one master-slave pair can communicate at a time. The rest of the devices stay idle during this time.&nbsp; <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"520\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-98.png\" alt=\"\" class=\"wp-image-14923\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-98.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-98-580x321.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-98-768x425.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To know more about I2C communication,\nvisit these pages:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/learn.mikroe.com\/i2c-everything-need-know\">https:\/\/learn.mikroe.com\/i2c-everything-need-know<\/a>&nbsp; <\/li><li><a href=\"https:\/\/learn.sparkfun.com\/tutorials\/i2c\">https:\/\/learn.sparkfun.com\/tutorials\/i2c<\/a> &nbsp;<\/li><li><a href=\"http:\/\/www.ti.com\/lsds\/ti\/interface\/i2c-overview.page\">http:\/\/www.ti.com\/lsds\/ti\/interface\/i2c-overview.page<\/a>&nbsp;&nbsp; <\/li><li><a href=\"http:\/\/www.robot-electronics.co.uk\/i2c-tutorial\">http:\/\/www.robot-electronics.co.uk\/i2c-tutorial<\/a>&nbsp; <\/li><li><a href=\"https:\/\/www.i2c-bus.org\/i2c-bus\">https:\/\/www.i2c-bus.org\/i2c-bus<\/a>&nbsp; <\/li><li><a href=\"http:\/\/i2c.info\">http:\/\/i2c.info<\/a>&nbsp; <\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">I2C.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> SCL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P1.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P2.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> P7.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;3<br> P3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;4<br> *\/<br> &nbsp;<br> #define&nbsp;I2C_pin_option(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P_SW2&nbsp;|=&nbsp;value;}while(0)<br> &nbsp;<br> \/\/Timeout<br> #define&nbsp;I2C_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 1000<br> &nbsp;<br> \/\/state<br> #define&nbsp;I2C_disable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;I2C_enable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x80<br> &nbsp;<br> \/\/mode<br> #define&nbsp;I2C_slave_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;I2C_master_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x40<br> &nbsp;<br> #define&nbsp;I2C_setup(state,&nbsp;mode,&nbsp;clk)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);&nbsp;\\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CCFG&nbsp;=&nbsp;(state&nbsp;|&nbsp;mode&nbsp;|&nbsp;(clk&nbsp;&amp;&nbsp;0x3F));&nbsp;\\&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> void&nbsp;I2C_wait(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;t&nbsp;=&nbsp;I2C_timeout;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while((check_I2C_master_flag&nbsp;==&nbsp;FALSE)&nbsp;&amp;&amp;&nbsp;(t&nbsp;&gt;&nbsp;0))<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;t--;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1);<br> &nbsp;&nbsp;};<br> &nbsp;&nbsp;<br> &nbsp; clear_I2C_master_flag;<br> }<br> &nbsp;<br> void&nbsp;I2C_start(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x01;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;<br> }<br> &nbsp;<br> void&nbsp;I2C_stop(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x06;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);<br> }<br> &nbsp;<br> void&nbsp;I2C_write(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CTXD&nbsp;=&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x02;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x03;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;I2C_read(unsigned&nbsp;char&nbsp;ACK_state)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_set(P_SW2,&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x04;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;I2CRXD;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSST&nbsp;=&nbsp;~ACK_state;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2CMSCR&nbsp;=&nbsp;0x05;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_wait();<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_clr(P_SW2,&nbsp;7);&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DHT12.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;I2C_W&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;I2C_R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> &nbsp;<br> #define&nbsp;no_of_bytes_to_read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x05<br> &nbsp;<br> #define&nbsp;DHT12_I2C_address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xB8<br> &nbsp;<br> #define&nbsp;no_error&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00<br> #define&nbsp;CRC_error&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x01<br> &nbsp;<br> void&nbsp;DHT12_init(void);<br> unsigned&nbsp;char&nbsp;DHT12_CRC(unsigned&nbsp;char&nbsp;*array_values);<br> unsigned&nbsp;char&nbsp;DHT12_read_byte(unsigned&nbsp;char&nbsp;address);<br> unsigned&nbsp;char&nbsp;DHT12_get_data(float&nbsp;*DHT12_RH,&nbsp;float&nbsp;*DHT12_T); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DHT12.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"DHT12.h\"<br> &nbsp;<br> void&nbsp;DHT12_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_pin_option(0x00);<br> &nbsp;&nbsp;&nbsp; I2C_setup(I2C_enable,&nbsp;I2C_master_mode,&nbsp;0xFF);<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DHT12_CRC(unsigned&nbsp;char&nbsp;*array_values)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;0x03;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;crc_result&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;-1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc_result&nbsp;+=&nbsp;array_values[i];<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;crc_result;<br> }<br> <br> <br><br> <br><br> unsigned&nbsp;char&nbsp;DHT12_read_byte(unsigned&nbsp;char&nbsp;address)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(DHT12_I2C_address);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(address);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(DHT12_I2C_address&nbsp;|&nbsp;I2C_R);<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;I2C_read(0);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_stop();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> }<br> <br> <br><br> <br><br> unsigned&nbsp;char&nbsp;DHT12_get_data(float&nbsp;*DHT12_RH,&nbsp;float&nbsp;*DHT12_T)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;no_of_bytes_to_read;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;values[0x05]&nbsp;=&nbsp;{0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values[(no_of_bytes_to_read&nbsp;-&nbsp;i)]&nbsp;=&nbsp;DHT12_read_byte((no_of_bytes_to_read&nbsp;-&nbsp;i));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(values[0x04]&nbsp;==&nbsp;DHT12_CRC(values))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*DHT12_RH&nbsp;=&nbsp;(((float)values[0x00])&nbsp;+&nbsp;(((float)values[0x01])&nbsp;*&nbsp;0.1));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*DHT12_T&nbsp;=&nbsp;(((float)values[0x02])&nbsp;+&nbsp;(((float)values[0x03])&nbsp;*&nbsp;0.1));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;no_error;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;CRC_error;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> #include&nbsp;\"DHT12.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;state&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;float&nbsp;T&nbsp;=&nbsp;0.0;<br> &nbsp;&nbsp;&nbsp;&nbsp;float&nbsp;RH&nbsp;=&nbsp;0.0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp; setup();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"R.H&nbsp;\/&nbsp;%:\");<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"Temp\/&nbsp;C:\");<br> &nbsp;&nbsp;&nbsp;&nbsp;print_symbol(5,&nbsp;1,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;=&nbsp;DHT12_get_data(&amp;RH,&nbsp;&amp;T);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(state)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;no_error:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;0,&nbsp;RH,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;1,&nbsp;T,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(400);<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;load_custom_symbol();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;DHT12_init();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"301\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-I2C.png\" alt=\"\" class=\"wp-image-14924\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-I2C.png 741w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-I2C-580x236.png 580w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><em>I2C.h<\/em> header file describes how the I2C hardware will work. Firstly, I2C hardware pin pairs can be any of the following combinations:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> SCL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P1.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P2.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> P7.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;3<br> P3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;4<br> *\/<br> &nbsp;<br> #define&nbsp;I2C_pin_option(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P_SW2&nbsp;|=&nbsp;value;}while(0) <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Secondly, we have the following I2C library functions that control I2C-related registers. Mainly, we would need these functions in order to properly use the I2C hardware. These the commonly used ones. Details of register handling can be avoided in this way. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;I2C_start(void)<br> void&nbsp;I2C_stop(void)<br> void&nbsp;I2C_write(unsigned&nbsp;char&nbsp;value)<br> unsigned&nbsp;char&nbsp;I2C_read(unsigned&nbsp;char&nbsp;ACK_state) <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I have avoided interrupt-based I2C\ncommunication because I2C slave devices generally do not send out data without\nrequest from master device and master device only initiates data transaction\nwhen needed. There is no need to make things unnecessarily complicated. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before using I2C hardware, we have to set it up and <strong><em>I2C_setup <\/em><\/strong>function exactly does that. It dictates mode of operation and I2C bus clock speed. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> I2C_setup(I2C_enable,&nbsp;I2C_master_mode,&nbsp;0xFF); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For demoing I2C communication, Aosong\u2019s DHT12 relative humidity-temperature sensor is used. This device is pretty simple to use. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"241\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-99.png\" alt=\"\" class=\"wp-image-14925\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-99.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-99-580x149.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-99-768x197.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The timing diagram shown above depicts that the entire sequence of data transfer is a typical I2C read. However, to simplify the task of reading the sensor, I coded the read function to read the I2C bus in byte format rather than in word format. The reading process is a usual I2C read.&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned&nbsp;char&nbsp;DHT12_read_byte(unsigned&nbsp;char&nbsp;address)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(DHT12_I2C_address);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(address);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_write(DHT12_I2C_address&nbsp;|&nbsp;I2C_R);<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;I2C_read(0);<br> &nbsp;&nbsp;&nbsp;&nbsp;I2C_stop();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Since we have to take care of Cyclic Redundancy Check (CRC) in order to ensure data integrity several byte reads are done and the read data are stored in an array. The array consists of two bytes of relative humidity data followed by two bytes of temperature data and a CRC byte &#8211; five bytes in total. After getting all the values from the sensor, CRC check is performed. If there is no CRC error, the temperature and relative humidity data are processed or else CRC error is flagged.&nbsp;&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned&nbsp;char&nbsp;DHT12_get_data(float&nbsp;*DHT12_RH,&nbsp;float&nbsp;*DHT12_T)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;no_of_bytes_to_read;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;values[0x05]&nbsp;=&nbsp;{0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values[(no_of_bytes_to_read&nbsp;-&nbsp;i)]&nbsp;=&nbsp;DHT12_read_byte((no_of_bytes_to_read&nbsp;-&nbsp;i));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(values[0x04]&nbsp;==&nbsp;DHT12_CRC(values))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*DHT12_RH&nbsp;=&nbsp;(((float)values[0x00])&nbsp;+&nbsp;(((float)values[0x01])&nbsp;*&nbsp;0.1));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*DHT12_T&nbsp;=&nbsp;(((float)values[0x02])&nbsp;+&nbsp;(((float)values[0x03])&nbsp;*&nbsp;0.1));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;no_error;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;CRC_error;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">DH12\u2019s CRC check is straight-forward. The temperature and humidity bytes are summed up and checked against the sent-out CRC value. If the values are same then there is no error in sent data.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned&nbsp;char&nbsp;DHT12_CRC(unsigned&nbsp;char&nbsp;*array_values)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;0x03;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;crc_result&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;-1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc_result&nbsp;+=&nbsp;array_values[i];<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;crc_result;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the main, the sensor is read and the temperature-relative humidity data are displayed on an LCD display. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"412\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-100.png\" alt=\"\" class=\"wp-image-14926\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-100.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-100-580x254.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-100-768x337.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - I2C Example - Hooking DHT12 Relative Humidity -Temperature Sensor\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/LstlvrywyEs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">SPI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Serial Peripheral\nInterface (SPI) communication is another short-distance synchronous\ncommunication method like I2C. Unlike I2C, SPI requires 3 or more connections but\nthe bus speed is significantly higher than that of I2C\u2019s. Except chip selection pin, all SPI devices in a SPI bus can share the same set of communication\npins. Typical\nfull-duplex SPI bus requires four basic I\/O pins. Their naming suggests their\nindividual purpose. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><em>Master-In-Slave-Out (MIS0) <\/em><\/strong>connected to <strong><em>Slave-Data-Out (SDO)<\/em><\/strong>. <\/li><li><strong><em>Master-Out-Slave-In (MOSI) <\/em><\/strong>connected to <strong><em>Slave-Data-In (SDI)<\/em><\/strong>. <\/li><li><strong><em>Serial Clock (SCLK) <\/em><\/strong>connected to <strong><em>Slave Clock (SCK)<\/em><\/strong>. <\/li><li><strong><em>Slave Select (SS) <\/em><\/strong>connected to <strong><em>Chip Select (CS)<\/em><\/strong>. <\/li><li><\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"273\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-101.png\" alt=\"\" class=\"wp-image-14928\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-101.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-101-580x168.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-101-768x223.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Since SPI bus is very\nfast, it is widely used for interfacing displays, flash memories, etc. that\nneeds fast responsiveness. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SPI is can\nvisualized as a shift register that shifts data in and out one-by-one with clock pulse transitions. Like I2C bus, there can be one master device in a SPI\nbus and virtually unlimited amount of slave devices only separated by slave\nselection pins. Master sends commands to slave(s) by generating clock signals and selecting one slave\ndevice at a time. Selected\nslave responds to commands sent by the master. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In general, if you wish to know more\nabout SPI bus here are some cool links: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/learn.mikroe.com\/spi-bus\">https:\/\/learn.mikroe.com\/spi-bus<\/a> &nbsp;&nbsp;<\/li><li><a href=\"https:\/\/learn.sparkfun.com\/tutorials\/serial-peripheral-interface-spi\">https:\/\/learn.sparkfun.com\/tutorials\/serial-peripheral-interface-spi<\/a><\/li><li><a href=\"http:\/\/ww1.microchip.com\/downloads\/en\/devicedoc\/spi.pdf\">http:\/\/ww1.microchip.com\/downloads\/en\/devicedoc\/spi.pdf<\/a><\/li><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><li><a href=\"https:\/\/embeddedmicro.com\/tutorials\/mojo\/serial-peripheral-interface-spi\">https:\/\/embeddedmicro.com\/tutorials\/mojo\/serial-peripheral-interface-spi<\/a><\/li><li><a href=\"http:\/\/www.circuitbasics.com\/basics-of-the-spi-communication-protocol\">http:\/\/www.circuitbasics.com\/basics-of-the-spi-communication-protocol<\/a> &nbsp;<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">SPI.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> SS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOSI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MISO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCLK&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P1.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.5&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P2.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.5&nbsp;&nbsp;&nbsp;&nbsp;0x04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> P7.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.7&nbsp;&nbsp;&nbsp;&nbsp;0x08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;3<br> P3.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.2&nbsp;&nbsp;&nbsp;&nbsp;0x0C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;4<br> *\/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> #define&nbsp;SPI_clear&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPCTL&nbsp;=&nbsp;0x00;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPSTAT&nbsp;=&nbsp;0xC0;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPDAT&nbsp;=&nbsp;0x00;}while(0)<br> &nbsp;<br> &nbsp;<br> #define&nbsp;SPI_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> #define&nbsp;SPI_pin_option(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P_SW1&nbsp;|=&nbsp;value;}while(0)<br> &nbsp;<br> #define&nbsp;SPI_pins(value)<br> &nbsp;<br> #define&nbsp;SPI_disable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_clr(SPCTL,&nbsp;6)<br> #define&nbsp;SPI_enable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit_set(SPCTL,&nbsp;6)<br> &nbsp;<br> \/\/clk<br> #define&nbsp;SPI_clk_sysclk_div_4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_clk_sysclk_div_8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;SPI_clk_sysclk_div_16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> #define&nbsp;SPI_clk_sysclk_div_32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x03<br> &nbsp;<br> \/\/MS<br> #define&nbsp;SPI_slave&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_master&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10<br> &nbsp;<br> \/\/data_orientation<br> #define&nbsp;SPI_MSB_first&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_LSB_first&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20<br> &nbsp;<br> \/\/CPHA<br> #define&nbsp;SPI_CPHA_leading&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_CPHA_trailing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04<br> &nbsp;<br> \/\/CPOL<br> #define&nbsp;SPI_CLK_CPOL_idle_low&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_CLK_CPOL_idle_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x08<br> &nbsp;<br> \/\/ss<br> #define&nbsp;SPI_SS_not_ignored&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;SPI_SS_ignored&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x80<br> <br> <br><br> <br><br> #define&nbsp;SPI_setup(clk,&nbsp;MS,&nbsp;data_orientation,&nbsp;CPHA,&nbsp;CPOL,&nbsp;ss)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_clear;&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPCTL&nbsp;|=&nbsp;(clk&nbsp;|&nbsp;MS&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;data_orientation&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;CPHA&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;CPOL&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ss);&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(0)<br> &nbsp;<br> unsigned&nbsp;char&nbsp;SPI_transfer(unsigned&nbsp;char&nbsp;write_value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;read_value&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;timeout&nbsp;=&nbsp;SPI_timeout;<br> &nbsp;<br> &nbsp;&nbsp;SPDAT&nbsp;=&nbsp;write_value;<br> &nbsp;&nbsp;while((!check_SPI_flag)&nbsp;&amp;&amp;&nbsp;(timeout&nbsp;&gt;&nbsp;0))&nbsp;<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;timeout--;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1);<br> &nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;clear_SPI_flag;<br> &nbsp;&nbsp;clear_SPI_write_collision_flag;<br> &nbsp;<br> &nbsp;&nbsp;read_value&nbsp;=&nbsp;SPDAT;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;return&nbsp;read_value;<br> }&nbsp; <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DS3234.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;read_cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;write_cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x80<br> &nbsp;<br> #define&nbsp;second_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;minute_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;hour_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> #define&nbsp;day_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x03<br> #define&nbsp;date_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04<br> #define&nbsp;month_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x05<br> #define&nbsp;year_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x06<br> #define&nbsp;alarm1sec_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x07<br> #define&nbsp;alarm1min_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x08<br> #define&nbsp;alarm1hr_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x09<br> #define&nbsp;alarm1date_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0A<br> #define&nbsp;alarm2min_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0B<br> #define&nbsp;alarm2hr_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0C<br> #define&nbsp;alarm2date_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0D<br> #define&nbsp;control_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0E<br> #define&nbsp;status_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0F<br> #define&nbsp;ageoffset_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10<br> #define&nbsp;tempMSB_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x11<br> #define&nbsp;tempLSB_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x12<br> #define&nbsp;tempdisable_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x13<br> #define&nbsp;sramaddr_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x18<br> #define&nbsp;sramdata_reg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x19<br> &nbsp;<br> #define&nbsp;am&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;hr24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;hr12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> &nbsp;<br> #define&nbsp;DS3234_SS_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P12_high<br> #define&nbsp;DS3234_SS_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P12_low<br> &nbsp;<br> unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;min&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;hr&nbsp;=&nbsp;10;<br> unsigned&nbsp;char&nbsp;ampm&nbsp;=&nbsp;pm;<br> unsigned&nbsp;char&nbsp;dy&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;dt&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;mt&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;yr&nbsp;=&nbsp;1;<br> unsigned&nbsp;char&nbsp;hr_format&nbsp;=&nbsp;hr12;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;bcd_to_decimal(unsigned&nbsp;char&nbsp;d);<br> unsigned&nbsp;char&nbsp;decimal_to_bcd(unsigned&nbsp;char&nbsp;d);<br> void&nbsp;DS3234_init(void);<br> unsigned&nbsp;char&nbsp;DS3234_read(unsigned&nbsp;char&nbsp;addr);<br> void&nbsp;DS3234_write(unsigned&nbsp;char&nbsp;addr,&nbsp;unsigned&nbsp;char&nbsp;value);<br> float&nbsp;DS3234_get_temp(void);<br> void&nbsp;DS3234_write_SRAM(unsigned&nbsp;char&nbsp;addr,&nbsp;unsigned&nbsp;char&nbsp;value);<br> unsigned&nbsp;char&nbsp;DS3234_read_SRAM(unsigned&nbsp;char&nbsp;addr);<br> void&nbsp;DS3234_get_time(unsigned&nbsp;short&nbsp;hour_format);<br> void&nbsp;DS3234_get_date(void);<br> void&nbsp;DS3234_set_time(unsigned&nbsp;char&nbsp;hSet,&nbsp;unsigned&nbsp;char&nbsp;mSet,&nbsp;unsigned&nbsp;char&nbsp;sSet,&nbsp;unsigned&nbsp;char&nbsp;am_pm_state,&nbsp;unsigned&nbsp;char&nbsp;hour_format);<br> void&nbsp;DS3234_set_date(unsigned&nbsp;char&nbsp;daySet,&nbsp;unsigned&nbsp;char&nbsp;dateSet,&nbsp;unsigned&nbsp;char&nbsp;monthSet,&nbsp;unsigned&nbsp;char&nbsp;yearSet); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DS3234.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"DS3234.h\"<br> &nbsp;<br> unsigned&nbsp;char&nbsp;bcd_to_decimal(unsigned&nbsp;char&nbsp;d)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;return&nbsp;((d&nbsp;&amp;&nbsp;0x0F)&nbsp;+&nbsp;(((d&nbsp;&amp;&nbsp;0xF0)&nbsp;&gt;&gt;&nbsp;4)&nbsp;*&nbsp;10));<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;decimal_to_bcd(unsigned&nbsp;char&nbsp;d)<br> {<br> &nbsp;&nbsp;return&nbsp;(((d&nbsp;\/&nbsp;10)&nbsp;&lt;&lt;&nbsp;4)&nbsp;&amp;&nbsp;0xF0)&nbsp;|&nbsp;((d&nbsp;%&nbsp;10)&nbsp;&amp;&nbsp;0x0F);<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;DS3234_init(void)<br> {<br> &nbsp;&nbsp;P12_push_pull_mode;<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;SPI_pin_option(0x00);<br> &nbsp;<br> &nbsp;&nbsp;SPI_setup(SPI_clk_sysclk_div_16,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_master,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_MSB_first,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CPHA_trailing,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CLK_CPOL_idle_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SS_ignored);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;SPI_enable;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;DS3234_write(control_reg,&nbsp;0x20);<br> &nbsp;&nbsp;DS3234_write(status_reg,&nbsp;0x48);<br> &nbsp;&nbsp;DS3234_set_time(hr,&nbsp;min,&nbsp;s,&nbsp;ampm,&nbsp;hr_format);<br> &nbsp;&nbsp;DS3234_set_date(dy,&nbsp;dt,&nbsp;mt,&nbsp;yr);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DS3234_read(unsigned&nbsp;char&nbsp;addr)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_SS_LOW;<br> &nbsp;&nbsp;SPI_transfer(addr&nbsp;|&nbsp;read_cmd);<br> &nbsp;&nbsp;value&nbsp;=&nbsp;SPI_transfer(0x00);<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;value;<br> }<br> &nbsp;<br> void&nbsp;DS3234_write(unsigned&nbsp;char&nbsp;addr,&nbsp;unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;long&nbsp;temp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_SS_LOW;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(addr&nbsp;|&nbsp;write_cmd);<br> &nbsp;&nbsp;SPI_transfer(temp);<br> &nbsp;&nbsp;SPI_transfer(value);<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> }<br> &nbsp;<br> float&nbsp;DS3234_get_temp(void)<br> {<br> &nbsp;&nbsp;float&nbsp;t&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;signed&nbsp;char&nbsp;highByte&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;lowByte&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;highByte&nbsp;=&nbsp;DS3234_read(tempMSB_reg);<br> &nbsp;&nbsp;lowByte&nbsp;=&nbsp;DS3234_read(tempLSB_reg);<br> &nbsp;<br> &nbsp;&nbsp;lowByte&nbsp;&gt;&gt;=&nbsp;6;<br> &nbsp;&nbsp;t&nbsp;=&nbsp;(lowByte&nbsp;&amp;&nbsp;0x03);<br> &nbsp;&nbsp;t&nbsp;*=&nbsp;0.25;<br> &nbsp;&nbsp;t&nbsp;+=&nbsp;highByte;<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;t;<br> }&nbsp;<br> &nbsp;<br> void&nbsp;DS3234_write_SRAM(unsigned&nbsp;char&nbsp;addr,&nbsp;unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;DS3234_write(sramaddr_reg,&nbsp;addr);<br> &nbsp;&nbsp;DS3234_write(sramdata_reg,&nbsp;value);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DS3234_read_SRAM(unsigned&nbsp;char&nbsp;addr)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_SS_LOW;<br> &nbsp;&nbsp;SPI_transfer(sramaddr_reg);<br> &nbsp;&nbsp;SPI_transfer(addr);<br> &nbsp;&nbsp;value&nbsp;=&nbsp;DS3234_read(sramdata_reg);<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;value;<br> }<br> &nbsp;<br> void&nbsp;DS3234_get_time(unsigned&nbsp;short&nbsp;hour_format)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;s&nbsp;=&nbsp;DS3234_read(second_reg);<br> &nbsp;&nbsp;s&nbsp;=&nbsp;bcd_to_decimal(s);<br> &nbsp;&nbsp;min&nbsp;=&nbsp;DS3234_read(minute_reg);<br> &nbsp;&nbsp;min&nbsp;=&nbsp;bcd_to_decimal(min);<br> &nbsp;&nbsp;tmp&nbsp;=&nbsp;DS3234_read(hour_reg);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;switch(hour_format)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;hr12:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;=&nbsp;(tmp&nbsp;&amp;&nbsp;0x20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;&gt;&gt;=&nbsp;5;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;(tmp&nbsp;&amp;&nbsp;0x1F);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;bcd_to_decimal(hr);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;(0x3F&nbsp;&amp;&nbsp;tmp);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;bcd_to_decimal(hr);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;DS3234_get_date(void)<br> {<br> &nbsp;&nbsp;yr&nbsp;=&nbsp;DS3234_read(year_reg);<br> &nbsp;&nbsp;yr&nbsp;=&nbsp;bcd_to_decimal(yr);<br> &nbsp;&nbsp;mt&nbsp;=&nbsp;(0x1F&nbsp;&amp;&nbsp;DS3234_read(month_reg));<br> &nbsp;&nbsp;mt&nbsp;=&nbsp;bcd_to_decimal(mt);<br> &nbsp;&nbsp;dt&nbsp;=&nbsp;(0x3F&nbsp;&amp;&nbsp;DS3234_read(date_reg));<br> &nbsp;&nbsp;dt&nbsp;=&nbsp;bcd_to_decimal(dt);<br> &nbsp;&nbsp;dy&nbsp;=&nbsp;(0x07&nbsp;&amp;&nbsp;DS3234_read(day_reg));<br> &nbsp;&nbsp;dy&nbsp;=&nbsp;bcd_to_decimal(dy);<br> }<br> &nbsp;<br> void&nbsp;DS3234_set_time(unsigned&nbsp;char&nbsp;hSet,&nbsp;unsigned&nbsp;char&nbsp;mSet,&nbsp;unsigned&nbsp;char&nbsp;sSet,&nbsp;unsigned&nbsp;char&nbsp;am_pm_state,&nbsp;unsigned&nbsp;char&nbsp;hour_format)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_write(second_reg,&nbsp;(decimal_to_bcd(sSet)));<br> &nbsp;&nbsp;DS3234_write(minute_reg,&nbsp;(decimal_to_bcd(mSet)));<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;switch(hour_format)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;hr12:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(am_pm_state)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pm:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;0x20;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS3234_write(hour_reg,&nbsp;((tmp&nbsp;|&nbsp;0x40&nbsp;|&nbsp;(0x1F&nbsp;&amp;&nbsp;(decimal_to_bcd(hSet))))));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS3234_write(hour_reg,&nbsp;(0xBF&nbsp;&amp;&nbsp;(0x3F&nbsp;&amp;&nbsp;(decimal_to_bcd(hSet)))));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;DS3234_set_date(unsigned&nbsp;char&nbsp;daySet,&nbsp;unsigned&nbsp;char&nbsp;dateSet,&nbsp;unsigned&nbsp;char&nbsp;monthSet,&nbsp;unsigned&nbsp;char&nbsp;yearSet)<br> {<br> &nbsp;&nbsp;DS3234_write(day_reg,&nbsp;(decimal_to_bcd(daySet)));<br> &nbsp;&nbsp;DS3234_write(date_reg,&nbsp;(decimal_to_bcd(dateSet)));<br> &nbsp;&nbsp;DS3234_write(month_reg,&nbsp;(decimal_to_bcd(monthSet)));<br> &nbsp;&nbsp;DS3234_write(year_reg,&nbsp;(decimal_to_bcd(yearSet)));<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include \"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> #include&nbsp;\"DS3234.c\"<br> &nbsp;<br> #define&nbsp;SET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;INC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<br> #define&nbsp;SAVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<br> &nbsp;<br> #define&nbsp;keypad_dly&nbsp;&nbsp;&nbsp;&nbsp;10<br> #define&nbsp;disp_dly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;90<br> &nbsp;<br> void&nbsp;setup(void);<br> unsigned&nbsp;char&nbsp;get_keypad(void);<br> void&nbsp;display_value(unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;value);<br> void&nbsp;show_temperature();<br> void&nbsp;display_time(void);<br> void&nbsp;get_date_time_data(void);<br> unsigned&nbsp;char&nbsp;change_value(unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;max_value,&nbsp;unsigned&nbsp;char&nbsp;min_value);<br> void&nbsp;setting(void);<br> void&nbsp;show_day(unsigned&nbsp;char&nbsp;value);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;setting();<br> &nbsp;&nbsp;&nbsp;&nbsp;get_date_time_data();<br> &nbsp;&nbsp;&nbsp;&nbsp;show_temperature();<br> &nbsp;&nbsp;&nbsp;&nbsp;display_time();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(200);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;P40_input_mode;<br> &nbsp;&nbsp;P41_input_mode;<br> &nbsp;&nbsp;P42_input_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;DS3234_init();<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;load_custom_symbol();<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;get_keypad()<br> {<br> &nbsp;&nbsp;if(!P40_get_input)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(keypad_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;SET;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;else&nbsp;if(!P41_get_input)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(keypad_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;INC;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;else&nbsp;if(!P42_get_input)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(keypad_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;SAVE;<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;else<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;display_value(unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;ch&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;LCD_goto((x_pos&nbsp;-&nbsp;1),&nbsp;(y_pos&nbsp;-&nbsp;1));<br> &nbsp;&nbsp;LCD_putchar((ch&nbsp;+&nbsp;0x30));<br> &nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;LCD_goto(x_pos,&nbsp;(y_pos&nbsp;-&nbsp;1));<br> &nbsp;&nbsp;LCD_putchar((ch&nbsp;+&nbsp;0x30));<br> }<br> &nbsp;<br> void&nbsp;display_time()<br> {<br> &nbsp;&nbsp;display_value(1,&nbsp;1,&nbsp;hr);<br> &nbsp;&nbsp;LCD_goto(2,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\":\");<br> &nbsp;&nbsp;display_value(1,&nbsp;4,&nbsp;min);<br> &nbsp;&nbsp;LCD_goto(5,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\":\");<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;display_value(1,&nbsp;7,&nbsp;s);<br> &nbsp;<br> &nbsp;&nbsp;switch(hr_format)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;hr12:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(ampm)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pm:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"PM\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"AM\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;display_value(2,&nbsp;1,&nbsp;dt);<br> &nbsp;&nbsp;LCD_goto(2,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"\/\");<br> &nbsp;&nbsp;display_value(2,&nbsp;4,&nbsp;mt);<br> &nbsp;&nbsp;LCD_goto(5,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"\/\");<br> &nbsp;&nbsp;display_value(2,&nbsp;7,&nbsp;yr);<br> &nbsp;&nbsp;show_day(dy);<br> }<br> &nbsp;<br> void&nbsp;show_temperature()<br> {<br> &nbsp;&nbsp;float&nbsp;t&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;t&nbsp;=&nbsp;DS3234_get_temp();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;t;<br> &nbsp;&nbsp;display_value(2,&nbsp;10,&nbsp;temp);<br> &nbsp;&nbsp;LCD_goto(11,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\".\");<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;((t&nbsp;-&nbsp;temp)&nbsp;*&nbsp;100);<br> &nbsp;&nbsp;display_value(2,&nbsp;13,&nbsp;temp);<br> &nbsp;&nbsp;print_symbol(14,&nbsp;1,&nbsp;0);<br> &nbsp;&nbsp;LCD_goto(15,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"C\");<br> }<br> &nbsp;<br> void&nbsp;get_date_time_data()<br> {<br> &nbsp;&nbsp;DS3234_get_date();<br> &nbsp;&nbsp;DS3234_get_time(hr_format);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;change_value(unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;max_value,&nbsp;unsigned&nbsp;char&nbsp;min_value)<br> {<br> &nbsp;&nbsp;while(TRUE)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;INC)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value++;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&gt;&nbsp;max_value)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;min_value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_goto((x_pos&nbsp;-&nbsp;1),&nbsp;(y_pos&nbsp;-&nbsp;1));<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;\");&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;display_value(y_pos,&nbsp;x_pos,&nbsp;value);<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;SAVE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(get_keypad()&nbsp;==&nbsp;SAVE);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;setting()<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bit&nbsp;set_cmd;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_cmd&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;SET)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(get_keypad()&nbsp;==&nbsp;SET);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_cmd&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(set_cmd)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;INC)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&gt;&nbsp;2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(tmp)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"AM\");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;=&nbsp;am;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr_format&nbsp;=&nbsp;hr12;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"PM\");&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ampm&nbsp;=&nbsp;pm;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr_format&nbsp;=&nbsp;hr12;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(9,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"24\");&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr_format&nbsp;=&nbsp;hr24;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;SAVE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;change_value(1,&nbsp;7,&nbsp;s,&nbsp;59,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;=&nbsp;change_value(1,&nbsp;4,&nbsp;min,&nbsp;59,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(hr_format)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;hr12:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;change_value(1,&nbsp;1,&nbsp;hr,&nbsp;12,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;=&nbsp;change_value(1,&nbsp;1,&nbsp;hr,&nbsp;23,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt&nbsp;=&nbsp;change_value(2,&nbsp;1,&nbsp;dt,&nbsp;31,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mt&nbsp;=&nbsp;change_value(2,&nbsp;4,&nbsp;mt,&nbsp;12,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yr&nbsp;=&nbsp;change_value(2,&nbsp;7,&nbsp;yr,&nbsp;99,&nbsp;0);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;dy;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;INC)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&gt;&nbsp;7)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(13,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"&nbsp;&nbsp;&nbsp;&nbsp;\");&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;show_day(tmp);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(disp_dly);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(get_keypad()&nbsp;==&nbsp;SAVE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;=&nbsp;tmp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS3234_set_time(hr,&nbsp;min,&nbsp;s,&nbsp;ampm,&nbsp;hr_format);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS3234_set_date(dy,&nbsp;dt,&nbsp;mt,&nbsp;yr);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_cmd&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;show_day(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;LCD_goto(13,&nbsp;0);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;switch(value)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"SUN\");&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"MON\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"TUE\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;4:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"WED\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;5:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"THR\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;6:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"FRI\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;7:<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"SAT\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"890\" height=\"292\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SPI.png\" alt=\"\" class=\"wp-image-14929\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SPI.png 890w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SPI-580x190.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SPI-768x252.png 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SPI-880x290.png 880w\" sizes=\"auto, (max-width: 890px) 100vw, 890px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As with other hardware, the built-in SPI hardware also has many alternative pin options. The SPI header file describes these pin combinations. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> SS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOSI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MISO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCLK&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P1.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1.5&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P2.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P2.5&nbsp;&nbsp;&nbsp;&nbsp;0x04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> P7.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P7.7&nbsp;&nbsp;&nbsp;&nbsp;0x08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;3<br> P3.5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P3.2&nbsp;&nbsp;&nbsp;&nbsp;0x0C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;4<br> *\/<br> &nbsp;<br> &nbsp;<br> #define SPI_pin_option(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P_SW1 |= value;}while(0) <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To use SPI peripheral, we have to set it up first as shown below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> SPI_setup(SPI_clk_sysclk_div_16,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_master,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_MSB_first,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CPHA_trailing,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CLK_CPOL_idle_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SS_ignored);<br> &nbsp;&nbsp;<br> SPI_enable; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>SPI_setup <\/em><\/strong>function sets up SPI bus clock, device role,\ndata sequence, clock phase and polarity alongside built-in hardware slave\nselect pin operation state. After having these set up, the SPI hardware is\nready to be enabled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since SPI functions like a ring shift-register, only one function is needed for SPI bus data transactions. The following <strong><em>SPI_transfer<\/em><\/strong> function is used for this purpose. First data is written and then read. Reading and writing <em>SPDAT<\/em> register automatically generates SPI bus clock. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned char SPI_transfer(unsigned char write_value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;read_value&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;timeout&nbsp;=&nbsp;SPI_timeout;<br> &nbsp;<br> &nbsp;&nbsp;SPDAT&nbsp;=&nbsp;write_value;<br> &nbsp;&nbsp;while((!check_SPI_flag)&nbsp;&amp;&amp;&nbsp;(timeout&nbsp;&gt;&nbsp;0))&nbsp;<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;timeout--;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1);<br> &nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;clear_SPI_flag;<br> &nbsp;&nbsp;clear_SPI_write_collision_flag;<br> &nbsp;<br> &nbsp;&nbsp;read_value&nbsp;=&nbsp;SPDAT;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;return&nbsp;read_value;<br> }&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SPI peripheral is demoed here using DS3234 Real-Time Clock (RTC). The first three functions are what we basically need to fully make the RTC communicate with our STC micro. The rest of the RTC library functions are extensions of the DS3234 read and write functions. The read and write functions are typically what we see with other SPI devices. I recommend readers to check the timing diagrams of DS3234 from its datasheet and check the code in order to properly realize the SPI working principle in conjunction with the code presented here. Note that since the hardware slave select pin is not used, slave selection is done in code by changing the state of a GPIO pin. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;DS3234_init(void)<br> {<br> &nbsp;&nbsp;P12_push_pull_mode;<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;SPI_pin_option(0x00);<br> &nbsp;<br> &nbsp;&nbsp;SPI_setup(SPI_clk_sysclk_div_16,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_master,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_MSB_first,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CPHA_trailing,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CLK_CPOL_idle_low,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SS_ignored);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;SPI_enable;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;DS3234_write(control_reg,&nbsp;0x20);<br> &nbsp;&nbsp;DS3234_write(status_reg,&nbsp;0x48);<br> &nbsp;&nbsp;DS3234_set_time(hr,&nbsp;min,&nbsp;s,&nbsp;ampm,&nbsp;hr_format);<br> &nbsp;&nbsp;DS3234_set_date(dy,&nbsp;dt,&nbsp;mt,&nbsp;yr);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DS3234_read(unsigned&nbsp;char&nbsp;addr)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_SS_LOW;<br> &nbsp;&nbsp;SPI_transfer(addr&nbsp;|&nbsp;read_cmd);<br> &nbsp;&nbsp;value&nbsp;=&nbsp;SPI_transfer(0x00);<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;value;<br> }<br> &nbsp;<br> void&nbsp;DS3234_write(unsigned&nbsp;char&nbsp;addr,&nbsp;unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;long&nbsp;temp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;DS3234_SS_LOW;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(addr&nbsp;|&nbsp;write_cmd);<br> &nbsp;&nbsp;SPI_transfer(temp);<br> &nbsp;&nbsp;SPI_transfer(value);<br> &nbsp;&nbsp;DS3234_SS_HIGH;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"402\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-102.png\" alt=\"\" class=\"wp-image-14930\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-102.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-102-580x248.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-102-768x328.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - SPI Example - Interfacing DS3234 RTCC with STC Micro\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/MeiDFeziIFk?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">UART<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Serial communication is probably the most widely used communication method. It is simple to implement and can be used to communicate with a computer literally directly without needing too many extra external hardware. Serial communication also has the distance advantage over other communication interfaces. Serial communication can be implemented using UART hardware peripherals of STC micros. Many sensors, communication devices like GSM modems and RF devices, RFIDs and other external devices use this simple and time-proven interface for communicating with host micros. UART is also the backbone of other communication methods like MODBUS, IrDA, LIN, etc. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"269\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-103.png\" alt=\"\" class=\"wp-image-14932\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-103.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-103-580x166.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-103-768x220.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To learn more about UART visit the\nfollowing link: <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/learn.mikroe.com\/uart-serial-communication\">https:\/\/learn.mikroe.com\/uart-serial-communication<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;msg1[10]&nbsp;=&nbsp;{\"MicroArena\"};<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;msg2[10]&nbsp;=&nbsp;{\"SShahryiar\"};<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;char&nbsp;rcv_1&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;char&nbsp;rcv_4&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"TXD1:&nbsp;\");<br> &nbsp;&nbsp;LCD_goto(10,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"RXD1:&nbsp;\");<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"TXD4:&nbsp;\");<br> &nbsp;&nbsp;LCD_goto(10,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"RXD4:&nbsp;\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_write_buffer(msg1[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART4_write_buffer(msg2[i]);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(5,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(msg1[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(5,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(msg2[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rcv_1&nbsp;=&nbsp;UART1_read_buffer();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rcv_4&nbsp;=&nbsp;UART4_read_buffer();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(15,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(rcv_1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(15,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(rcv_4);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(900);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;UART1_pin_option(0xC0);<br> &nbsp;&nbsp;UART1_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_baud_source_TMR2,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_timer_12T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;UART4_pin_option(0x04);<br> &nbsp;&nbsp;UART4_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART4_baud_source_TMR4,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART4_timer_1T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000);<br> &nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"817\" height=\"303\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-UART.png\" alt=\"\" class=\"wp-image-14937\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-UART.png 817w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-UART-580x215.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-UART-768x285.png 768w\" sizes=\"auto, (max-width: 817px) 100vw, 817px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">STC8A8K64S4A12 has four hardware UART peripherals. Of these four, UART1 has some advanced features that are rarely needed. The rest are pretty much alike. Like other communication hardware peripherals, pin configuration must be selected as alternative pin arrangements are available. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/*<br> RXD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option<br> P0.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P0.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;1<br> P5.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P5.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option&nbsp;2<br> *\/<br> &nbsp;<br> #define&nbsp;UART4_pin_option(value)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{P_SW2&nbsp;|=&nbsp;value;}while(0) <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UART,\nalthough asynchronous, need to transmit and receive data in timed-frame formats\nand so when two UART devices need to communicate with each other, they must\nnegotiate a mutually agreed baud rate or else data will not recognized. It is\nlike tuning to the right radio station for listening the music channel that we\nwant to listen. Thus, baud rate generation is a very crucial part of UART\nperipheral. For baud rate generation, UARTs can either use Timer 2 or other\ntimer having the same number as the UART itself, for example, in the case of\nUART3, only Timer 2 and Timer 3 can be used as baud rate generator. I\npersonally recommend that we keep Timer 2 reserved for other applications or\nUART2 and use other timers independently as to avoid conflicts in different\nUART hardware. Yes, I know it contradicts with my past statement of keeping\nTimer 2 reserved for UART applications but what else can be done when multiple\nUARTs are used in an application. BSP functions take care of everything\ninternally and so we can focus on coding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The system clock is set to 12MHz. This is very important because timers are responsible for baud rate generation and are dependent on system clock. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To setup UART, we need to specify baud rate, clock source of baud rate generator, i.e., the timer to be used, its prescale factor and system clock speed in hertz.&nbsp; <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> UART4_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART4_baud_source_TMR4,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART4_timer_1T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UART reading and writing is done as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> UART4_write_buffer(msg2[i]);&nbsp;&nbsp;<br> ....<br> rcv_4&nbsp;=&nbsp;UART4_read_buffer(); <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The demo here uses two built-in UARTs &#8211; UART1 and UART4, crisscrossed among themselves. Each transmitting and receiving the other\u2019s message. Whatever each is sending and receiving is also shown on an LCD display. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"595\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-104.png\" alt=\"\" class=\"wp-image-14934\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-104.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-104-580x374.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-104-768x496.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12   UART Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/5MO5_YcRB_s?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">RS485 MODBUS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">RS485 is basically a long-range reliable\nindustrial version of serial communication. It is a hardware layer that can\nsupport anything from simple serial communication to complex software-based\ncommunication layers. MODBUS is such a software layer or protocol that can be\nused to reliably exchange data between devices. MODBUS (particularly MODBUS\nRTU) is very popular among industrial devices like energy meters, PLCs and sensor devices.\nMODBUS has some similarity with I2C in some regards. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another similar communication medium is the Controller Area Network (CAN). CAN is not supported internally by STC microcontrollers unlike some advanced microcontrollers like the STM32s and other ARMs but with external hardware like MCP2551 and MCP2515 CAN communication can also be achieved. CAN communication is beyond the scope of this tutorial.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"483\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-105.png\" alt=\"\" class=\"wp-image-14935\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-105.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-105-580x298.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-105-768x395.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To know more about MODBUS, visit these\nlinks:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Modbus\">https:\/\/en.wikipedia.org\/wiki\/Modbus<\/a>\n<\/li><li><a href=\"https:\/\/modbus.org\/docs\/PI_MBUS_300.pdf\">https:\/\/modbus.org\/docs\/PI_MBUS_300.pdf<\/a>\n<\/li><li><a href=\"https:\/\/modbus.org\/docs\/Modbus_Application_Protocol_V1_1b.pdf\">https:\/\/modbus.org\/docs\/Modbus_Application_Protocol_V1_1b.pdf<\/a>\n<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD.c\"<br> #include&nbsp;\"lcd_print.c\"<br> &nbsp;<br> #define&nbsp;DIR_RX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P12_low<br> #define&nbsp;DIR_TX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P12_high<br> &nbsp;<br> &nbsp;<br> &nbsp;<br> &nbsp;<br> #define&nbsp;TX_buffer_length&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8<br> #define&nbsp;RX_buffer_length&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10<br> &nbsp;<br> unsigned&nbsp;char&nbsp;cnt&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_buffer[RX_buffer_length];<br> &nbsp;<br> static&nbsp;const&nbsp;unsigned&nbsp;char&nbsp;TX_buffer[TX_buffer_length]&nbsp;=&nbsp;{0x01,&nbsp;0x03,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x02,&nbsp;0xC4,&nbsp;0x0B};<br> &nbsp;<br> void&nbsp;setup(void);<br> void&nbsp;flush_RX_buffer(void);<br> void&nbsp;send_read_command(void);<br> unsigned&nbsp;int&nbsp;make_word(unsigned&nbsp;char&nbsp;HB,&nbsp;unsigned&nbsp;char&nbsp;LB);<br> void&nbsp;get_HB_LB(unsigned&nbsp;int&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;*HB,&nbsp;unsigned&nbsp;char&nbsp;*LB);<br> unsigned&nbsp;int&nbsp;MODBUS_RTU_CRC16(unsigned&nbsp;char&nbsp;*data_input,&nbsp;unsigned&nbsp;char&nbsp;data_length);<br> &nbsp;<br> void&nbsp;UART_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;8<br> {<br> &nbsp;&nbsp;if(check_UART_2_RX_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;RX_buffer[cnt++]&nbsp;=&nbsp;UART2_read_buffer();<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;value&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;CRC_check_1&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;CRC_check_2&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"R.H&nbsp;\/&nbsp;%:\");<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"Temp\/&nbsp;C:\");<br> &nbsp;&nbsp;print_symbol(5,&nbsp;1,&nbsp;0);<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_read_command();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRC_check_1&nbsp;=&nbsp;MODBUS_RTU_CRC16(RX_buffer,&nbsp;7);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRC_check_2&nbsp;=&nbsp;make_word(RX_buffer[8],&nbsp;RX_buffer[7]);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(CRC_check_1&nbsp;==&nbsp;CRC_check_2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;make_word(RX_buffer[5],&nbsp;RX_buffer[6]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;0,&nbsp;(value&nbsp;\/&nbsp;10.0),&nbsp;1);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;make_word(RX_buffer[3],&nbsp;RX_buffer[4]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;1,&nbsp;(value&nbsp;\/&nbsp;10.0),&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P55_toggle;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1000);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;P12_push_pull_mode;<br> &nbsp;&nbsp;P55_open_drain_mode;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;load_custom_symbol();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;UART2_pin_option(0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;UART2_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART2_timer_1T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;_enable_UART_2_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> }<br> &nbsp;<br> void&nbsp;flush_RX_buffer(void)<br> {<br> &nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;(RX_buffer_length&nbsp;-&nbsp;1);<br> &nbsp;<br> &nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;-1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;RX_buffer[i]&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;send_read_command(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;flush_RX_buffer();<br> &nbsp;<br> &nbsp;&nbsp;DIR_TX;<br> &nbsp;<br> &nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;TX_buffer_length;&nbsp;i++)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;UART2_write_buffer(TX_buffer[i]);<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;cnt&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;DIR_RX;<br> &nbsp;<br> &nbsp;&nbsp;delay_ms(600);<br> }<br> &nbsp;<br> unsigned&nbsp;int&nbsp;make_word(unsigned&nbsp;char&nbsp;HB,&nbsp;unsigned&nbsp;char&nbsp;LB)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;tmp&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;tmp&nbsp;=&nbsp;HB;<br> &nbsp;&nbsp;tmp&nbsp;&lt;&lt;=&nbsp;8;<br> &nbsp;&nbsp;tmp&nbsp;|=&nbsp;LB;<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;tmp;<br> }<br> &nbsp;<br> void&nbsp;get_HB_LB(unsigned&nbsp;int&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;*HB,&nbsp;unsigned&nbsp;char&nbsp;*LB)<br> {<br> &nbsp;&nbsp;*LB&nbsp;=&nbsp;(value&nbsp;&amp;&nbsp;0x00FF);<br> &nbsp;&nbsp;*HB&nbsp;=&nbsp;((value&nbsp;&amp;&nbsp;0xFF00)&nbsp;&gt;&gt;&nbsp;8);<br> }<br> &nbsp;<br> unsigned&nbsp;int&nbsp;MODBUS_RTU_CRC16(unsigned&nbsp;char&nbsp;*data_input,&nbsp;unsigned&nbsp;char&nbsp;data_length)<br> {<br> &nbsp;&nbsp;static&nbsp;const&nbsp;unsigned&nbsp;int&nbsp;CRC_table[256]&nbsp;=<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0000,&nbsp;0xC0C1,&nbsp;0xC181,&nbsp;0x0140,&nbsp;0xC301,&nbsp;0x03C0,&nbsp;0x0280,&nbsp;0xC241,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xC601,&nbsp;0x06C0,&nbsp;0x0780,&nbsp;0xC741,&nbsp;0x0500,&nbsp;0xC5C1,&nbsp;0xC481,&nbsp;0x0440,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xCC01,&nbsp;0x0CC0,&nbsp;0x0D80,&nbsp;0xCD41,&nbsp;0x0F00,&nbsp;0xCFC1,&nbsp;0xCE81,&nbsp;0x0E40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0A00,&nbsp;0xCAC1,&nbsp;0xCB81,&nbsp;0x0B40,&nbsp;0xC901,&nbsp;0x09C0,&nbsp;0x0880,&nbsp;0xC841,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD801,&nbsp;0x18C0,&nbsp;0x1980,&nbsp;0xD941,&nbsp;0x1B00,&nbsp;0xDBC1,&nbsp;0xDA81,&nbsp;0x1A40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x1E00,&nbsp;0xDEC1,&nbsp;0xDF81,&nbsp;0x1F40,&nbsp;0xDD01,&nbsp;0x1DC0,&nbsp;0x1C80,&nbsp;0xDC41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x1400,&nbsp;0xD4C1,&nbsp;0xD581,&nbsp;0x1540,&nbsp;0xD701,&nbsp;0x17C0,&nbsp;0x1680,&nbsp;0xD641,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD201,&nbsp;0x12C0,&nbsp;0x1380,&nbsp;0xD341,&nbsp;0x1100,&nbsp;0xD1C1,&nbsp;0xD081,&nbsp;0x1040,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xF001,&nbsp;0x30C0,&nbsp;0x3180,&nbsp;0xF141,&nbsp;0x3300,&nbsp;0xF3C1,&nbsp;0xF281,&nbsp;0x3240,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x3600,&nbsp;0xF6C1,&nbsp;0xF781,&nbsp;0x3740,&nbsp;0xF501,&nbsp;0x35C0,&nbsp;0x3480,&nbsp;0xF441,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x3C00,&nbsp;0xFCC1,&nbsp;0xFD81,&nbsp;0x3D40,&nbsp;0xFF01,&nbsp;0x3FC0,&nbsp;0x3E80,&nbsp;0xFE41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFA01,&nbsp;0x3AC0,&nbsp;0x3B80,&nbsp;0xFB41,&nbsp;0x3900,&nbsp;0xF9C1,&nbsp;0xF881,&nbsp;0x3840,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x2800,&nbsp;0xE8C1,&nbsp;0xE981,&nbsp;0x2940,&nbsp;0xEB01,&nbsp;0x2BC0,&nbsp;0x2A80,&nbsp;0xEA41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xEE01,&nbsp;0x2EC0,&nbsp;0x2F80,&nbsp;0xEF41,&nbsp;0x2D00,&nbsp;0xEDC1,&nbsp;0xEC81,&nbsp;0x2C40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xE401,&nbsp;0x24C0,&nbsp;0x2580,&nbsp;0xE541,&nbsp;0x2700,&nbsp;0xE7C1,&nbsp;0xE681,&nbsp;0x2640,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x2200,&nbsp;0xE2C1,&nbsp;0xE381,&nbsp;0x2340,&nbsp;0xE101,&nbsp;0x21C0,&nbsp;0x2080,&nbsp;0xE041,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA001,&nbsp;0x60C0,&nbsp;0x6180,&nbsp;0xA141,&nbsp;0x6300,&nbsp;0xA3C1,&nbsp;0xA281,&nbsp;0x6240,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x6600,&nbsp;0xA6C1,&nbsp;0xA781,&nbsp;0x6740,&nbsp;0xA501,&nbsp;0x65C0,&nbsp;0x6480,&nbsp;0xA441,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x6C00,&nbsp;0xACC1,&nbsp;0xAD81,&nbsp;0x6D40,&nbsp;0xAF01,&nbsp;0x6FC0,&nbsp;0x6E80,&nbsp;0xAE41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xAA01,&nbsp;0x6AC0,&nbsp;0x6B80,&nbsp;0xAB41,&nbsp;0x6900,&nbsp;0xA9C1,&nbsp;0xA881,&nbsp;0x6840,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x7800,&nbsp;0xB8C1,&nbsp;0xB981,&nbsp;0x7940,&nbsp;0xBB01,&nbsp;0x7BC0,&nbsp;0x7A80,&nbsp;0xBA41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xBE01,&nbsp;0x7EC0,&nbsp;0x7F80,&nbsp;0xBF41,&nbsp;0x7D00,&nbsp;0xBDC1,&nbsp;0xBC81,&nbsp;0x7C40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xB401,&nbsp;0x74C0,&nbsp;0x7580,&nbsp;0xB541,&nbsp;0x7700,&nbsp;0xB7C1,&nbsp;0xB681,&nbsp;0x7640,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x7200,&nbsp;0xB2C1,&nbsp;0xB381,&nbsp;0x7340,&nbsp;0xB101,&nbsp;0x71C0,&nbsp;0x7080,&nbsp;0xB041,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x5000,&nbsp;0x90C1,&nbsp;0x9181,&nbsp;0x5140,&nbsp;0x9301,&nbsp;0x53C0,&nbsp;0x5280,&nbsp;0x9241,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x9601,&nbsp;0x56C0,&nbsp;0x5780,&nbsp;0x9741,&nbsp;0x5500,&nbsp;0x95C1,&nbsp;0x9481,&nbsp;0x5440,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x9C01,&nbsp;0x5CC0,&nbsp;0x5D80,&nbsp;0x9D41,&nbsp;0x5F00,&nbsp;0x9FC1,&nbsp;0x9E81,&nbsp;0x5E40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x5A00,&nbsp;0x9AC1,&nbsp;0x9B81,&nbsp;0x5B40,&nbsp;0x9901,&nbsp;0x59C0,&nbsp;0x5880,&nbsp;0x9841,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8801,&nbsp;0x48C0,&nbsp;0x4980,&nbsp;0x8941,&nbsp;0x4B00,&nbsp;0x8BC1,&nbsp;0x8A81,&nbsp;0x4A40,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x4E00,&nbsp;0x8EC1,&nbsp;0x8F81,&nbsp;0x4F40,&nbsp;0x8D01,&nbsp;0x4DC0,&nbsp;0x4C80,&nbsp;0x8C41,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x4400,&nbsp;0x84C1,&nbsp;0x8581,&nbsp;0x4540,&nbsp;0x8701,&nbsp;0x47C0,&nbsp;0x4680,&nbsp;0x8641,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8201,&nbsp;0x42C0,&nbsp;0x4380,&nbsp;0x8341,&nbsp;0x4100,&nbsp;0x81C1,&nbsp;0x8081,&nbsp;0x4040<br> &nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;unsigned&nbsp;int&nbsp;CRC_word&nbsp;=&nbsp;0xFFFF;<br> &nbsp;<br> &nbsp;&nbsp;while(data_length--)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;*data_input++&nbsp;^&nbsp;CRC_word;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRC_word&nbsp;&gt;&gt;=&nbsp;8;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRC_word&nbsp;^=&nbsp;CRC_table[temp];<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;return&nbsp;CRC_word;<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"410\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RS485.png\" alt=\"\" class=\"wp-image-14936\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RS485.png 741w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-RS485-580x321.png 580w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, a MODBUS-based SHT20\nrelative humidity and temperature sensor is read with a STC micro. The sensor\naccepts MODBUS RTU data frames. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The setup is similar to the one we have already seen in the UART example and it should easy by now. The only exceptions are the UART module and the use of its interrupt. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> P12_push_pull_mode;<br> P55_open_drain_mode;<br> &nbsp;&nbsp;<br> UART2_pin_option(0x00);<br> &nbsp;&nbsp;<br> UART2_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART2_timer_1T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000);<br> &nbsp;<br> _enable_UART_2_interrupt;<br> _enable_global_interrupt; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The UART\u2019s interrupt is used for receiving data only.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;UART_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;8<br> {<br> &nbsp;&nbsp;if(check_UART_2_RX_flag)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;RX_buffer[cnt++]&nbsp;=&nbsp;UART2_read_buffer();<br> &nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For sending data, the following function is used. In this function, previously received data are cleared first in order to make the micro ready to receive new batch of data and to make sure that past data do not make any conflict with the new ones. The onboard MAX485\u2019s data direction is set to transmission mode and the transmission (TX) buffer data are sent via UART. MAX485\u2019s mode operation is reset back to reception mode in order to receive new data.&nbsp; &nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"371\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-106.png\" alt=\"\" class=\"wp-image-14938\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-106.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-106-580x229.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-106-768x303.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"wp-block-preformatted\">static const unsigned char TX_buffer[TX_buffer_length] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};<br> &nbsp;<br> ....<br> &nbsp;<br> void&nbsp;send_read_command(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;flush_RX_buffer();<br> &nbsp;<br> &nbsp;&nbsp;DIR_TX;<br> &nbsp;<br> &nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;TX_buffer_length;&nbsp;i++)&nbsp; <br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;UART2_write_buffer(TX_buffer[i]);<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;cnt&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;DIR_RX;<br> &nbsp;<br> &nbsp;&nbsp;delay_ms(600);<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The TX buffer contains the following information in the following order. This is the standard frame that should be sent by a host device to read holding registers. MODBUS RTU strictly prohibits other data frame formats and doing so will only lead to errors. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"146\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-107.png\" alt=\"\" class=\"wp-image-14939\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-107.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-107-580x90.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-107-768x119.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">When the sensor receives these bytes in this order, it responds back with a reception or RX frame which is something like the frame shown below. This frame is similar to the TX frame but the important stuffs are the relative humidity and temperature data. These are the stuff that we mainly need. The values in frame shown below is just for giving an example. &nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"115\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-108.png\" alt=\"\" class=\"wp-image-14940\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-108.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-108-580x71.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-108-768x94.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">As per MODBUS RTU frame shown above, the slave ID is 0x01, the function code is 0x03 and 4 data bytes have been sent by the sensor along with the CRC fields. Function code 0x03 stands for reading holding registers. The temperature and the relative humidity are computed according to the calculation shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"96\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-109.png\" alt=\"\" class=\"wp-image-14941\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-109.png 716w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-109-580x78.png 580w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The table above shows that the high and low\nbytes are combined to make word and the word is divided by 10 to get desired\noutputs. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more information on MODBUS, please refer to the docs mentioned in the beginning of this section. MODBUS RTU, itself, is a big topic and it is not possible to fully cover it in this tutorial. The code runs by querying the SHT20 sensor. After receiving all data from sensor, two Cyclic Redundancy Checks (CRC) are performed in order to ensure that valid and error-free data have been received. One CRC is the embedded with the RX frame and other is calculated using a CRC lookup table. Details of CRC lookup table and formula are covered in MODBUS RTU documentations. If CRCs match then the RX frame is considered to contain valid data and with the RX data, we can compute relative humidity and temperature values.&nbsp; &nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> send_read_command();<br> &nbsp;<br> CRC_check_1&nbsp;=&nbsp;MODBUS_RTU_CRC16(RX_buffer,&nbsp;7);<br> CRC_check_2&nbsp;=&nbsp;make_word(RX_buffer[8],&nbsp;RX_buffer[7]);<br> &nbsp;<br> if(CRC_check_1&nbsp;==&nbsp;CRC_check_2)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;make_word(RX_buffer[5],&nbsp;RX_buffer[6]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;0,&nbsp;(value&nbsp;\/&nbsp;10.0),&nbsp;1);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;make_word(RX_buffer[3],&nbsp;RX_buffer[4]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_F(11,&nbsp;1,&nbsp;(value&nbsp;\/&nbsp;10.0),&nbsp;1);<br> }<br> &nbsp;<br> else<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(12,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putstr(\"--.-\");<br> }<br> &nbsp;<br> P55_toggle;<br> delay_ms(1000); <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"508\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-110.png\" alt=\"\" class=\"wp-image-14942\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-110.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-110-580x320.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-110-768x423.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - MODBUS (RS485) Example - Reading a MODBUS Hygrometer Sensor\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/e9XLeAYte_Q?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">One Wire and Bit-Banging Technique<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One wire is not a standard system of communication unlike I2C, SPI and UART because it varies from device to device. Thus, this form of communication needs more coding rather than hardware-design consideration.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DS18B20 is a digital temperature sensor that uses one wire communication to communicate with a host microcontroller. One wire technique relies on time-slotting mechanism in which logical ones and zeroes are represented by pulses of variable widths. The same technique is used in infrared remote controllers, various sensors like SONAR sensors, relative humidity and temperature sensors like DHT22, etc and many other devices. The strategic advantage of one-wire technique is low pin count but the disadvantage is heavy software implementation and background processing. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"316\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-111.png\" alt=\"\" class=\"wp-image-14944\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-111.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-111-580x195.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-111-768x258.png 768w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-111-420x140.png 420w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Like one wire devices, sometimes we have\nto deal with hardware devices that do not follow conventional communication\ntechniques as mentioned earlier and yet again we have to drive these devices\nusing bit-banging techniques. TM1637 seven-segment display driver is such a\ndevice. Apparently, it uses something similar to I2C as two wires (clock and\ndata) are needed for communication but in practice it has no similarity with\nI2C communication at all.&nbsp;&nbsp; <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The best way to deal with such cases is to study the device datasheet and look for its timing diagrams. Timing diagrams along with proprietary protocols are all that would be needed to make libraries for these devices on our own.&nbsp; <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">one_wire.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;DS18B20_GPIO_init()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_quasi_bidirectional_mode<br> &nbsp;<br> #define&nbsp;DS18B20_IN()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_get_input<br> &nbsp;<br> #define&nbsp;DS18B20_OUT_LOW()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_low<br> #define&nbsp;DS18B20_OUT_HIGH()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_high<br> &nbsp;<br> #define&nbsp;TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1<br> #define&nbsp;FALSE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;0<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_reset(void);&nbsp;<br> void&nbsp;onewire_write_bit(unsigned&nbsp;char&nbsp;bit_value);<br> unsigned&nbsp;char&nbsp;onewire_read_bit(void);<br> void&nbsp;onewire_write(unsigned&nbsp;char&nbsp;value);&nbsp;&nbsp;&nbsp;&nbsp;<br> unsigned&nbsp;char&nbsp;onewire_read(void); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">one_wire.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"one_wire.h\"<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_reset(void)&nbsp;&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;res&nbsp;=&nbsp;FALSE;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_GPIO_init();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(480);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res&nbsp;=&nbsp;DS18B20_IN();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(480);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;res;&nbsp;<br> }&nbsp;<br> &nbsp;<br> void&nbsp;onewire_write_bit(unsigned&nbsp;char&nbsp;bit_value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(bit_value)<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(104);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_read_bit(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp; &nbsp;delay_us(15);&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return(DS18B20_IN());&nbsp;&nbsp;&nbsp;&nbsp;<br> }<br> &nbsp;<br> void&nbsp;onewire_write(unsigned&nbsp;char&nbsp;value)&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&lt;&nbsp;8)&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&amp;&nbsp;(1&nbsp;&lt;&lt;&nbsp;s)))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_read(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&lt;&nbsp;8)&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(DS18B20_IN())&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;&nbsp;(1&nbsp;&lt;&lt;&nbsp;s);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> }&nbsp;&nbsp;&nbsp;&nbsp; <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DS18B20.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"one_wire.c\"&nbsp;&nbsp;<br> &nbsp;<br> #define&nbsp;convert_T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x44<br> #define&nbsp;read_scratchpad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xBE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;write_scratchpad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x4E&nbsp;<br> #define&nbsp;copy_scratchpad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x48&nbsp;&nbsp;&nbsp;<br> #define&nbsp;recall_E2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xB8&nbsp;<br> #define&nbsp;read_power_supply&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xB4&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;skip_ROM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xCC<br> &nbsp;<br> #define&nbsp;resolution&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12<br> &nbsp;<br> void&nbsp;DS18B20_init(void);<br> float&nbsp;DS18B20_get_temperature(void);&nbsp;&nbsp; <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DS18B20.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"DS18B20.h\"<br> &nbsp;<br> void&nbsp;DS18B20_init(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_reset();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(100);<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> float&nbsp;DS18B20_get_temperature(void)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;msb&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;lsb&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;float&nbsp;temp&nbsp;=&nbsp;0.0;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_reset();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_write(skip_ROM);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_write(convert_T);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(resolution)&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;12:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(750);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;11:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(375);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;10:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(188);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;9:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(94);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_reset();&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_write(skip_ROM);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;onewire_write(read_scratchpad);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;lsb&nbsp;=&nbsp;onewire_read();<br> &nbsp;&nbsp;&nbsp;&nbsp;msb&nbsp;=&nbsp;onewire_read();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;msb;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;*=&nbsp;256.0;<br> &nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;+=&nbsp;lsb;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(resolution)&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;12:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;*=&nbsp;0.0625;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;11:&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;*=&nbsp;0.125;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;10:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;*=&nbsp;0.25;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;9:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;*=&nbsp;0.5;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(40);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(temp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">TM1637.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;TM1637_CLK_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P41_high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;TM1637_CLK_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P41_low&nbsp;<br> &nbsp;<br> #define&nbsp;TM1637_DAT_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P42_high<br> #define&nbsp;TM1637_DAT_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P42_low<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;TM1637_DELAY_US&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<br> &nbsp;<br> #define&nbsp;TM1637_BRIGHTNESS_MIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;TM1637_BRIGHTNESS_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;TM1637_BRIGHTNESS_2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<br> #define&nbsp;TM1637_BRIGHTNESS_3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<br> #define&nbsp;TM1637_BRIGHTNESS_4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<br> #define&nbsp;TM1637_BRIGHTNESS_5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;TM1637_BRIGHTNESS_6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6<br> #define&nbsp;TM1637_BRIGHTNESS_MAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;TM1637_POSITION_MAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<br> &nbsp;<br> #define&nbsp;TM1637_CMD_SET_DATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x40<br> #define&nbsp;TM1637_CMD_SET_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xC0<br> #define&nbsp;TM1637_CMD_SET_DSIPLAY&nbsp;&nbsp;&nbsp;0x80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> #define&nbsp;TM1637_SET_DATA_WRITE&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;TM1637_SET_DATA_READ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> #define&nbsp;TM1637_SET_DATA_A_ADDR&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;TM1637_SET_DATA_F_ADDR&nbsp;&nbsp;&nbsp;0x04<br> #define&nbsp;TM1637_SET_DATA_M_NORM&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;TM1637_SET_DATA_M_TEST&nbsp;&nbsp;&nbsp;0x10<br> #define&nbsp;TM1637_SET_DISPLAY_OFF&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;TM1637_SET_DISPLAY_ON&nbsp;&nbsp;&nbsp;&nbsp;0x08&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> const&nbsp;unsigned&nbsp;char&nbsp;seg_data[10]&nbsp;=<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;0x3F,&nbsp;\/\/&nbsp;0<br> &nbsp;&nbsp;&nbsp;&nbsp;0x06,&nbsp;\/\/&nbsp;1<br> &nbsp;&nbsp;&nbsp;&nbsp;0x5B,&nbsp;\/\/&nbsp;2<br> &nbsp;&nbsp;&nbsp;&nbsp;0x4F,&nbsp;\/\/&nbsp;3<br> &nbsp;&nbsp;&nbsp;&nbsp;0x66,&nbsp;\/\/&nbsp;4<br> &nbsp;&nbsp;&nbsp;&nbsp;0x6D,&nbsp;\/\/&nbsp;5<br> &nbsp;&nbsp;&nbsp;&nbsp;0x7D,&nbsp;\/\/&nbsp;6<br> &nbsp;&nbsp;&nbsp;&nbsp;0x07,&nbsp;\/\/&nbsp;7<br> &nbsp;&nbsp;&nbsp;&nbsp;0x7F,&nbsp;\/\/&nbsp;8<br> &nbsp;&nbsp;&nbsp;&nbsp;0x6F&nbsp;&nbsp;\/\/&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> };&nbsp;<br> &nbsp;<br> void&nbsp;TM1637_init(void);<br> void&nbsp;TM1637_start(void);<br> void&nbsp;TM1637_stop(void);<br> unsigned&nbsp;char&nbsp;TM1637_write_byte(unsigned&nbsp;char&nbsp;value);<br> void&nbsp;TM1637_send_command(unsigned&nbsp;char&nbsp;value);<br> void&nbsp;TM1637_clear(void);<br> void&nbsp;TM1637_display_segments(unsigned&nbsp;char&nbsp;position,&nbsp;unsigned&nbsp;char&nbsp;segment_value,&nbsp;unsigned&nbsp;char&nbsp;colon_state); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">TM1637.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"TM1637.h\"<br> &nbsp;<br> void&nbsp;TM1637_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;P41_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P42_push_pull_mode;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_send_command(TM1637_CMD_SET_DSIPLAY&nbsp;|&nbsp;TM1637_BRIGHTNESS_2&nbsp;|&nbsp;TM1637_SET_DISPLAY_ON);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_clear();<br> }<br> &nbsp;<br> void&nbsp;TM1637_start(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> }<br> &nbsp;<br> void&nbsp;TM1637_stop(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;TM1637_write_byte(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x08;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ack&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&amp;&nbsp;0x01)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&gt;&gt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ack&nbsp;=&nbsp;P42_get_input;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(ack&nbsp;!=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(ack);<br> }<br> &nbsp;<br> void&nbsp;TM1637_send_command(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_write_byte(value);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_stop();<br> }<br> &nbsp;<br> void&nbsp;TM1637_clear(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;char&nbsp;i&nbsp;=&nbsp;(TM1637_POSITION_MAX&nbsp;-&nbsp;1);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;-1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(i,&nbsp;0x00,&nbsp;0x00);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> <br> <br><br> <br><br> void&nbsp;TM1637_display_segments(unsigned&nbsp;char&nbsp;position,&nbsp;unsigned&nbsp;char&nbsp;segment_value,&nbsp;unsigned&nbsp;char&nbsp;colon_state)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(position&nbsp;==&nbsp;1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(colon_state)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;segment_value&nbsp;|=&nbsp;0x80;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;segment_value&nbsp;&amp;=&nbsp;0x7F;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_send_command(TM1637_CMD_SET_DATA&nbsp;|&nbsp;TM1637_SET_DATA_F_ADDR);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_write_byte(TM1637_CMD_SET_ADDR&nbsp;|&nbsp;(position&nbsp;&amp;&nbsp;(TM1637_POSITION_MAX&nbsp;-&nbsp;1)));<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_write_byte(segment_value);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_stop();<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"DS18B20.c\"<br> #include&nbsp;\"TM1637.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;signed&nbsp;long&nbsp;t&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;=&nbsp;((signed&nbsp;long)DS18B20_get_temperature());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((t&nbsp;&gt;&nbsp;999)&nbsp;&amp;&amp;&nbsp;(t&nbsp;&gt;=&nbsp;0))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(0,&nbsp;0x40,&nbsp;0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(1,&nbsp;0x40,&nbsp;0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(0,&nbsp;seg_data[(t&nbsp;\/&nbsp;10)],&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(1,&nbsp;seg_data[(t&nbsp;%&nbsp;10)],&nbsp;0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(2,&nbsp;0x63,&nbsp;0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_display_segments(3,&nbsp;0x39,&nbsp;0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(600);&nbsp;<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;TM1637_init();<br> &nbsp;&nbsp;DS18B20_init();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"628\" height=\"314\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Bit-Banging.png\" alt=\"\" class=\"wp-image-14945\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Bit-Banging.png 628w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-Bit-Banging-580x290.png 580w\" sizes=\"auto, (max-width: 628px) 100vw, 628px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">DS18B20\u2019s one communication basics are shown below. Notice how time-slotting technique is being employed.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"680\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-112.png\" alt=\"\" class=\"wp-image-14946\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-112.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-112-580x420.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-112-768x556.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">These timing diagrams are what that have been use to compose the following codes:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;onewire_write_bit(unsigned&nbsp;char&nbsp;bit_value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(bit_value)<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(104);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_read_bit(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp; &nbsp;delay_us(15);&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return(DS18B20_IN());&nbsp;&nbsp;&nbsp;&nbsp;<br> }<br> &nbsp;<br> void&nbsp;onewire_write(unsigned&nbsp;char&nbsp;value)&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&lt;&nbsp;8)&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&amp;&nbsp;(1&nbsp;&lt;&lt;&nbsp;s)))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;onewire_read(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&lt;&nbsp;8)&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_nop_();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DS18B20_OUT_HIGH();&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(DS18B20_IN())&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;&nbsp;(1&nbsp;&lt;&lt;&nbsp;s);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(60);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;value;<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Details of DS18B20\u2019s one wire\ncommunication can be found in the following application notes from Maxim.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/126\">https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/126<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/162\">https:\/\/www.maximintegrated.com\/en\/app-notes\/index.mvp\/id\/162<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These notes are all that are needed for implementing the one wire communication interface for DS18B20. Please go through these notes. The codes are self-explanatory and are implemented from the code examples in these app notes.  It is worth mentioning that pin declarations should be checked before actually hooking any device.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;DS18B20_GPIO_init()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_quasi_bidirectional_mode<br> &nbsp;<br> #define&nbsp;DS18B20_IN()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_get_input<br> &nbsp;<br> #define&nbsp;DS18B20_OUT_LOW()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_low<br> #define&nbsp;DS18B20_OUT_HIGH()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P30_high <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bit-banging TM1637 is achieved by implementing what have been documented in the <strong><em>Interface interpretation<\/em><\/strong> section of the datasheet.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"133\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-113.png\" alt=\"\" class=\"wp-image-14947\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-113.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-113-580x82.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-113-768x109.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The following codes are the coded representation of the communication timing diagram of the device. Again, I insist readers to go through device datasheet for details and explanation. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;TM1637_start(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> }<br> &nbsp;<br> void&nbsp;TM1637_stop(void)<br> {<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;TM1637_write_byte(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x08;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ack&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&amp;&nbsp;0x01)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&gt;&gt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ack&nbsp;=&nbsp;P42_get_input;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(ack&nbsp;!=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TM1637_DAT_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;TM1637_CLK_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(TM1637_DELAY_US);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(ack);<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The demo here is a simple DS18B20-based thermometer. The temperature sensed by the DS18B20 sensor is displayed on a TM1637-based seven segment displays.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"636\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-114.png\" alt=\"\" class=\"wp-image-14948\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-114.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-114-580x400.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-114-768x530.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - One Wire and Bit-Banging Example  - Interfacing DS18B20 and TM1637 with STC Micro\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/2SP1hiXuvfM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Software SPI and One Wire\nBit-Banging<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Software SPI is basically bit-banging ordinary GPIO pins to reproduce SPI signals. Software SPI is not needed unless hardware SPI peripheral is absent in the device or hardware SPI pins are used up for some other tasks. Though it is slow and require extra coding compared to hardware SPI, it is helpful for beginners to understand SPI-based hardware as it offers full control over all SPI signals. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"494\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-115.png\" alt=\"\" class=\"wp-image-14949\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-115.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-115-580x311.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-115-768x411.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Likewise, bit-banging can also be applied\nto communicate with one wire devices such as DHT11, DHT22, etc.&nbsp; <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this section, we will see how to use bit-banging to read a DHT11 sensor and show temperature and relative humidity data on a SPI-based SSD1306 OLED display. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">DHT11.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;DHT11_pin_init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_quasi_bidirectional_mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> #define&nbsp;DHT11_pin_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P10_high<br> #define&nbsp;DHT11_pin_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P10_low<br> &nbsp;<br> #define&nbsp;DHT11_pin_IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_get_input&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;values[5];<br> &nbsp;<br> void&nbsp;DHT11_init(void);<br> unsigned&nbsp;char&nbsp;DHT11_get_byte(void);<br> unsigned&nbsp;char&nbsp;DHT11_get_data(void); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">DHT11.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"DHT11.h\"<br> &nbsp;<br> extern&nbsp;unsigned&nbsp;char&nbsp;values[5]&nbsp;=&nbsp;{0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00};&nbsp;<br> &nbsp;<br> void&nbsp;DHT11_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;DHT11_pin_init;<br> &nbsp;&nbsp;&nbsp;delay_ms(1000);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DHT11_get_byte(void)<br> {<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x08;<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)&nbsp;<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(DHT11_pin_IN&nbsp;==&nbsp;LOW);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;large_delay_TMR_0(30);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(DHT11_pin_IN&nbsp;==&nbsp;HIGH)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(DHT11_pin_IN&nbsp;==&nbsp;HIGH);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;return&nbsp;value;<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;DHT11_get_data(void)<br> {<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;check_sum&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;DHT11_pin_HIGH;<br> &nbsp;&nbsp;&nbsp;DHT11_pin_LOW;<br> &nbsp;&nbsp;&nbsp;large_delay_TMR_0(18000);<br> &nbsp;&nbsp;&nbsp;DHT11_pin_HIGH;<br> &nbsp;&nbsp;&nbsp;large_delay_TMR_0(26);<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;if(DHT11_pin_IN&nbsp;==&nbsp;HIGH)<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;large_delay_TMR_0(80);<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;if(DHT11_pin_IN&nbsp;==&nbsp;LOW)<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;2;<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;large_delay_TMR_0(80);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;=&nbsp;4;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values[s]&nbsp;=&nbsp;DHT11_get_byte();<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;DHT11_pin_HIGH;&nbsp;<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;&nbsp;4;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;check_sum&nbsp;+=&nbsp;values[s];<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;if(check_sum&nbsp;!=&nbsp;values[4])<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;3;<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br> &nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">font.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> const&nbsp;unsigned&nbsp;char&nbsp;font_regular[92][6]&nbsp;=<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;sp<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x2f,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;!<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x07,&nbsp;0x00,&nbsp;0x07,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;\"<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x14,&nbsp;0x7f,&nbsp;0x14,&nbsp;0x7f,&nbsp;0x14,&nbsp;&nbsp;&nbsp;\/\/&nbsp;#<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x24,&nbsp;0x2a,&nbsp;0x7f,&nbsp;0x2a,&nbsp;0x12,&nbsp;&nbsp;&nbsp;\/\/&nbsp;$<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x62,&nbsp;0x64,&nbsp;0x08,&nbsp;0x13,&nbsp;0x23,&nbsp;&nbsp;&nbsp;\/\/&nbsp;%<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x36,&nbsp;0x49,&nbsp;0x55,&nbsp;0x22,&nbsp;0x50,&nbsp;&nbsp;&nbsp;\/\/&nbsp;&amp;<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x05,&nbsp;0x03,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;'<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x1c,&nbsp;0x22,&nbsp;0x41,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;(<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x41,&nbsp;0x22,&nbsp;0x1c,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x14,&nbsp;0x08,&nbsp;0x3E,&nbsp;0x08,&nbsp;0x14,&nbsp;&nbsp;&nbsp;\/\/&nbsp;*<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x08,&nbsp;0x08,&nbsp;0x3E,&nbsp;0x08,&nbsp;0x08,&nbsp;&nbsp;&nbsp;\/\/&nbsp;+<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0xA0,&nbsp;0x60,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;,<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x08,&nbsp;0x08,&nbsp;0x08,&nbsp;0x08,&nbsp;0x08,&nbsp;&nbsp;&nbsp;\/\/&nbsp;-<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x60,&nbsp;0x60,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;.<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x20,&nbsp;0x10,&nbsp;0x08,&nbsp;0x04,&nbsp;0x02,&nbsp;&nbsp;&nbsp;\/\/&nbsp;\/<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3E,&nbsp;0x51,&nbsp;0x49,&nbsp;0x45,&nbsp;0x3E,&nbsp;&nbsp;&nbsp;\/\/&nbsp;0<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x42,&nbsp;0x7F,&nbsp;0x40,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;1<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x42,&nbsp;0x61,&nbsp;0x51,&nbsp;0x49,&nbsp;0x46,&nbsp;&nbsp;&nbsp;\/\/&nbsp;2<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x21,&nbsp;0x41,&nbsp;0x45,&nbsp;0x4B,&nbsp;0x31,&nbsp;&nbsp;&nbsp;\/\/&nbsp;3<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x18,&nbsp;0x14,&nbsp;0x12,&nbsp;0x7F,&nbsp;0x10,&nbsp;&nbsp;&nbsp;\/\/&nbsp;4<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x27,&nbsp;0x45,&nbsp;0x45,&nbsp;0x45,&nbsp;0x39,&nbsp;&nbsp;&nbsp;\/\/&nbsp;5<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3C,&nbsp;0x4A,&nbsp;0x49,&nbsp;0x49,&nbsp;0x30,&nbsp;&nbsp;&nbsp;\/\/&nbsp;6<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x01,&nbsp;0x71,&nbsp;0x09,&nbsp;0x05,&nbsp;0x03,&nbsp;&nbsp;&nbsp;\/\/&nbsp;7<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x36,&nbsp;0x49,&nbsp;0x49,&nbsp;0x49,&nbsp;0x36,&nbsp;&nbsp;&nbsp;\/\/&nbsp;8<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x06,&nbsp;0x49,&nbsp;0x49,&nbsp;0x29,&nbsp;0x1E,&nbsp;&nbsp;&nbsp;\/\/&nbsp;9<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x36,&nbsp;0x36,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;:<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x56,&nbsp;0x36,&nbsp;0x00,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;;<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x08,&nbsp;0x14,&nbsp;0x22,&nbsp;0x41,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;&lt;<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;&nbsp;&nbsp;\/\/&nbsp;=<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x41,&nbsp;0x22,&nbsp;0x14,&nbsp;0x08,&nbsp;&nbsp;&nbsp;\/\/&nbsp;&gt;<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x02,&nbsp;0x01,&nbsp;0x51,&nbsp;0x09,&nbsp;0x06,&nbsp;&nbsp;&nbsp;\/\/&nbsp;?<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x32,&nbsp;0x49,&nbsp;0x59,&nbsp;0x51,&nbsp;0x3E,&nbsp;&nbsp;&nbsp;\/\/&nbsp;@<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7C,&nbsp;0x12,&nbsp;0x11,&nbsp;0x12,&nbsp;0x7C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;A<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x49,&nbsp;0x49,&nbsp;0x49,&nbsp;0x36,&nbsp;&nbsp;&nbsp;\/\/&nbsp;B<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3E,&nbsp;0x41,&nbsp;0x41,&nbsp;0x41,&nbsp;0x22,&nbsp;&nbsp;&nbsp;\/\/&nbsp;C<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x41,&nbsp;0x41,&nbsp;0x22,&nbsp;0x1C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;D<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x49,&nbsp;0x49,&nbsp;0x49,&nbsp;0x41,&nbsp;&nbsp;&nbsp;\/\/&nbsp;E<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x09,&nbsp;0x09,&nbsp;0x09,&nbsp;0x01,&nbsp;&nbsp;&nbsp;\/\/&nbsp;F<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3E,&nbsp;0x41,&nbsp;0x49,&nbsp;0x49,&nbsp;0x7A,&nbsp;&nbsp;&nbsp;\/\/&nbsp;G<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x08,&nbsp;0x08,&nbsp;0x08,&nbsp;0x7F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;H<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x41,&nbsp;0x7F,&nbsp;0x41,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;I<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x20,&nbsp;0x40,&nbsp;0x41,&nbsp;0x3F,&nbsp;0x01,&nbsp;&nbsp;&nbsp;\/\/&nbsp;J<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x08,&nbsp;0x14,&nbsp;0x22,&nbsp;0x41,&nbsp;&nbsp;&nbsp;\/\/&nbsp;K<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;&nbsp;&nbsp;\/\/&nbsp;L<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x02,&nbsp;0x0C,&nbsp;0x02,&nbsp;0x7F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;M<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x04,&nbsp;0x08,&nbsp;0x10,&nbsp;0x7F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;N<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3E,&nbsp;0x41,&nbsp;0x41,&nbsp;0x41,&nbsp;0x3E,&nbsp;&nbsp;&nbsp;\/\/&nbsp;O<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x09,&nbsp;0x09,&nbsp;0x09,&nbsp;0x06,&nbsp;&nbsp;&nbsp;\/\/&nbsp;P<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3E,&nbsp;0x41,&nbsp;0x51,&nbsp;0x21,&nbsp;0x5E,&nbsp;&nbsp;&nbsp;\/\/&nbsp;Q<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x09,&nbsp;0x19,&nbsp;0x29,&nbsp;0x46,&nbsp;&nbsp;&nbsp;\/\/&nbsp;R<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x46,&nbsp;0x49,&nbsp;0x49,&nbsp;0x49,&nbsp;0x31,&nbsp;&nbsp;&nbsp;\/\/&nbsp;S<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x01,&nbsp;0x01,&nbsp;0x7F,&nbsp;0x01,&nbsp;0x01,&nbsp;&nbsp;&nbsp;\/\/&nbsp;T<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3F,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;0x3F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;U<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x1F,&nbsp;0x20,&nbsp;0x40,&nbsp;0x20,&nbsp;0x1F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;V<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3F,&nbsp;0x40,&nbsp;0x38,&nbsp;0x40,&nbsp;0x3F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;W<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x63,&nbsp;0x14,&nbsp;0x08,&nbsp;0x14,&nbsp;0x63,&nbsp;&nbsp;&nbsp;\/\/&nbsp;X<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x07,&nbsp;0x08,&nbsp;0x70,&nbsp;0x08,&nbsp;0x07,&nbsp;&nbsp;&nbsp;\/\/&nbsp;Y<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x61,&nbsp;0x51,&nbsp;0x49,&nbsp;0x45,&nbsp;0x43,&nbsp;&nbsp;&nbsp;\/\/&nbsp;Z<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x7F,&nbsp;0x41,&nbsp;0x41,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;[&nbsp;91<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x02,&nbsp;0x04,&nbsp;0x08,&nbsp;0x10,&nbsp;0x20,&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;\\92<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x41,&nbsp;0x41,&nbsp;0x7F,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;]<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x04,&nbsp;0x02,&nbsp;0x01,&nbsp;0x02,&nbsp;0x04,&nbsp;&nbsp;&nbsp;\/\/&nbsp;^<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;0x40,&nbsp;&nbsp;&nbsp;\/\/&nbsp;_<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x01,&nbsp;0x02,&nbsp;0x04,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;'<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x20,&nbsp;0x54,&nbsp;0x54,&nbsp;0x54,&nbsp;0x78,&nbsp;&nbsp;&nbsp;\/\/&nbsp;a<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x48,&nbsp;0x44,&nbsp;0x44,&nbsp;0x38,&nbsp;&nbsp;&nbsp;\/\/&nbsp;b<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x38,&nbsp;0x44,&nbsp;0x44,&nbsp;0x44,&nbsp;0x20,&nbsp;&nbsp;&nbsp;\/\/&nbsp;c<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x38,&nbsp;0x44,&nbsp;0x44,&nbsp;0x48,&nbsp;0x7F,&nbsp;&nbsp;&nbsp;\/\/&nbsp;d<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x38,&nbsp;0x54,&nbsp;0x54,&nbsp;0x54,&nbsp;0x18,&nbsp;&nbsp;&nbsp;\/\/&nbsp;e<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x08,&nbsp;0x7E,&nbsp;0x09,&nbsp;0x01,&nbsp;0x02,&nbsp;&nbsp;&nbsp;\/\/&nbsp;f<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x18,&nbsp;0xA4,&nbsp;0xA4,&nbsp;0xA4,&nbsp;0x7C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;g<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x08,&nbsp;0x04,&nbsp;0x04,&nbsp;0x78,&nbsp;&nbsp;&nbsp;\/\/&nbsp;h<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x44,&nbsp;0x7D,&nbsp;0x40,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;i<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x40,&nbsp;0x80,&nbsp;0x84,&nbsp;0x7D,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;j<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7F,&nbsp;0x10,&nbsp;0x28,&nbsp;0x44,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;k<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x00,&nbsp;0x41,&nbsp;0x7F,&nbsp;0x40,&nbsp;0x00,&nbsp;&nbsp;&nbsp;\/\/&nbsp;l<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7C,&nbsp;0x04,&nbsp;0x18,&nbsp;0x04,&nbsp;0x78,&nbsp;&nbsp;&nbsp;\/\/&nbsp;m<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7C,&nbsp;0x08,&nbsp;0x04,&nbsp;0x04,&nbsp;0x78,&nbsp;&nbsp;&nbsp;\/\/&nbsp;n<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x38,&nbsp;0x44,&nbsp;0x44,&nbsp;0x44,&nbsp;0x38,&nbsp;&nbsp;&nbsp;\/\/&nbsp;o<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0xFC,&nbsp;0x24,&nbsp;0x24,&nbsp;0x24,&nbsp;0x18,&nbsp;&nbsp;&nbsp;\/\/&nbsp;p<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x18,&nbsp;0x24,&nbsp;0x24,&nbsp;0x18,&nbsp;0xFC,&nbsp;&nbsp;&nbsp;\/\/&nbsp;q<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x7C,&nbsp;0x08,&nbsp;0x04,&nbsp;0x04,&nbsp;0x08,&nbsp;&nbsp;&nbsp;\/\/&nbsp;r<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x48,&nbsp;0x54,&nbsp;0x54,&nbsp;0x54,&nbsp;0x20,&nbsp;&nbsp;&nbsp;\/\/&nbsp;s<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x04,&nbsp;0x3F,&nbsp;0x44,&nbsp;0x40,&nbsp;0x20,&nbsp;&nbsp;&nbsp;\/\/&nbsp;t<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3C,&nbsp;0x40,&nbsp;0x40,&nbsp;0x20,&nbsp;0x7C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;u<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x1C,&nbsp;0x20,&nbsp;0x40,&nbsp;0x20,&nbsp;0x1C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;v<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x3C,&nbsp;0x40,&nbsp;0x30,&nbsp;0x40,&nbsp;0x3C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;w<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x44,&nbsp;0x28,&nbsp;0x10,&nbsp;0x28,&nbsp;0x44,&nbsp;&nbsp;&nbsp;\/\/&nbsp;x<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x1C,&nbsp;0xA0,&nbsp;0xA0,&nbsp;0xA0,&nbsp;0x7C,&nbsp;&nbsp;&nbsp;\/\/&nbsp;y<br> &nbsp;&nbsp;&nbsp;&nbsp;0x00,&nbsp;0x44,&nbsp;0x64,&nbsp;0x54,&nbsp;0x4C,&nbsp;0x44,&nbsp;&nbsp;&nbsp;\/\/&nbsp;z<br> &nbsp;&nbsp;&nbsp;&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14,&nbsp;0x14&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;horiz&nbsp;lines<br> }; <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">SSD1306.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;SSD1306_CS_PIN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P03_high<br> #define&nbsp;SSD1306_CS_PIN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P03_low<br> &nbsp;<br> #define&nbsp;SSD1306_DC_PIN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P04_high<br> #define&nbsp;SSD1306_DC_PIN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P04_low<br> &nbsp;<br> #define&nbsp;SSD1306_RST_PIN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P05_high<br> #define&nbsp;SSD1306_RST_PIN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P05_low<br> &nbsp;<br> #define&nbsp;SSD1306_SDA_PIN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P06_high<br> #define&nbsp;SSD1306_SDA_PIN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P06_low<br> &nbsp;<br> #define&nbsp;SSD1306_SCK_PIN_HIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P07_high<br> #define&nbsp;SSD1306_SCK_PIN_LOW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P07_low<br> &nbsp;<br> #define&nbsp;DAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Set_Lower_Column_Start_Address_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Set_Higher_Column_Start_Address_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x10<br> #define&nbsp;Set_Memory_Addressing_Mode_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20<br> #define&nbsp;Set_Column_Address_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x21<br> #define&nbsp;Set_Page_Address_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x22<br> #define&nbsp;Set_Display_Start_Line_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x40<br> #define&nbsp;Set_Contrast_Control_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x81<br> #define&nbsp;Set_Charge_Pump_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8D<br> #define&nbsp;Set_Segment_Remap_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA0<br> #define&nbsp;Set_Entire_Display_ON_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA4<br> #define&nbsp;Set_Normal_or_Inverse_Display_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA6<br> #define&nbsp;Set_Multiplex_Ratio_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA8<br> #define&nbsp;Set_Display_ON_or_OFF_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xAE<br> #define&nbsp;Set_Page_Start_Address_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xB0<br> #define&nbsp;Set_COM_Output_Scan_Direction_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xC0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Set_Display_Offset_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD3<br> #define&nbsp;Set_Display_Clock_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD5<br> #define&nbsp;Set_Pre_charge_Period_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xD9<br> #define&nbsp;Set_Common_HW_Config_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xDA<br> #define&nbsp;Set_VCOMH_Level_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xDB<br> #define&nbsp;Set_NOP_CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xE3<br> &nbsp;<br> #define&nbsp;Horizontal_Addressing_Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Vertical_Addressing_Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;Page_Addressing_Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> &nbsp;<br> #define&nbsp;Disable_Charge_Pump&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Enable_Charge_Pump&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Column_Address_0_Mapped_to_SEG0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Column_Address_0_Mapped_to_SEG127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> &nbsp;<br> #define&nbsp;Normal_Display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Entire_Display_ON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Non_Inverted_Display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Inverted_Display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;Display_OFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Display_ON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> &nbsp;<br> #define&nbsp;Scan_from_COM0_to_63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> #define&nbsp;Scan_from_COM63_to_0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x08<br> &nbsp;<br> #define&nbsp;x_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;128<br> #define&nbsp;x_max&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_size<br> #define&nbsp;x_min&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> #define&nbsp;y_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;64<br> #define&nbsp;y_max&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8<br> #define&nbsp;y_min&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;<br> #define&nbsp;ON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;OFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;<br> #define&nbsp;ROUND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;SQUARE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br> &nbsp;<br> #define&nbsp;buffer_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1024\/\/(x_max&nbsp;*&nbsp;y_max)<br> &nbsp;<br> unsigned&nbsp;char&nbsp;buffer[buffer_size];<br> &nbsp;<br> void&nbsp;OLED_init(void);<br> void&nbsp;OLED_reset_sequence(void);<br> void&nbsp;OLED_write(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;type);<br> void&nbsp;OLED_gotoxy(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos);<br> void&nbsp;OLED_fill(unsigned&nbsp;char&nbsp;bmp_data);<br> void&nbsp;OLED_clear_screen(void);<br> void&nbsp;OLED_clear_buffer(void);<br> void&nbsp;OLED_cursor(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos);<br> void&nbsp;OLED_draw_bitmap(unsigned&nbsp;char&nbsp;xb,&nbsp;unsigned&nbsp;char&nbsp;yb,&nbsp;unsigned&nbsp;char&nbsp;xe,&nbsp;unsigned&nbsp;char&nbsp;ye,&nbsp;unsigned&nbsp;char&nbsp;bmp_img[]);&nbsp;&nbsp;<br> void&nbsp;OLED_print_char(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;ch);<br> void&nbsp;OLED_print_string(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;*ch);<br> void&nbsp;OLED_print_chr(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value);<br> void&nbsp;OLED_print_int(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value);<br> void&nbsp;OLED_print_decimal(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;long&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points);<br> void&nbsp;OLED_print_float(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;float&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points);&nbsp;<br> void&nbsp;Draw_Pixel(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;short&nbsp;colour);<br> void&nbsp;Draw_Line(signed&nbsp;long&nbsp;x1,&nbsp;signed&nbsp;long&nbsp;y1,&nbsp;signed&nbsp;long&nbsp;x2,&nbsp;signed&nbsp;long&nbsp;y2,&nbsp;short&nbsp;colour);<br> void&nbsp;Draw_Rectangle(signed&nbsp;long&nbsp;x1,&nbsp;signed&nbsp;long&nbsp;y1,&nbsp;signed&nbsp;long&nbsp;x2,&nbsp;signed&nbsp;long&nbsp;y2,&nbsp;short&nbsp;fill,&nbsp;short&nbsp;colour,&nbsp;short&nbsp;type);<br> void&nbsp;Draw_Circle(signed&nbsp;long&nbsp;xc,&nbsp;signed&nbsp;long&nbsp;yc,&nbsp;signed&nbsp;long&nbsp;radius,&nbsp;short&nbsp;fill,&nbsp;short&nbsp;colour); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">SSD1306.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"SSD1306.h\"<br> #include&nbsp;\"fonts.c\"&nbsp;<br> &nbsp;<br> void&nbsp;OLED_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;P03_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P04_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P05_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P06_push_pull_mode;<br> &nbsp;&nbsp;&nbsp;&nbsp;P07_push_pull_mode;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_clear_buffer();<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_reset_sequence();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Display_ON_or_OFF_CMD&nbsp;+&nbsp;Display_OFF)&nbsp;,&nbsp;CMD);;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Display_Clock_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0x80,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Multiplex_Ratio_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0x3F,&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Display_Offset_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0x00,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Display_Start_Line_CMD&nbsp;|&nbsp;0x00),&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Charge_Pump_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Higher_Column_Start_Address_CMD&nbsp;|&nbsp;0x04),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Memory_Addressing_Mode_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Page_Addressing_Mode,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Segment_Remap_CMD&nbsp;|&nbsp;Column_Address_0_Mapped_to_SEG127),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_COM_Output_Scan_Direction_CMD&nbsp;|&nbsp;Scan_from_COM63_to_0),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Common_HW_Config_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0x12,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Contrast_Control_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0xCF,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Pre_charge_Period_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0xF1,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_VCOMH_Level_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0x40,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Entire_Display_ON_CMD&nbsp;|&nbsp;Normal_Display),&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Normal_or_Inverse_Display_CMD&nbsp;|&nbsp;Non_Inverted_Display),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Display_ON_or_OFF_CMD&nbsp;+&nbsp;Display_ON)&nbsp;,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(0,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_clear_screen();<br> }<br> &nbsp;<br> void&nbsp;OLED_reset_sequence(void)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_HIGH;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_RST_PIN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_RST_PIN_HIGH;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_LOW;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(60);<br> }<br> &nbsp;<br> void&nbsp;OLED_write(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;type)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x08;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_CS_PIN_LOW;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(type)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;DAT:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_DC_PIN_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_DC_PIN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&amp;&nbsp;0x80)&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SDA_PIN_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SDA_PIN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_HIGH;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_LOW;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_CS_PIN_HIGH;&nbsp;<br> }&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;OLED_gotoxy(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Page_Start_Address_CMD&nbsp;+&nbsp;y_pos),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(((x_pos&nbsp;&amp;&nbsp;0x0F)&nbsp;|&nbsp;Set_Lower_Column_Start_Address_CMD),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write((((x_pos&nbsp;&amp;&nbsp;0xF0)&nbsp;&gt;&gt;&nbsp;0x04)&nbsp;|&nbsp;Set_Higher_Column_Start_Address_CMD),&nbsp;CMD);<br> }<br> &nbsp;<br> void&nbsp;OLED_fill(unsigned&nbsp;char&nbsp;bmp_data)&nbsp;<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;x_pos&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;page&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(page&nbsp;=&nbsp;y_min;&nbsp;page&nbsp;&lt;&nbsp;y_max;&nbsp;page++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write((Set_Page_Start_Address_CMD&nbsp;+&nbsp;page),&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Lower_Column_Start_Address_CMD,&nbsp;CMD);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(Set_Higher_Column_Start_Address_CMD,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(x_pos&nbsp;=&nbsp;x_min;&nbsp;x_pos&nbsp;&lt;&nbsp;x_max;&nbsp;x_pos++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(bmp_data,&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br> }&nbsp;<br> &nbsp;<br> void&nbsp;OLED_clear_screen(void)<br> {&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_fill(0x00);<br> }<br> &nbsp;<br> void&nbsp;OLED_clear_buffer(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;s&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0;&nbsp;s&nbsp;&lt;&nbsp;buffer_size;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer[s]&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;OLED_cursor(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(y_pos&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(x_pos&nbsp;==&nbsp;1)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(0x00,&nbsp;(y_pos&nbsp;+&nbsp;0x02));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy((0x50&nbsp;+&nbsp;((x_pos&nbsp;-&nbsp;0x02)&nbsp;*&nbsp;0x06)),&nbsp;(y_pos&nbsp;+&nbsp;0x02));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;6;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(0xFF,&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;OLED_draw_bitmap(unsigned&nbsp;char&nbsp;xb,&nbsp;unsigned&nbsp;char&nbsp;yb,&nbsp;unsigned&nbsp;char&nbsp;xe,&nbsp;unsigned&nbsp;char&nbsp;ye,&nbsp;unsigned&nbsp;char&nbsp;bmp_img[])<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;s&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;x_pos&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;y_pos&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(y_pos&nbsp;=&nbsp;yb;&nbsp;y_pos&nbsp;&lt;=&nbsp;ye;&nbsp;y_pos++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(xb,&nbsp;y_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(x_pos&nbsp;=&nbsp;xb;&nbsp;x_pos&nbsp;&lt;&nbsp;xe;&nbsp;x_pos++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(bmp_img[s++],&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> void&nbsp;OLED_print_char(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;ch)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;chr&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;chr&nbsp;=&nbsp;(ch&nbsp;-&nbsp;32);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(x_pos&nbsp;&gt;&nbsp;(x_max&nbsp;-&nbsp;6))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_pos&nbsp;=&nbsp;0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y_pos++;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(x_pos,&nbsp;y_pos);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;for(s&nbsp;=&nbsp;0x00;&nbsp;s&nbsp;&lt;&nbsp;0x06;&nbsp;s++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(font_regular[chr][s],&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;OLED_print_string(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;char&nbsp;*ch)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;chr&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;j&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(ch[j]&nbsp;!=&nbsp;'\\0')<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chr&nbsp;=&nbsp;(ch[j]&nbsp;-&nbsp;32);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(x_pos&nbsp;&gt;&nbsp;(x_max&nbsp;-&nbsp;0x06))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_pos&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y_pos++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(x_pos,&nbsp;y_pos);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0x00;&nbsp;i&nbsp;&lt;&nbsp;0x06;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_write(font_regular[chr][i],&nbsp;DAT);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_pos&nbsp;+=&nbsp;6;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> void&nbsp;OLED_print_chr(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ch&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,&nbsp;'-');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;-value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,'&nbsp;');<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&gt;&nbsp;99)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;999))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;9)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;99))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;0)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;9))<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;OLED_print_int(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;signed&nbsp;long&nbsp;value)<br> {&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ch&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,&nbsp;'-');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;-value;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,'&nbsp;');<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(value&nbsp;&gt;&nbsp;9999)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;\/&nbsp;10000);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;10000)\/&nbsp;1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;999)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;9999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;10000)\/&nbsp;1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;99)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;&nbsp;9)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;=&nbsp;99))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos&nbsp;,&nbsp;32);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;OLED_print_decimal(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;unsigned&nbsp;long&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ch&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,&nbsp;'.');<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;\/&nbsp;1000);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;6),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(points&nbsp;&gt;&nbsp;1)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;1000)&nbsp;\/&nbsp;100);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(points&nbsp;&gt;&nbsp;2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;((value&nbsp;%&nbsp;100)&nbsp;\/&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(points&nbsp;&gt;&nbsp;3)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;=&nbsp;(value&nbsp;%&nbsp;10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos&nbsp;,&nbsp;(48&nbsp;+&nbsp;ch));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> void&nbsp;OLED_print_float(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;float&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;points)&nbsp;<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;tmp&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_print_int(x_pos,&nbsp;y_pos,&nbsp;tmp);<br> &nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;((value&nbsp;-&nbsp;tmp)&nbsp;*&nbsp;10000);<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;-tmp;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&gt;=&nbsp;9999)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;99999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_decimal((x_pos&nbsp;+&nbsp;36),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;999)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;9999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_decimal((x_pos&nbsp;+&nbsp;30),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;99)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;999))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_decimal((x_pos&nbsp;+&nbsp;24),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if((value&nbsp;&gt;=&nbsp;9)&nbsp;&amp;&amp;&nbsp;(value&nbsp;&lt;&nbsp;99))<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_decimal((x_pos&nbsp;+&nbsp;18),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(value&nbsp;&lt;&nbsp;9)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_decimal((x_pos&nbsp;+&nbsp;12),&nbsp;y_pos,&nbsp;tmp,&nbsp;points);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value)&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,&nbsp;'-');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_char(x_pos,&nbsp;y_pos,&nbsp;'&nbsp;');<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;Draw_Pixel(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos,&nbsp;short&nbsp;colour)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;page&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;bit_pos&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;page&nbsp;=&nbsp;(y_pos&nbsp;\/&nbsp;y_max);<br> &nbsp;&nbsp;&nbsp;&nbsp;bit_pos&nbsp;=&nbsp;(y_pos&nbsp;-&nbsp;(page&nbsp;*&nbsp;y_max));<br> &nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;buffer[((page&nbsp;*&nbsp;x_max)&nbsp;+&nbsp;x_pos)];<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if((colour&nbsp;&amp;&nbsp;0x01)&nbsp;!=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;(1&nbsp;&lt;&lt;&nbsp;bit_pos);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&amp;=&nbsp;(~(1&nbsp;&lt;&lt;&nbsp;bit_pos));<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;buffer[((page&nbsp;*&nbsp;x_max)&nbsp;+&nbsp;x_pos)]&nbsp;=&nbsp;value;<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_gotoxy(x_pos,&nbsp;page);<br> &nbsp;&nbsp;&nbsp;&nbsp;OLED_write(value,&nbsp;DAT);<br> }<br> &nbsp;<br> void&nbsp;Draw_Line(signed&nbsp;long&nbsp;x1,&nbsp;signed&nbsp;long&nbsp;y1,&nbsp;signed&nbsp;long&nbsp;x2,&nbsp;signed&nbsp;long&nbsp;y2,&nbsp;short&nbsp;colour)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;dx&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;dy&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;stepx&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;stepy&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;fraction&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;=&nbsp;(y2&nbsp;-&nbsp;y1);<br> &nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;=&nbsp;(x2&nbsp;-&nbsp;x1);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dy&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;=&nbsp;-dy;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stepy--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stepy&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dx&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;=&nbsp;-dx;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stepx--;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stepx&nbsp;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;&lt;&lt;=&nbsp;1;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x1),&nbsp;((unsigned&nbsp;char)y1),&nbsp;colour);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(dx&nbsp;&gt;&nbsp;dy)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;=&nbsp;(dy&nbsp;-&nbsp;(dx&nbsp;&gt;&gt;&nbsp;1));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(x1&nbsp;!=&nbsp;x2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fraction&nbsp;&gt;=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y1&nbsp;+=&nbsp;stepy;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;-=&nbsp;dx;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x1&nbsp;+=&nbsp;stepx;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;+=&nbsp;dy;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x1),&nbsp;((unsigned&nbsp;char)y1),&nbsp;colour);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;=&nbsp;(dx&nbsp;-&nbsp;(dy&nbsp;&gt;&gt;&nbsp;1));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(y1&nbsp;!=&nbsp;y2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(fraction&nbsp;&gt;=&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x1&nbsp;+=&nbsp;stepx;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;-=&nbsp;dy;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y1&nbsp;+=&nbsp;stepy;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fraction&nbsp;+=&nbsp;dx;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x1),&nbsp;((unsigned&nbsp;char)y1),&nbsp;colour);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;Draw_Rectangle(signed&nbsp;long&nbsp;x1,&nbsp;signed&nbsp;long&nbsp;y1,&nbsp;signed&nbsp;long&nbsp;x2,&nbsp;signed&nbsp;long&nbsp;y2,&nbsp;short&nbsp;fill,&nbsp;short&nbsp;colour,&nbsp;short&nbsp;type)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;xmin&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;xmax&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ymin&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;ymax&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fill&nbsp;==&nbsp;ON)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(x1&nbsp;&lt;&nbsp;x2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmin&nbsp;=&nbsp;x1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmax&nbsp;=&nbsp;x2;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmin&nbsp;=&nbsp;x2;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmax&nbsp;=&nbsp;x1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(y1&nbsp;&lt;&nbsp;y2)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ymin&nbsp;=&nbsp;y1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ymax&nbsp;=&nbsp;y2;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ymin&nbsp;=&nbsp;y2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ymax&nbsp;=&nbsp;y1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;ymin;&nbsp;i&nbsp;&lt;=&nbsp;ymax;&nbsp;++i)&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line(xmin,&nbsp;i,&nbsp;xmax,&nbsp;i,&nbsp;colour);&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line(x1,&nbsp;y1,&nbsp;x2,&nbsp;y1,&nbsp;colour);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line(x1,&nbsp;y2,&nbsp;x2,&nbsp;y2,&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line(x1,&nbsp;y1,&nbsp;x1,&nbsp;y2,&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line(x2,&nbsp;y1,&nbsp;x2,&nbsp;y2,&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(type&nbsp;!=&nbsp;SQUARE)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x1),&nbsp;((unsigned&nbsp;char)y1),&nbsp;~colour);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x1),&nbsp;((unsigned&nbsp;char)y2),&nbsp;~colour);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x2),&nbsp;((unsigned&nbsp;char)y1),&nbsp;~colour);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel(((unsigned&nbsp;char)x2),&nbsp;((unsigned&nbsp;char)y2),&nbsp;~colour);&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;Draw_Circle(signed&nbsp;long&nbsp;xc,&nbsp;signed&nbsp;long&nbsp;yc,&nbsp;signed&nbsp;long&nbsp;radius,&nbsp;short&nbsp;fill,&nbsp;short&nbsp;colour)&nbsp;<br> {<br> &nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;a&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;b&nbsp;=&nbsp;0x0000;<br> &nbsp;&nbsp;&nbsp;signed&nbsp;long&nbsp;P&nbsp;=&nbsp;0x0000;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;radius;<br> &nbsp;&nbsp;&nbsp;P&nbsp;=&nbsp;(1&nbsp;-&nbsp;b);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;do<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fill&nbsp;==&nbsp;ON)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line((xc&nbsp;-&nbsp;a),&nbsp;(yc&nbsp;+&nbsp;b),&nbsp;(xc&nbsp;+&nbsp;a),&nbsp;(yc&nbsp;+&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line((xc&nbsp;-&nbsp;a),&nbsp;(yc&nbsp;-&nbsp;b),&nbsp;(xc&nbsp;+&nbsp;a),&nbsp;(yc&nbsp;-&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line((xc&nbsp;-&nbsp;b),&nbsp;(yc&nbsp;+&nbsp;a),&nbsp;(xc&nbsp;+&nbsp;b),&nbsp;(yc&nbsp;+&nbsp;a),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Line((xc&nbsp;-&nbsp;b),&nbsp;(yc&nbsp;-&nbsp;a),&nbsp;(xc&nbsp;+&nbsp;b),&nbsp;(yc&nbsp;-&nbsp;a),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;+&nbsp;a),&nbsp;(yc&nbsp;+&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;+&nbsp;b),&nbsp;(yc&nbsp;+&nbsp;a),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;-&nbsp;a),&nbsp;(yc&nbsp;+&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;-&nbsp;b),&nbsp;(yc&nbsp;+&nbsp;a),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;+&nbsp;b),&nbsp;(yc&nbsp;-&nbsp;a),&nbsp;colour);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;+&nbsp;a),&nbsp;(yc&nbsp;-&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;-&nbsp;a),&nbsp;(yc&nbsp;-&nbsp;b),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Draw_Pixel((xc&nbsp;-&nbsp;b),&nbsp;(yc&nbsp;-&nbsp;a),&nbsp;colour);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(P&nbsp;&lt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P&nbsp;+=&nbsp;(3&nbsp;+&nbsp;(2&nbsp;*&nbsp;a++));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P&nbsp;+=&nbsp;(5&nbsp;+&nbsp;(2&nbsp;*&nbsp;((a++)&nbsp;-&nbsp;(b--))));<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}while(a&nbsp;&lt;=&nbsp;b);<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"DHT11.c\"<br> #include&nbsp;\"SSD1306.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;state&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;OLED_print_string(24,&nbsp;0,&nbsp;\"Temp\/Deg&nbsp;C\");&nbsp;&nbsp;<br> &nbsp;&nbsp;OLED_print_string(24,&nbsp;4,&nbsp;\"Rel.Hum&nbsp;\/%\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;=&nbsp;DHT11_get_data();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(state)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;1:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;2:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_string(56,&nbsp;2,&nbsp;\"&nbsp;&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_string(56,&nbsp;6,&nbsp;\"&nbsp;&nbsp;&nbsp;\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;3:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_string(56,&nbsp;2,&nbsp;\"--\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_string(56,&nbsp;6,&nbsp;\"--\");<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_chr(55,&nbsp;2,&nbsp;values[2]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OLED_print_chr(55,&nbsp;6,&nbsp;values[0]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(1000);<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_no_output,&nbsp;MCLK_out_P54);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;DHT11_init();<br> &nbsp;&nbsp;OLED_init();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"605\" height=\"318\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-SPI.png\" alt=\"\" class=\"wp-image-14950\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-SPI.png 605w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-SPI-580x305.png 580w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">DHT11\u2019s logical one and zero timing diagrams below show that it too uses time-slotting mechanism just like DS18B20. However, its way of communication or protocol is not same as that of DS18B20\u2019s and codes are not compatible amongst each other. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"212\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-116.png\" alt=\"\" class=\"wp-image-14951\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-116.png 940w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-116-580x131.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-116-768x173.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">From the above timing diagrams, it is clear that the difference between these two signals is the high time. Thus, after sensing low input we should wait for about 30\u00b5s before trying to determine if the sensor sent a <em>zero<\/em> time-slot or a <em>one<\/em> time-slot. This is so because if it sent a logical zero then after 30\u00b5s of delay, there should be no floating or logic high signal in DHT11\u2019s communication pin. If it is otherwise then a logical <em>one<\/em> time slot should be expected. This is what the following code does. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> unsigned&nbsp;char&nbsp;DHT11_get_byte(void)<br> {<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x08;<br> &nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;value&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)&nbsp;<br> &nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(DHT11_pin_IN&nbsp;==&nbsp;LOW);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;large_delay_TMR_0(30);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(DHT11_pin_IN&nbsp;==&nbsp;HIGH)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;|=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(DHT11_pin_IN&nbsp;==&nbsp;HIGH);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;<br> &nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;return&nbsp;value;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, it is necessary to mention\nthat instead of traditional software-based delay library that relies on wasting\nCPU cycles, hardware-based delay library has been used in this code. This library\n(<em>tmr_delay.h<\/em>) generates more accurate time delays. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s see how SSD1306 OLED display can be bit-banged. First, notice its timing diagram.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"221\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-117.png\" alt=\"\" class=\"wp-image-14952\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-117.png 939w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-117-580x137.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-117-768x181.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The timing diagram suggests:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SPI clock (SCLK) is held low in\nidle mode.<\/li><li>SPI data (SDIN) is shifted or\nclocked during the rising edge or low-to-high transition of SPI clock.<\/li><li>SPI chip\/slave select (CS)\nshould be held low during data transfer only and for the rest of the times, it\nshould be held high. <\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">All these points suggest us that it is a Mode 0 SPI communication and we can craft a code using these data as shown below. It is a mere timing diagram to code translation. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;OLED_write(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;type)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;s&nbsp;=&nbsp;0x08;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_CS_PIN_LOW;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(type)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;DAT:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_DC_PIN_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_DC_PIN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(s&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((value&nbsp;&amp;&nbsp;0x80)&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SDA_PIN_HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SDA_PIN_LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_HIGH;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSD1306_SCK_PIN_LOW;&nbsp;&nbsp;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SSD1306_CS_PIN_HIGH;&nbsp;<br> }&nbsp; <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"467\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-118.png\" alt=\"\" class=\"wp-image-14953\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-118.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-118-580x294.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-118-768x389.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - One Wire and Software SPI Example - Interfacing SSD1306 and DHT11 with STC Micro\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/IP4_gTHhLRI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h2 class=\"wp-block-heading\">Software I2C and Software UART<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After trying to grasp the past software-based communication techniques, I think reader should now have some idea of the tricks employed to do the tasks.  At this final stage, we are left with software I2C and software UART. The tricks behind software I2C are similar to our past encounters with one wire communications and TM1637. However, software UART implementation is a bit complicated.  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"794\" height=\"569\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-119.png\" alt=\"\" class=\"wp-image-14954\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-119.png 794w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-119-580x416.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-119-768x550.png 768w\" sizes=\"auto, (max-width: 794px) 100vw, 794px\" \/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The demo for this example is a simple multi-UART chatting. One UART is hardware-based while the other is based on software. The chatting between the UARTs is displayed on I2C-based serial LCD. This LCD is driven using I2C-based PCF8574 GPIO expander. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">SW_I2C.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> define SDA_DIR_OUT()&nbsp;&nbsp;&nbsp;P10_push_pull_mode<br> #define&nbsp;SDA_DIR_IN()&nbsp;&nbsp;&nbsp;&nbsp;P10_input_mode<br> &nbsp;<br> #define&nbsp;SCL_DIR_OUT()&nbsp;&nbsp;&nbsp;P11_push_pull_mode<br> #define&nbsp;SCL_DIR_IN()&nbsp;&nbsp;&nbsp;&nbsp;P11_input_mode<br> &nbsp;<br> #define&nbsp;SDA_HIGH()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_high<br> #define&nbsp;SDA_LOW()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_low<br> &nbsp;<br> #define&nbsp;SCL_HIGH()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P11_high<br> #define&nbsp;SCL_LOW()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P11_low<br> &nbsp;<br> #define&nbsp;SDA_IN()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P10_get_input<br> &nbsp;<br> #define&nbsp;I2C_ACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFF<br> #define&nbsp;I2C_NACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x00<br> &nbsp;<br> #define&nbsp;I2C_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1000<br> &nbsp;<br> void&nbsp;SW_I2C_init(void);<br> void&nbsp;SW_I2C_start(void);<br> void&nbsp;SW_I2C_stop(void);<br> unsigned&nbsp;char&nbsp;SW_I2C_read(unsigned&nbsp;char&nbsp;ack);<br> void&nbsp;SW_I2C_write(unsigned&nbsp;char&nbsp;value);<br> void&nbsp;SW_I2C_ACK_NACK(unsigned&nbsp;char&nbsp;mode);<br> unsigned&nbsp;char&nbsp;SW_I2C_wait_ACK(void); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">SW_I2C.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"SW_I2C.h\"<br> &nbsp;<br> void&nbsp;SW_I2C_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_OUT();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_DIR_OUT();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> }<br> &nbsp;<br> void&nbsp;SW_I2C_start(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_OUT();<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(40);<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(40);<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> }<br> &nbsp;<br> void&nbsp;SW_I2C_stop(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_OUT();<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(40);<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(40);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;SW_I2C_read(unsigned&nbsp;char&nbsp;ack)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;8;<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;j&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_IN();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(SDA_IN()&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(ack)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;I2C_ACK:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_ACK_NACK(I2C_ACK);;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_ACK_NACK(I2C_NACK);;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;j;<br> }<br> &nbsp;<br> void&nbsp;SW_I2C_write(unsigned&nbsp;char&nbsp;value)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i&nbsp;=&nbsp;8;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_OUT();<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(i&nbsp;&gt;&nbsp;0)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(((value&nbsp;&amp;&nbsp;0x80)&nbsp;&gt;&gt;&nbsp;7)&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;&lt;&lt;=&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;SW_I2C_ACK_NACK(unsigned&nbsp;char&nbsp;mode)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_OUT();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;switch(mode)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;I2C_ACK:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(20);<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;SW_I2C_wait_ACK(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;signed&nbsp;int&nbsp;timeout&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_DIR_IN();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SDA_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(10);<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_HIGH();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_us(10);<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;while(SDA_IN()&nbsp;!=&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timeout++;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(timeout&nbsp;&gt;&nbsp;I2C_timeout)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_stop();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;};<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SCL_LOW();<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPCF8574.h\n\n\n\n<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"SW_I2C.c\"<br> &nbsp;<br> #define&nbsp;PCF8574_address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x4E<br> &nbsp;<br> #define&nbsp;PCF8574_write_cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PCF8574_address<br> #define&nbsp;PCF8574_read_cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PCF8574_address&nbsp;|&nbsp;1)<br> &nbsp;<br> void&nbsp;PCF8574_init(void);<br> unsigned&nbsp;char&nbsp;PCF8574_read(void);<br> void&nbsp;PCF8574_write(unsigned&nbsp;char&nbsp;data_byte); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">PCF8574.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"PCF8574.h\"<br> &nbsp;<br> void&nbsp;PCF8574_init(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_init();<br> &nbsp;&nbsp;&nbsp;&nbsp;delay_ms(10);<br> }<br> &nbsp;<br> unsigned&nbsp;char&nbsp;PCF8574_read(void)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;port_byte&nbsp;=&nbsp;0;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_write(PCF8574_read_cmd);<br> &nbsp;&nbsp;&nbsp;&nbsp;port_byte&nbsp;=&nbsp;SW_I2C_read(I2C_NACK);<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_stop();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;port_byte;<br> }<br> &nbsp;<br> void&nbsp;PCF8574_write(unsigned&nbsp;char&nbsp;data_byte)<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_start();<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_write(PCF8574_write_cmd);<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_ACK_NACK(I2C_ACK);<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_write(data_byte);<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_ACK_NACK(I2C_ACK);<br> &nbsp;&nbsp;&nbsp;&nbsp;SW_I2C_stop();<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">LCD_2_Wire.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"PCF8574.c\"<br> &nbsp;<br> #define&nbsp;clear_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;goto_home&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;cursor_direction_inc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_direction_dec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x04&nbsp;|&nbsp;0x00)<br> #define&nbsp;display_shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x01)<br> #define&nbsp;display_no_shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x04&nbsp;|&nbsp;0x00)<br> &nbsp;<br> #define&nbsp;display_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x04)<br> #define&nbsp;display_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x02)<br> #define&nbsp;cursor_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x00)<br> #define&nbsp;blink_on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x08&nbsp;|&nbsp;0x01)<br> #define&nbsp;blink_off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x08&nbsp;|&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> #define&nbsp;_8_pin_interface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x10)<br> #define&nbsp;_4_pin_interface&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> #define&nbsp;_2_row_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x08)<br> #define&nbsp;_1_row_display&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> #define&nbsp;_5x10_dots&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x40)<br> #define&nbsp;_5x7_dots&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0x20&nbsp;|&nbsp;0x00)<br> &nbsp;<br> #define&nbsp;BL_ON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br> #define&nbsp;BL_OFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;0<br> &nbsp;<br> #define&nbsp;dly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<br> &nbsp;<br> #define&nbsp;DAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1<br> #define&nbsp;CMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;0<br> &nbsp;<br> void&nbsp;LCD_init(void);<br> void&nbsp;LCD_toggle_EN(void);<br> void&nbsp;LCD_send(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;mode);&nbsp;<br> void&nbsp;LCD_4bit_send(unsigned&nbsp;char&nbsp;lcd_data);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> void&nbsp;LCD_putstr(char&nbsp;*lcd_string);<br> void&nbsp;LCD_putchar(char&nbsp;char_data);<br> void&nbsp;LCD_clear_home(void);<br> void&nbsp;LCD_goto(unsigned&nbsp;char&nbsp;x_pos,&nbsp;unsigned&nbsp;char&nbsp;y_pos); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">LCD_2_Wire.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"LCD_2_Wire.h\"<br> &nbsp;<br> static&nbsp;unsigned&nbsp;char&nbsp;bl_state;<br> static&nbsp;unsigned&nbsp;char&nbsp;data_value;<br> &nbsp;<br> void&nbsp;LCD_init(void)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;PCF8574_init();<br> &nbsp;&nbsp;delay_ms(10);<br> &nbsp;<br> &nbsp;&nbsp;bl_state&nbsp;=&nbsp;BL_ON;<br> &nbsp;&nbsp;data_value&nbsp;=&nbsp;0x04;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;<br> &nbsp;&nbsp;delay_ms(10);<br> &nbsp;<br> &nbsp;&nbsp;LCD_send(0x33,&nbsp;CMD);<br> &nbsp;&nbsp;LCD_send(0x32,&nbsp;CMD);<br> &nbsp;<br> &nbsp;&nbsp;LCD_send((_4_pin_interface&nbsp;|&nbsp;_2_row_display&nbsp;|&nbsp;_5x7_dots),&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_send((display_on&nbsp;|&nbsp;cursor_off&nbsp;|&nbsp;blink_off),&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_send((clear_display),&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_send((cursor_direction_inc&nbsp;|&nbsp;display_no_shift),&nbsp;CMD);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> }&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;LCD_toggle_EN(void)<br> {<br> &nbsp;&nbsp;data_value&nbsp;|=&nbsp;0x04;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;&nbsp;delay_ms(1);<br> &nbsp;&nbsp;data_value&nbsp;&amp;=&nbsp;0xF9;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;&nbsp;delay_ms(1);<br> }<br> &nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;LCD_send(unsigned&nbsp;char&nbsp;value,&nbsp;unsigned&nbsp;char&nbsp;mode)<br> {<br> &nbsp;&nbsp;switch(mode)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;CMD:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_value&nbsp;&amp;=&nbsp;0xF4;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;DAT:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_value&nbsp;|=&nbsp;0x01;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;switch(bl_state)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;BL_ON:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_value&nbsp;|=&nbsp;0x08;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;BL_OFF:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_value&nbsp;&amp;=&nbsp;0xF7;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;&nbsp;LCD_4bit_send(value);<br> &nbsp;&nbsp;delay_ms(1);<br> }<br> &nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;LCD_4bit_send(unsigned&nbsp;char&nbsp;lcd_data)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp&nbsp;=&nbsp;0x00;<br> &nbsp;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(lcd_data&nbsp;&amp;&nbsp;0xF0);<br> &nbsp;&nbsp;data_value&nbsp;&amp;=&nbsp;0x0F;<br> &nbsp;&nbsp;data_value&nbsp;|=&nbsp;temp;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;&nbsp;LCD_toggle_EN();<br> &nbsp;<br> &nbsp;&nbsp;temp&nbsp;=&nbsp;(lcd_data&nbsp;&amp;&nbsp;0x0F);<br> &nbsp;&nbsp;temp&nbsp;&lt;&lt;=&nbsp;0x04;<br> &nbsp;&nbsp;data_value&nbsp;&amp;=&nbsp;0x0F;<br> &nbsp;&nbsp;data_value&nbsp;|=&nbsp;temp;<br> &nbsp;&nbsp;PCF8574_write(data_value);<br> &nbsp;&nbsp;LCD_toggle_EN();<br> }&nbsp;&nbsp;<br> &nbsp;<br> void&nbsp;LCD_putstr(char&nbsp;*lcd_string)<br> {<br> &nbsp;&nbsp;do<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(*lcd_string++);<br> &nbsp;&nbsp;}while(*lcd_string&nbsp;!=&nbsp;'\\0')&nbsp;;<br> }<br> &nbsp;<br> void&nbsp;LCD_putchar(char&nbsp;char_data)<br> {<br> &nbsp;&nbsp;if((char_data&nbsp;&gt;=&nbsp;0x20)&nbsp;&amp;&amp;&nbsp;(char_data&nbsp;&lt;=&nbsp;0x7F))<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send(char_data,&nbsp;DAT);<br> &nbsp;&nbsp;}<br> }<br> &nbsp;<br> void&nbsp;LCD_clear_home(void)<br> {<br> &nbsp;&nbsp;LCD_send(clear_display,&nbsp;CMD);<br> &nbsp;&nbsp;LCD_send(goto_home,&nbsp;CMD);<br> }<br> &nbsp;<br> void&nbsp;LCD_goto(unsigned&nbsp;char&nbsp;x_pos,unsigned&nbsp;char&nbsp;y_pos)<br> {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;if(y_pos&nbsp;==&nbsp;0)&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((0x80&nbsp;|&nbsp;x_pos),&nbsp;CMD);<br> &nbsp;&nbsp;}<br> &nbsp;&nbsp;else&nbsp;<br> &nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;LCD_send((0x80&nbsp;|&nbsp;0x40&nbsp;|&nbsp;x_pos),&nbsp;CMD);&nbsp;<br> &nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">soft_UART.h<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #define&nbsp;tmr_max_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xFFFF<br> &nbsp;<br> \/\/sysclk<br> #define&nbsp;sysclk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000<br> &nbsp;<br> \/\/baud&nbsp;rate<br> #define&nbsp;baud_rate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9600<br> &nbsp;<br> \/\/T_value<br> #define&nbsp;_1T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;_12T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0C<br> &nbsp;<br> #define&nbsp;tmr_load_value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tmr_max_cnt&nbsp;-&nbsp;(sysclk&nbsp;\/&nbsp;3&nbsp;\/&nbsp;baud_rate&nbsp;\/&nbsp;_1T))<br> &nbsp;<br> sbit&nbsp;RXD_pin&nbsp;=&nbsp;P1^6;<br> sbit&nbsp;TXD_pin&nbsp;=&nbsp;P1^7;<br> &nbsp;<br> unsigned&nbsp;char&nbsp;TXing&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RXing&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;TX_Bit&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_Bit&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;TX_CNT&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_CNT&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;TX_Data&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_Data&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;TX_done&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_done&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;TX_Buffer&nbsp;=&nbsp;0x00;<br> unsigned&nbsp;char&nbsp;RX_Buffer&nbsp;=&nbsp;0x00;<br> &nbsp;<br> void&nbsp;soft_UART_init(void); <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">soft_UART.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"soft_UART.h\"<br> &nbsp;<br> void&nbsp;soft_UART_init(void)<br> {<br> &nbsp;&nbsp;TXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;RXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;TX_CNT&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;TX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;RX_done&nbsp;=&nbsp;FALSE;<br> &nbsp;<br> &nbsp;&nbsp;TMR2_setup(TMR2_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR2_clk_prescalar_1T);<br> &nbsp;<br> &nbsp;&nbsp;TMR2_load_counter_16(tmr_load_value);<br> &nbsp;<br> &nbsp;&nbsp;TMR2_start;<br> &nbsp;<br> &nbsp;&nbsp;_enable_TMR_2_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> }<br> &nbsp;<br> void&nbsp;TMR_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;12<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(RXing&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--RX_CNT&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x03;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--RX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Buffer&nbsp;=&nbsp;RX_Data;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Data&nbsp;&gt;&gt;=&nbsp;0x01;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(RXD_pin&nbsp;==&nbsp;HIGH)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Data&nbsp;|=&nbsp;0x80;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(RXD_pin&nbsp;==&nbsp;FALSE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RXing&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x04;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Bit&nbsp;=&nbsp;0x09;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(--TX_CNT&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_CNT&nbsp;=&nbsp;0x03;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TXing&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Data&nbsp;=&nbsp;TX_Buffer;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Bit&nbsp;=&nbsp;0x09;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Data&nbsp;&gt;&gt;=&nbsp;0x01;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--TX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;CY;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">main.c<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\"> #include&nbsp;\"STC8xxx.h\"<br> #include&nbsp;\"BSP.h\"<br> #include&nbsp;\"LCD_2_Wire.c\"<br> #include&nbsp;\"soft_UART.c\"<br> &nbsp;<br> void&nbsp;setup(void);<br> &nbsp;<br> void&nbsp;main(void)<br> {<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;msg1[10]&nbsp;=&nbsp;{\"0123456789\"};<br> &nbsp;&nbsp;unsigned&nbsp;char&nbsp;msg2[10]&nbsp;=&nbsp;{\"!@#$%^&amp;*()\"};<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;char&nbsp;i&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;char&nbsp;rcv_s&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;char&nbsp;rcv_3&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;setup();<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"TXDs:&nbsp;\");<br> &nbsp;&nbsp;LCD_goto(10,&nbsp;0);<br> &nbsp;&nbsp;LCD_putstr(\"TXD3:&nbsp;\");<br> &nbsp;<br> &nbsp;&nbsp;LCD_goto(0,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"RXDs:&nbsp;\");<br> &nbsp;&nbsp;LCD_goto(10,&nbsp;1);<br> &nbsp;&nbsp;LCD_putstr(\"RXD3:&nbsp;\");<br> &nbsp;<br> &nbsp;&nbsp;while(1)<br> &nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;for(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10;&nbsp;i++)<br> &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TX_done&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_done&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Buffer&nbsp;=&nbsp;msg1[i];<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXing&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART3_write_buffer(msg2[i]);&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(5,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(msg1[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(15,&nbsp;0);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(msg2[i]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(RX_done&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_done&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rcv_s&nbsp;=&nbsp;RX_Buffer;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rcv_3&nbsp;=&nbsp;UART3_read_buffer();<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(5,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(rcv_s);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_goto(15,&nbsp;1);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LCD_putchar(rcv_3);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay_ms(900);<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;};<br> }<br> &nbsp;<br> void&nbsp;setup(void)<br> {<br> &nbsp;&nbsp;CLK_set_sys_clk(IRC_24M,&nbsp;2,&nbsp;MCLK_SYSCLK_div_1,&nbsp;MCLK_out_P54);<br> &nbsp;<br> &nbsp;&nbsp;UART3_pin_option(0x00);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;UART3_init(9600,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART3_baud_source_TMR3,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART3_timer_1T,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000);<br> &nbsp;&nbsp;<br> &nbsp;&nbsp;LCD_init();<br> &nbsp;&nbsp;LCD_clear_home();<br> &nbsp;&nbsp;soft_UART_init();<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Schematic<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"671\" height=\"336\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-UART-1.png\" alt=\"\" class=\"wp-image-14955\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-UART-1.png 671w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/Schematic-SW-UART-1-580x290.png 580w\" sizes=\"auto, (max-width: 671px) 100vw, 671px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Explanation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To use software UART efficiently, the following definitions have to defined properly. Unlike the past software communications that we have seen so far, software UART requires the use of a timer its overflow interrupt. Hardware UARTs also need timers for baud rate generation but here in software UART, a timer has a different but somewhat similar use. UART, itself, is asynchronous in nature and so its data timings must be as accurate as possible in order to reduce data loss, error and corruption. This fact becomes a more serious matter when it comes to software UART because not only we are dealing with an asynchronous communication but we will also be dealing it with software solution instead of actual hardware. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> \/\/sysclk<br> #define&nbsp;sysclk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12000000<br> &nbsp;<br> \/\/baud&nbsp;rate<br> #define&nbsp;baud_rate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9600<br> &nbsp;<br> \/\/T_value<br> #define&nbsp;_1T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01<br> #define&nbsp;_12T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x0C<br> &nbsp;<br> #define&nbsp;tmr_load_value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tmr_max_cnt&nbsp;-&nbsp;(sysclk&nbsp;\/&nbsp;3&nbsp;\/&nbsp;baud_rate&nbsp;\/&nbsp;_1T))<br> &nbsp;<br> sbit&nbsp;RXD_pin&nbsp;=&nbsp;P1^6;<br> sbit&nbsp;TXD_pin&nbsp;=&nbsp;P1^7; <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Initialization of software UART is pretty easy. There are lot of variables that need to be initialized with some defaults and the timer to be used should be initialized and started along with the enabling of the interrupts. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;soft_UART_init(void)<br> {<br> &nbsp;&nbsp;TXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;RXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;TX_CNT&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x00;<br> &nbsp;&nbsp;TX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;RX_done&nbsp;=&nbsp;FALSE;<br> &nbsp;<br> &nbsp;&nbsp;TMR2_setup(TMR2_sysclk,&nbsp;\\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TMR2_clk_prescalar_1T);<br> &nbsp;<br> &nbsp;&nbsp;TMR2_load_counter_16(tmr_load_value);<br> &nbsp;<br> &nbsp;&nbsp;TMR2_start;<br> &nbsp;<br> &nbsp;&nbsp;_enable_TMR_2_interrupt;<br> &nbsp;&nbsp;_enable_global_interrupt;<br> } <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the timer interrupt, data transmission and reception operations are done independently of the main loop. The whole operation is done in a similar process as one would expect with a real hardware UART. There are flags and buffers for both TX and RX operations and the timer\u2019s interrupt is used to simulate baud rate as perfectly as possible. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> void&nbsp;TMR_2_ISR(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> interrupt&nbsp;12<br> {<br> &nbsp;&nbsp;&nbsp;&nbsp;if(RXing&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--RX_CNT&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x03;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--RX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Buffer&nbsp;=&nbsp;RX_Data;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Data&nbsp;&gt;&gt;=&nbsp;0x01;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(RXD_pin&nbsp;==&nbsp;HIGH)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Data&nbsp;|=&nbsp;0x80;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(RXD_pin&nbsp;==&nbsp;FALSE)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RXing&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_CNT&nbsp;=&nbsp;0x04;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RX_Bit&nbsp;=&nbsp;0x09;<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;if(--TX_CNT&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_CNT&nbsp;=&nbsp;0x03;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TXing&nbsp;==&nbsp;TRUE)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(TX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;LOW;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Data&nbsp;=&nbsp;TX_Buffer;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Bit&nbsp;=&nbsp;0x09;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_Data&nbsp;&gt;&gt;=&nbsp;0x01;<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(--TX_Bit&nbsp;==&nbsp;0x00)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;HIGH;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXing&nbsp;=&nbsp;FALSE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TX_done&nbsp;=&nbsp;TRUE;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TXD_pin&nbsp;=&nbsp;CY;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> } <\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Demo<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"672\" src=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-120.png\" alt=\"\" class=\"wp-image-14956\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-120.png 922w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-120-580x423.png 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2021\/12\/image-120-768x560.png 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"STC8A8K64S4A12 - Software UART and Software I2C Example\" width=\"860\" height=\"484\" src=\"https:\/\/www.youtube.com\/embed\/7AUjfIpg9a0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<!--nextpage-->\n\n\n\n<h3 class=\"wp-block-heading\">Epilogue <\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As with any new\nmicrocontroller, I enjoyed developing stuffs for STC micros too. Every hardware\nperipheral was a new experience for me, especially the PCA module. The reasons\nwhy I love exploring 8051 core-based MCUs are their relative ease of usage,\ncompatibility and similarity. STC microcontrollers were no exceptions. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There were times during\nthe forging of this work, I did face some odd issues while cherished at some\nother points and here in the end I would like share some of them.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>While trying out multichannel\nADCs, I did notice significant interference amongst channels but later I fixed\nit by changing ADC clock speed.<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>The analogue frontend of STC\nmicros need special attention when designing PCBs because things may not look\ngood if things as stated in the first point happen.<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>The more the resolution of an\nADC, the more noise it is likely to pick and so external Op-Amp-based buffering\nand filtering should be considered. Good external reference voltage source\nshould be used for good accuracy. <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>As with any 8051-based MCU,\nmemory model is a very important stuff and should be considered in some cases,\nespecially when dealing with pointers and large arrays. The following link\ndescribes memory model in details specifically for Keil C51 C compiler: <a href=\"https:\/\/www.keil.com\/support\/man\/docs\/c51\/c51_le_memmodels.htm\">https:\/\/www.keil.com\/support\/man\/docs\/c51\/c51_le_memmodels.htm<\/a>.&nbsp; <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>The programmer GUI is a tool\nthat has many optional functions that are really very helpful. I advise\nupdating the GUI as new releases are uploaded. <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Since STC\u2019s portfolio consists\nof wide variety of 8051-based MCUs, it is possible to use the BSP header files\nI coded in this document and slightly modify for other STC MCUs. <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>STC should invest on a\nfree-compiler of its own. In the past, I have criticized many Chinese\nsemiconductor manufacturers for their lack of software support and STC doesn\u2019t\nstand different from the others. The same is true for official development\nboards.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, I would like to state that STC micros are game changers in the market of 8051-based microcontrollers. They are reliable, cheap and in fact widely used in Chinese and Asian markets. Personally, I feel delighted to have introduced them to the non-Chinese world. STC micros are without any doubt good micros for any new design.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PDF of this tutorial can be found <a href=\"https:\/\/drive.google.com\/file\/d\/1nhOzo4Zj1o9BPVcRg3USxDLMUaH0VlgC\/view?usp=sharing\">here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Code Examples and Libraries used in this tutorial can be downloaded from <a href=\"https:\/\/github.com\/sshahryiar\/STC8A8K64S4A12-Tutorial\">here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All demo videos of this tutorial can be found in this <a href=\"https:\/\/youtube.com\/playlist?list=PL-EErZRpDPIWmbv_A1gEZgIDU9Sjo9lZJ\">Youtube playlist.<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Happy coding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Author: Shawon M. Shahryiar<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.facebook.com\/groups\/microarena\">https:\/\/www.facebook.com\/groups\/microarena<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.facebook.com\/MicroArena?ref=hl\"><em>https:\/\/www.facebook.com\/MicroArena<\/em><\/a><em> &nbsp;&nbsp;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>03.12.2021<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>About STC8A8K64S4A12 Microcontroller and its Development Board This is the continuation of my first post on STC 8051 Microcontrollers here. Many Chinese microcontroller manufacturers develop awesome and cheap general-purpose MCUs using the popular 8051 architecture. There are many reasons for that but most importantly the 8051 architecture is a very common one that has been around for quite a long time. Secondly, manufacturing MCUs with 8051 DNA allows manufacturers to focus less on developing their own proprietary core and to give more effort in adding features. Holtek, Nuvoton, STC, etc are a few manufacturers to name.<\/p>\n","protected":false},"author":5,"featured_media":14922,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,1464,1734,1466],"tags":[1722,1748,1733,1747,1745,1746],"class_list":["post-14763","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-lessons","category-featured","category-stc8051","category-tutorials","tag-1722","tag-chinese-microcontroller","tag-stc","tag-stc-microcontroller","tag-stc8051","tag-stc8a8k64s4a12"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/14763","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=14763"}],"version-history":[{"count":44,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/14763\/revisions"}],"predecessor-version":[{"id":15405,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/14763\/revisions\/15405"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/14922"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=14763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=14763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=14763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}