<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: jstivic</title>
    <description>The latest articles on DEV Community by jstivic (@jstivic).</description>
    <link>https://dev.to/jstivic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1077827%2F61edc213-9ee9-42b7-b3d3-039e59a3f87a.png</url>
      <title>DEV Community: jstivic</title>
      <link>https://dev.to/jstivic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jstivic"/>
    <language>en</language>
    <item>
      <title>Microcontroller Programming (8) - Assembler and DDRB</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sun, 07 May 2023 17:24:40 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-9-assembler-and-ddrb-4hk2</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-9-assembler-and-ddrb-4hk2</guid>
      <description>&lt;p&gt;The best way to compare programming languages and what they offer is to program identical functionalities in the languages we know. I must admit that I am extremely concerned about the understanding of the following texts, but I cannot find a better and simpler way of complicated programming. An Arduino programmer does not understand what is behind Arduino functions. An AVR Studio C/C++ programmer does not understand what is behind assembler. An assembler programmer does not understand what is behind...&lt;br&gt;
To understand all these programmers and therefore get to know the AVR architecture of microcontrollers, we must look at it from multiple programming languages. Because of the special characters of the C/C++ language ({ } [ ] &amp;lt; &amp;gt; * -&amp;gt; &amp;amp; | || &amp;amp;&amp;amp; % ~ ^ &amp;lt;&amp;lt; &amp;gt;&amp;gt; # ; : "" '), learning its syntax is repulsive and ugly. After a longer period of writing C/C++ syntax, brackets and special characters will not be a problem. On the contrary, it will be a phenomenal indicator of what starts, where it starts, where it ends, what it does, how it works... Assembler syntax is simpler than C/C++ syntax, and we will get to know it through examples.&lt;br&gt;
In the previous text, the AVR registers were pictorially explained, their location in the address space of the SRAM memory, and their essential purpose. The first register we will get to know will be viewed at the assembler programmer level, and then delve into the understanding of the identical register from the perspective of AVR Studio C/C++ and the Arduino development environment. Therefore, let's forget about other programming languages for a moment and listen to what sounds like: DDRB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZuzntY5s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uppk2qxtf129zk4m4l8d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZuzntY5s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uppk2qxtf129zk4m4l8d.jpg" alt="Image description" width="604" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try to pronounce the register name as a word, your tongue will likely get tangled somewhere between the letters. Try again, but this time like this: "Data Direction Register B." Not only can you say its full name, but you can also understand its purpose: "Register for controlling the data direction of Port B" (input/output). The DDRB register is 1 byte (8-bit) in size and can therefore only control 8 physical pins of the microcontroller (PB0 - PB7). Don't be surprised that almost everything in our microcontroller is 8 bits in size. The ATmega2560 is an 8-bit computer, so its registers are also 8 bits in size. The diagram shows the microcontroller pinout and the pins whose direction is controlled by the DDRB register.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eImd6XtH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25admlkxddvh2ilknlcq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eImd6XtH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25admlkxddvh2ilknlcq.jpg" alt="Image description" width="433" height="303"&gt;&lt;/a&gt;&lt;br&gt;
As the ATmega2560 microcontroller has more than 8 pins, there are multiple DDRx registers. Their names differ only in the last letter, which describes the port: DDRA, DDRB, DDRC, DDRD, DDRE, DDRF, DDRG, DDRH, DDRJ, DDRK, and DDRL. After an AVR microcontroller reset, all of these registers are set to 0x00, and all pins of the microcontroller are inputs. This knowledge provides an important detail for controlling data direction: "If you want it to be an output, make it a logical 1." To configure input and output for the microcontroller, we always access the DDRx registers while following the mentioned rule (0x00 = inputs, 0xFF = outputs).&lt;/p&gt;

&lt;p&gt;The biggest problem with Arduino functions such as pinMode() and all other Arduino functions is that you are limited to one architecture, the Arduino development board, and the Arduino IDE. If you know the DDRB register in the AVR architecture, you don't need to be afraid of the TIRISA register on the PIC or the FIO0DIR register on the ARM. The fact that registers have different names in different architectures and that they are controlled differently is not an insurmountable long-standing problem. A few days of searching through the documentation for another architecture will be enough to adopt new register names and their purposes.&lt;/p&gt;

&lt;p&gt;As the LED on the development board is connected to PB7, the following example shows how an assembler programmer can configure the output using the SBI instruction in a simple way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GOuseeoF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eklki0wt3oenm3sqn6m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GOuseeoF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eklki0wt3oenm3sqn6m.jpg" alt="Image description" width="713" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full name of the SBI instruction is "Set Bit", and it sets a desired register bit to logic "1". Only one instruction is required to set PB7 as the output of the microcontroller. However, the assembler programmer must be aware of an important limitation of the SBI instruction: the maximum address of the IO register that the instruction can handle is DEC 31 or HEX 0x1F.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--clH96tMg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irdsehga72q9y7zsvcyd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--clH96tMg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irdsehga72q9y7zsvcyd.jpg" alt="Image description" width="453" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the SBI instruction is 16 bits, only 5 bits can be used for the IO register address (0-31), and therefore it is not possible to use the instruction for an address greater than 0x1F. 3 bits, in combination with numbers (0-7), are used for the position in the register that we set to logic "1", and 8 bits are part of the operation code of the instruction (BIN 10011010). When we add all the bits together, we get a result of 16 (5+3+8). Remember: the AVR CPU only executes 16 or 32-bit instructions.&lt;/p&gt;

&lt;p&gt;In addition to the SBI instruction, there is also the CBI instruction, which sets one bit of the IO register to logic "0". Note that the only difference between the CBI and SBI instructions is in the first 8 bits of the operation code. For CBI, they are 1001 1000, and for SBI, 1001 1010. The difference in just one bit of the operation code for the AVR CPU means the execution of a completely different instruction (SBI or CBI). The advantage of the CBI and SBI instructions is their speed in managing a single bit in the address space of IO registers 0-31. All other methods are slower because they require more instructions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fw-75yOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gc50epyk06zn4fss31w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fw-75yOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gc50epyk06zn4fss31w.jpg" alt="Image description" width="444" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Executing CBI and SBI instructions requires 2 cycles of the main oscillator. If the MCU is running at 16 MHz, it can be said that configuring the output of port PB7 takes 2 x 62.5 ns or 125 ns (nanoseconds). It is important to know the duration of assembler instructions to have a better understanding of how much time is wasted when using "delay()". During the execution of one command of a higher programming language such as "DelayMs(1);", PB7 can be configured as the output of the microcontroller 8000 times.&lt;br&gt;
SBI and CBI instructions can be used to control a single bit in a register, and in addition to being limited to only the first 32 IO registers, they are not suitable for controlling the entire register, i.e., 8 bits. If you wanted to set all 8 bits of the DDRB register as output, you would have to execute SBI 8 times. The following example shows how to set all bits of the DDRB register using the SBI instruction. (DDRB = 0xFF)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wz1pqPz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akq89whoid3hozpfjyqq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wz1pqPz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akq89whoid3hozpfjyqq.jpg" alt="Image description" width="603" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When accessing all bits of a single register, it is better to use the IN and OUT instructions. The example shows how to set all 8 bits of Port B as outputs (DDRB = 0xFF). When using the IN and OUT instructions, it is important to note that the maximum address of an IO register that can be read and written is 0x3F. Therefore, these instructions can only access IO registers in the address space of 0-63.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--86yMNN6f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/offt2w729moloxdrcze5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--86yMNN6f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/offt2w729moloxdrcze5.jpg" alt="Image description" width="635" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The IN and OUT instructions are a bit more complicated than CBI and SBI as they use the AVR's working registers, which we haven't discussed yet. The AVR architecture has 32 working registers, R0-R31, and we won't go into detail about them at the moment. Writing 0xFF to the DDRB register using the OUT instruction can be done by loading the constant into a working register, R16-R31, using the LDI instruction, and then using the OUT instruction to store the value of the working register at the address of the DDRB register. When writing to the DDRB register in this way, we follow this procedure:&lt;/p&gt;

&lt;p&gt;Load the constant binary number 1111 1111 into a working register R16 (LDI R16, 0xFF).&lt;br&gt;
Store the working register R16 at the address of the DDRB register (OUT DDRB, R16).&lt;br&gt;
The OUT instruction has a significant drawback when it comes to manipulating a single bit: "With the OUT instruction, we change all 8 bits, not just one bit." If we want to change only one bit, we must know the state of the other 7 bits in order to keep them identical. The following example shows how to configure an output on port PB7 using the IN and OUT instructions, changing only one bit of PB7.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QtQmwARR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6iinro41c5i8ujj803r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QtQmwARR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6iinro41c5i8ujj803r.jpg" alt="Image description" width="671" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Controlling a single bit in C/C++ language is identical to controlling a single bit in assembly language using IN, OUT, ORI, and ANDI instructions. Since this chapter is more extensive, we will deal with the issue of the last example in the following text. ORI and ANDI instructions are logical operations OR and AND between a working register and a constant.&lt;br&gt;
Let's remind ourselves: "AND and OR are logical operators whose truth tables we have memorized for the needs of digital electronics, but we have never found their purpose". We will dedicate the following text to "OR" and "AND" logical operators to understand controlling a single bit in both assembly and higher-level programming languages. We can describe the last example briefly in four steps:&lt;/p&gt;

&lt;p&gt;Load the DDRB register into the working register R16.&lt;br&gt;
Execute the OR operation of the R16 register with the constant HEX 0x80, BIN 1000000&lt;br&gt;
The result of the operation is stored in the R16 register&lt;br&gt;
Save the R16 working register at the address of the DDRB register&lt;br&gt;
For better understanding of the assembly instructions SBI and CBI, it is good to try to control the PORTB register after configuring the DDRB register as an output. By changing the bits of the PORTB register, the microcontroller output is set to "0 V" or "5V", making it easy to understand the basic operation of the microcontroller output at the assembly level. To set the PB7 output and turn on the LED, only the "SBI DDRB, 7" and "SBI PORTB, 7" instructions need to be executed.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microcontroller Programming (7) - Arrival to Čučerje</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sun, 07 May 2023 08:51:56 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-8-arrival-to-cucerje-1in4</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-8-arrival-to-cucerje-1in4</guid>
      <description>&lt;p&gt;We often discuss our first microcontroller and we all remember it in detail. It was our entry into the world of imagination. Although we were young and inexperienced, there was always curiosity that led us through all these years of learning. Each new discovery aroused great satisfaction within us. Creativity became a part of our lives and every new day in the world of imagination brought about new excitement. Unfortunately, we all made a big mistake that we corrected for years. You will say that we made a lot of mistakes, and I agree. The identical thing you are doing now, we did too. As scavengers, we ran towards the outside world and started "carving" justice, without even organizing our own village. It's not your fault, nor were we wrong a long time ago, that's what we were taught, and that's what they teach us today. Maybe the idea of teaching you to "blink" an LED, read a keypad, and write on an LCD is a good trap to awaken your curiosity? Perhaps we need to limit you to the world outside of the microcontroller and teach you everything again one day?&lt;/p&gt;

&lt;p&gt;I abandoned the Arduino IDE and the idea of writing about it for a simple reason: it hides our beautiful Čučerje. Controlling the inputs and outputs of the microcontroller is easy in all programming languages, and I don't want to teach you that. Unfortunately, our village inside the microcontroller is incredibly large, and we need several years of learning to master everything we have at our disposal. Even the simplest blinking of an LED, which we wrote in previous texts in the Arduino IDE using the delay() function, is not programmed in the same way. We often mention the ARM architecture as something powerful, and it really is, but we cannot teach you to manage a big city when you don't even know how to manage a big village. The AVR architecture will be our village, and we will call it "Čučerje". If you prefer another name, feel free to change it. I use our beautiful Čučerje as a metaphor, and I declare myself the supreme commander of Čučerje. If you prefer tribes, feel free to take the title of chief somewhere in the south of Africa. Don't worry, programming is imagination, and whatever you choose, you are right. Our Čučerje looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kgAiYJ7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxuv8hswz8brj4z6y7jb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kgAiYJ7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxuv8hswz8brj4z6y7jb.jpg" alt="Image description" width="723" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, Čučerje is not so small after all. We will get to know it through texts about programming, but first we have to get comfortable, and where else but in the "FLASH" command center. You can find it on the map, and you will see that our command responsibility is a close collaboration with our colleague AVR CPU. Look at our village or tribe however you like, but the fact is that all instructions are written in FLASH memory and executed by AVR CPU. What about the others on the map? Those are our citizens and they make the microcontroller interesting and powerful. Arduino hides them from us and limits our control over our own village. The residents of Čučerje only understand the ancient language of assembler, but since we have a translator called "Compiler", we can establish a command center using c/c++.&lt;br&gt;
Luckily, we are in an advantage. Most supreme commanders do not know about the existence of this magical village, they believe that FLASH and RAM make up the final microcontroller. We are not better off at the moment, but at least we know about the existence of the citizens of Čučerje, and we still have to learn how to communicate with them. To do this, we must understand the meaning of the word "register". The simplest description of a register is "special-purpose memory". Special-purpose memory...this description doesn't tell us much, especially since we have CPU registers, IO registers, this kind and that kind of register. We could think about the definition of registers for days, and it would be difficult to understand what they are. They are memory locations of special purpose, but in Čučerje, they are part of our colleague SRAM, with whom we will work closely in the future.&lt;br&gt;
The only way to control our Čučerje is to control the registers of the SRAM memory. But beware, our Čučerje is not just beautiful, it is full of big secrets. Every door we open will give us the impression that we are opening a Russian Babushka doll that never ends. Perhaps it is best that we first get to know the closest collaborators of Čučerje, AVR CPU and SRAM. Due to the complexity of their personalities, we currently cannot know everything about them, trust me, they are complicated types. But at least we can learn what they mean for Čučerje and what role they play in our village. Here, the three of us have met:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8kOGraft--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3i8byv46x52wawkvd5k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8kOGraft--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3i8byv46x52wawkvd5k.jpg" alt="Image description" width="297" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FLASH memory is the executive center of the AVR microcontroller, where all instructions are stored and where everything we program is located. Who executes them? Well, the AVR CPU, our processor, executes them. Do we have a processor in the microcontroller? Of course we do, that's our most valuable member of the team. SRAM is a somewhat complicated type that suffers from dementia and forgets everything if the "power" disappears for a moment. But we have invented a cure for it and called it "Initialization". The Arduino IDE calls this cure the setup() function.&lt;/p&gt;

&lt;p&gt;Our command chain is clear: the AVR CPU executes instructions exclusively from FLASH memory. There are microcontrollers that can execute instructions from SRAM memory as well, but their program is still stored in FLASH memory and is copied to SRAM when the MCU is started and executed from there. Our command center must be in FLASH memory and we do not have the ability to execute instructions from SRAM memory. FLASH and SRAM are memories of the microcontroller, and if we want to simplify their purpose, we can say that FLASH permanently stores our program, while SRAM is a data storage that we have when the microcontroller is powered on.&lt;/p&gt;

&lt;p&gt;As the saying goes: "SRAM is a data storage...". We can think of each memory having a beginning and an end, and everything in between is called the memory size or capacity. Using this principle, we can say that in a personal computer, we have 4096 MB of RAM memory, with a clearly defined beginning and end. For a simpler example, let's imagine a memory of 4 bytes and ask the logical question: what differentiates the beginning and end of the memory? The only difference is in the address and data. We can say that the data 10101010 is stored at address 0 and the data 00001111 is stored at address 3.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--exAOXJdm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3vuwwa0wa8sd6o9giqf2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--exAOXJdm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3vuwwa0wa8sd6o9giqf2.jpg" alt="Image description" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more important question is: Can we store the data that we previously stored at address 3 to address 0, and store the data from address 0 to address 3? If you look at RAM from the perspective of a personal computer and if RAM is a data storage, of course we can. RAM is our storage and we decide what and where to store it. However, in Čučerje, SRAM is not just a data storage, and the above example of memory does not apply to the residents of Čučerje. Certain memory locations are connected to ancient magic and it would be a shame not to know more about them. Let's take a closer look at our address space in SRAM memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D0hdviRR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7agz9fphptnvibp49w28.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D0hdviRR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7agz9fphptnvibp49w28.jpg" alt="Image description" width="492" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The data storage described above exists in Čučerje and is called "Internal SRAM", but its starting address is not 0x000, but 0x200. In the SRAM memory from address 0x000 - 0x1FF, Čučerje's registers are located, and that memory space cannot be called a data storage. Let's go back to the definition: "Registers are special purpose memory". We have proven that they are memory, and not just any memory but the address part of the SRAM memory, and not just any location but a specific address space 0x00 - 0x1FF. I know, I know. The question still stands: "What are registers?"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oquttisi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ih120t4p7pknux3xsd6x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oquttisi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ih120t4p7pknux3xsd6x.jpg" alt="Image description" width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to manage our village in some way, we must collaborate with all of its inhabitants, and we do this by reading and writing registers (special memory locations designed solely for this purpose). Each register is responsible for a certain functionality of our village, and since our village is quite large, we have a lot of registers. Managing registers is no more complicated than the following example. Instead of having sun, rain, we have DDRA, PORTC, PIND, TCCR1A..., but the principle is identical, and the purpose is not far from the truth.&lt;/p&gt;

&lt;p&gt;If we add up all the registers of Čučerje (32+64+416), we get a total of 512 bytes. We cannot use all of them since certain memory addresses of registers are reserved for possible expansion of Čučerje, but there are enough of them to keep us busy for several years and to make us wonder again: "How well do we know the AVR architecture?"&lt;/p&gt;

&lt;p&gt;In the AVR Studio development environment (in C and assembler), there are no pinMode() and digitalWrite() functions as in the Arduino IDE, but there is something even better. Every time we access the registers of Čučerje, we call them by their real names.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ftWaNCV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o9cnhgmyfc6ko8teqwqx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ftWaNCV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o9cnhgmyfc6ko8teqwqx.jpg" alt="Image description" width="478" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No wonder why all beginners cringe at such written programs. No wonder why they don't understand our close collaboration with architecture. We don't see any illogicalities in managing Čučerje, and you don't see the whole Čučerje.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microcontroller Programming (6) - Journey towards higher programming languages</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sun, 07 May 2023 07:43:02 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-6-journey-towards-higher-programming-languages-9k5</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-6-journey-towards-higher-programming-languages-9k5</guid>
      <description>&lt;p&gt;Recently, I had a conversation with a friend who, among a few thanks for my written text, advised me to pursue pure philosophy. The situation wouldn't be so bad if I didn't completely agree with his opinion. These few texts about different views on writing programs really fall into such a category. I have been circling around the topic for some time now and I'm not quite sure how to write the truth to you. I probably think that a certain understanding of the basics of our goal is the best foundation for starting to learn programming. I haven't talked about time yet, the thing that will give you the biggest headaches while trying to understand my text, but honestly, programming is always in some endless struggle with the concept of time and what time means for microcontrollers. Perhaps for that reason, I smell in the air that I will create a critical mass of enemies in a few sentences who will tell you, in this or that form, that I'm writing complete nonsense. Of course, this text is not only read by beginners, but also by people with a few initials in front of their names, like "Jean-Claude Van Damme". But regardless of the opinions of all the others who are trying to teach you programming, I will open Pandora's box and release the hell that makes up the biggest programming delusions.&lt;/p&gt;

&lt;p&gt;Among other things, I was criticized for not writing program examples that would introduce beginners to programming. What program examples? For 20 years, while reading texts about programming, we've been spinning in chaos of lies and wrong beliefs. What should I do now? Continue the path that all those before me have walked? I really don't want to. On the other hand, when it comes to programming microcontrollers, 99% of "normal" people we meet in life immediately push us into some basket with all other programmers. I often hear how the neighbor's kid is also a programmer, just like me, but is currently in Tehran delivering 70,000 dinosaur eggs from 60 million years ago... I have long lost the desire to say that I'm a programmer. "Normal" people don't know exactly what that means, and if I said some subset of programming like "Microcontrollers", then everyone would put me in the category of "Walking Weirdo". For several years now, I've been saying that I'm an electrician, just to avoid the misunderstanding of the word "Programmer". The person who designs websites or adjusts a CNC machine is also a programmer, regardless of the fact that their job has no points of contact with the issues we deal with. What is special about programming microcontrollers is the close collaboration of the program we write, the microcontroller hardware, and electronics. We can't put these three items into one "Windows" programmer who writes an application for a personal computer. He has no contact with electronics, and it certainly doesn't occur to him to solder a 100nF capacitor onto his personal computer processor. After all, his hardware is finite and cannot be changed, so he can only write software code.&lt;/p&gt;

&lt;p&gt;If we go back to our microcontrollers, hardware is not final. We are the ones who will decide on every pin of the microcontroller. We must connect it to an LCD, buttons, sensors... And to top it all off, we are the ones who collaborate with the hardware and architecture of the microcontroller. When I say "Architecture", referring to AVR, that is what I want to teach you. Knowing at least one architecture is incredibly valuable knowledge, and it brings with it the ability to program any microcontroller.&lt;/p&gt;

&lt;p&gt;Everything you have learned about programming during your upbringing is the biggest possible lie. For years, we have trained your minds to think logically, but we do it in a completely opposite way. We know very well that we are teaching you wrongly, but we cannot find a better solution. It is not a problem of the teacher, but a problem of our perception and experiencing of the world around us. We are used to thinking procedurally, programming just as we experience the world, but in such chaos, we never ask ourselves how the world experiences the microcontroller? The first program we will always make you do is called "Turning on and off the LED," and we immediately trick you. Our intuition tells us that we should turn on the LED, wait for 1 second, turn it off, wait for 1 second, and repeat the same procedure. We make this mistake in the Arduino IDE:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g8XqJq2k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f71s2o88r9deujx2aho1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g8XqJq2k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f71s2o88r9deujx2aho1.png" alt="Image description" width="386" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delay commands are not used in programming, at least not the way they are used by 100% beginners. The greatest power we possess is called instruction execution speed, and it is directly related to the concept of time. This is difficult to explain because the way microcontrollers work is directly opposite to our expectations. If I cannot explain it to you now, I can show you. Take all the programs you have ever written in your life and delete all the wait commands such as "Wait", "Delay", "Sleep". What you can conclude is that your program runs incredibly fast, and that is exactly the kind of program we should be writing.&lt;/p&gt;

&lt;p&gt;No one will tell you that wait commands are not used because it leads you to a difficult question: "How to wait for a second if we are not allowed to wait?" The answer is complicated, but trust me, let me guide you through the philosophy a bit more and we will start exploring this tangled truth about programming. I did not say that programs that use wait commands like "delay" do not serve their purpose, I am just saying that no program that uses "delay" for the purpose of describing real time is written correctly and completely limits the programmer's imagination. Time and "delay" will be our enemy in all the news that this text brings, and it is currently important that you only remember the name of the enemy. Don't worry, dear reader, you will understand this when time traps you.&lt;/p&gt;

&lt;p&gt;An assembly programmer sits on a "devil's" flying broomstick that has almost no brakes. He cannot call "delay(1000);" to wait for one second. The only thing he can do is execute an assembly "NOP" instruction, but it only slows the program down by 50 ns (nanoseconds) if the MCU is running at 20 MHz. He can add the same number over and over again to pass one second, but he cannot afford to waste so much time. We must forget about the waiting commands and not use them until we learn how to write programs without them. Of course, I don't expect you to understand me now, but when you understand how to program without "delay" commands, you will immediately realize the heavy burden you carry by using waiting commands.&lt;/p&gt;

&lt;p&gt;When we teach you how to program, we always start from the top of the mountain and develop your "delay" way of thinking in programming languages that are not even languages, but rather pictorial flowchart programs. This is when you arrange pictures like "Turn on LED, wait x time, turn off LED...". I will start from the bottom called assembly, just so you don't think that we write fried chicken in the FLASH memory of the microcontroller, but rather instructions composed of zeros and ones, in our case 2 or 4 bytes of combinations of the numbers "0" or "1". Assembly is a truly perfect programming language, they say 1 to 1. This means that each assembly instruction is identical to one microcontroller instruction stored in FLASH memory. Assembly is nothing but a more readable HEX file. You can find simple proof in the program for turning on the LED written in assembly and published in the previous text.&lt;/p&gt;

&lt;p&gt;Programming languages for microcontrollers can be divided into two groups, assembly and all the rest. In a program that involves LED on the Arduino MEGA 2560 board, we can see how powerful assembly language is and how short hex files it can generate. Of course, it can, as the hex file and assembly are one and the same, just packaged differently. Now you might be thinking, "I will write in assembly and be the best, fastest, and most perfect." Well, you won't, you didn't ask me about the cost of programming in assembly. When someone gives us perfect gifts, something must necessarily smell like great evil. If assembly language were so good, no one would use higher-level programming languages like C/C++. In fact, higher-level programming languages wouldn't even exist, yet they are here to stab magical fairies into the flesh on which we sit and force us to reconsider the programming language we want to work with microcontrollers. So far, I have only written about the perfection of assembly, but I haven't talked about its shortcomings, which is why we prefer C/C++.&lt;/p&gt;

&lt;p&gt;Every microcontroller architecture only supports the instructions for which it was designed. Knowledge of assembly can only help you on computers whose assembly language you know. You cannot use AVR assembler on other architectures and microcontrollers, and this fact limits us only to one architecture. For each new architecture, we would have to learn a new assembler. Each computer and its internal order are too different, so instructions that you know on the AVR architecture do not exist on other computers at all. Each architecture writes instructions completely differently and executes them completely differently. Assembly is an extremely complicated language, not only because it is tied to one architecture but also because it is the lowest level of thinking in which you cannot simply add even two numbers. If you wanted to use assembly, you would have to think identical to the microcontroller, and that is, believe me, complicated.&lt;/p&gt;

&lt;p&gt;Of course, in this regard, we needed some help and a new language that would unify all computers, architectures, and simplify the complicated assembler. Lo and behold, on the sixth day, higher-level programming languages were created, along with c/c++. They are considered higher-level only because they are not assembler. Therefore, they do not belong to the group that microcontrollers "think" in, but are much closer and simpler for us programmers. The programming language c/c++ is standardized and the whole world adheres to its rules. Remember the main() function. Regardless of whether it is hidden in the Arduino IDE, the rules of the c/c++ language dictate that the function must exist, otherwise, the programming language cannot be called c/c++. The beauty of a standardized language like c/c++ is the fact that all programmers must adhere to all language rules, and when you learn it, you can say that you speak at least two languages, one of which is c/c++. Today, you can communicate with all microcontrollers in the world using the programming language c/c++, which is why learning it is extremely important if you want to work with microcontroller programming.&lt;/p&gt;

&lt;p&gt;Why is the "main()" function so important? That's where we anchor and transition from philosophy to programming, that's where everything starts and ends, where every complete program is written in the c/c++ programming language, and there is nothing as pure and bright as an empty "main()" function that will be our starting point for creative work. However, no matter how hard we try to program in higher-level programming languages, we cannot escape the ugly reality that microcontrollers still execute only assembler instructions, only those zeros and ones, that hex file that always marks the bottom of our work.&lt;/p&gt;

&lt;p&gt;Slowly but surely, we are finally approaching the new concept of our life's misery called "Compiler." I have already tired you enough to know that it is not possible to enter a high-level programming language program into the FLASH memory of a microcontroller. High-level programming languages like C/C++ look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e--Iz5bi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye1c66tk9sse66eim1su.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e--Iz5bi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye1c66tk9sse66eim1su.png" alt="Image description" width="495" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now all possible alarm bells should be ringing in your head about how the microcontroller does not understand the language we keep whispering to it about what to do. It needs those zeros and ones, that ugly hex file. A compiler is a program that translates higher-level programming languages into assembler instructions that the microcontroller can understand. It's nice that there is a compiler for AVR, a compiler for 8051, a compiler for ARM, a compiler for everything. We no longer have to learn all the assembler languages, it's enough that we know c/c++, and let the compiler translate our higher-level programming language thinking into assembler for specific architectures.&lt;/p&gt;

&lt;p&gt;As in everything, we have to pay the price. There is no compiler as good as our wisdom and cunning. The compiler is a program that doesn't have our intelligence and can't translate higher-level programming languages as perfectly as we would write them in assembler. For this reason, there is no perfection in assembler, and we cannot use the microcontroller to 100% of its capabilities. However, due to the universal language with which we can program all microcontrollers, and the fact that speed, memory, and performance of microcontrollers are increasing year by year, the sacrifice we make is much smaller than the advantage we gain by using higher-level programming languages such as c/c++.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Programming microcontrollers (5) - Arduino / AVR Studio / Assembler</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sun, 07 May 2023 06:19:21 +0000</pubDate>
      <link>https://dev.to/jstivic/programming-microcontrollers-5-arduino-avr-studio-assembler-3emp</link>
      <guid>https://dev.to/jstivic/programming-microcontrollers-5-arduino-avr-studio-assembler-3emp</guid>
      <description>&lt;p&gt;I am starting to write a new text about programming, but something is slowing me down terribly. I have written a lot of text in which I cannot find satisfaction. I miss the registers, the cruel c/c++, I miss the vectors, counters, peripherals, I miss the structure of the program, I miss the imagination. It's like someone has taken away the beauty of programming, hidden the truth about hardware, and given me the Arduino IDE. And I ask myself the same question several times: "How can I teach you the AVR architecture using the Arduino IDE?" And somewhere between truth and lies, I find the answer: "You can't". Fortunately, I can go back to the beginning of the idea, to what I want to achieve with the programming text, and everything becomes clearer to me. I don't want to give you libraries, take away hardware, and hide the truth, no matter how complicated it may be. The Arduino IDE has very cleverly bypassed the MCU hardware and given you ready-made functions written by professionals. It's not all black, we can always write programs in a professional tool like AVR Studio and use the Arduino development board and its bootloader. Let's remind ourselves, the bootloader allows us to change the FLASH memory without using a programmer. Arduino IDE (left) and AVR Studio (right) are two different development environments, and you don't have to be a genius to conclude which one is more powerful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xRexBjVO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i477qukc75o1kl6qc1t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xRexBjVO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i477qukc75o1kl6qc1t.jpg" alt="Image description" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before starting to learn programming, we need to ensure the necessary hardware on which we can test all of our programs. Currently, Arduino offers around 20 different development boards, and we will be using the "Arduino MEGA 2560". This development board is characterized by one of the most powerful 8-bit AVR microcontrollers, the "ATmega2560". It is much easier to learn programming on a "smaller" microcontroller, but we do not want to be limited by the microcontroller's pins, memory, and peripherals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o1jSevZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0w1vh3wny7d6ivxvnp2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o1jSevZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0w1vh3wny7d6ivxvnp2.jpg" alt="Image description" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am trying in vain to connect different perspectives of writing programming code and I am unable to find the right words to describe the reasons for my previous failures. Arduino IDE is the best tool for beginners and offers an easy adoption of the basics of programming in c/c++ language. You can download it from the website &lt;a href="http://www.arduino.cc"&gt;www.arduino.cc&lt;/a&gt; and test a large number of programming examples implemented in the development environment within a few minutes.&lt;/p&gt;

&lt;p&gt;In all attempts to choose Arduino IDE as a development environment, I can't ignore the most important detail: "It's almost impossible to learn how to program microcontrollers in Arduino IDE!". It's not easy to support every "stupidity" I write with indisputable evidence, so accordingly, I will ask all Arudino c/c++ programmers the following question:&lt;/p&gt;

&lt;p&gt;Generate a 50% duty cycle PWM signal with a frequency of 62.5 kHz using "Timer/Counter 1" in "Fast PWM" mode provided that the "TOP" value of the counter is defined by the "ICR" register, and call the shortest possible "ISR" on each counter overflow. The question is: Which assembler instruction, other than "SEI", sets the I-bit of the SREG from logical "0" to logical "1" in the written program?&lt;/p&gt;

&lt;p&gt;I hear someone in the background, some genius AVR who doesn't even think about starting to program this. He just smiles and with knowledge of the AVR architecture, he answers "RETI" in a few seconds. Genius, sit down, you're right! We can't and shouldn't look at the microcontroller as a black box, and Arduino IDE constantly forces us to do so. However, freedom of choice still allows us to use both development environments, Arduino IDE and AVR Studio, and in the future, we will have to conclude what Arduino IDE hides, and I eagerly want to show you.&lt;/p&gt;

&lt;p&gt;Let's write the simplest program using the Arduino IDE. Connect the "Arduino MEGA 2560" development board to your USB computer, open the example located at "File/Examples/01.Basics/BareMinimum". If you have properly set the "Board" and "COM port", after clicking on the "Upload" button, the Arduino IDE will write a new program to the FLASH memory of the AVR microcontroller and confirm the write with the message "Done uploading". This is the simplest program we can write in the Arduino IDE.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tv-sLfvM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrhsblwqbjplitqf11p6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tv-sLfvM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrhsblwqbjplitqf11p6.jpg" alt="Image description" width="418" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important rule of the c/c++ language states that a written program must contain at least one function and it must be called "main()". As you can see in the example, we have functions named "setup()" and "loop()", but the "main()" function seems to be missing. By looking at the two functions in the Arduino IDE, we can conclude that something is hidden from us, and that is primarily the "main()" function. What is the truth when, on the other hand, it is a lie? Here is the "main()" function located at: "C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\main.cpp".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W49rhOuy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eoe72bvs248gxp7inizi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W49rhOuy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eoe72bvs248gxp7inizi.jpg" alt="Image description" width="383" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not possible to write a program in the C/C++ programming language without having a function called "main()". The shortest C/C++ program looks like this: "int main() { }" and consists of the only required function main(). Yes, Arduino IDE wrote the most important function "main()" without our knowledge, and gave us the functions "setup()" and "loop()". In the main() function, you can find a call to a completely new function called init();, which sets up the AVR architecture, its registers, counters, analog-to-digital converter... How did Arduino programmers know how to set up the microcontroller? They didn't know, they set it up as best they could and ignored 90% of the microcontroller's capabilities. I am appalled by the fact that they set 16-bit counters in an 8-bit mode and ran them at low frequencies. It's like driving a car at 2 km/h, and no one can dispute that you're still moving. I know you expect an explanation of terms such as counter, function, register, setup(), loop(), main(), and many other things I've written, but you'll have to be patient.&lt;/p&gt;

&lt;p&gt;Why doesn't Arduino IDE show you the main() function, all the details of the init() function, or to be more precise, all the details of any Arduino function? We would have to reveal a big secret: "Programming microcontrollers is extremely complicated." Instead of the truth, they give you functions with names like pinMode(), digitalWrite(), analogWrite(), analogRead(), tone(), shiftIn(), millis(), micros()... They give you libraries for Servo, GSM, Ethernet, WiFi, I2C, UART... They open up the possibility of connecting the development board to all sensors labeled "Arduino compatible." With such wonderful gifts, they take away 90% of the real capabilities of the microcontroller, leave 10%, and convince you that Arduino IDE is unquestionably the best. It's not the best, but it's certainly the easiest. That's why Arduino IDE is so popular, because nobody wants to learn too much, we all expect fast results. If I wrote only about Arduino IDE, I would save a lot of my and your nerves, show an example of turning on an LED, explain 2 functions, and finish this story in a few hours. There is one thing I wouldn't forgive myself for. Arduino IDE is a village, AVR architecture is a city, and ARM architecture is the whole world for now. &lt;/p&gt;

&lt;p&gt;If I wrote about Arduino IDE development environment and programming in it, I wouldn't be allowed to mention any of the terms from the following collection: "SREG, STACK, SP, PC, SEI, TCCR0A, OCR1B, R0, DDRC, PORTA, PINB, ADMUX, ADCSRA, EEAR, EICRA, EIMSK, CS00, TOIE2, COM2A, TOV2, UDR0, RET..." Over time, I would write many Arduino IDE examples, make dozens of devices and robots, fulfill all your assumptions about programming, and throw away many years of my own struggle and learning. For Arduino IDE, you can find all program examples and detailed descriptions on the internet, the whole world writes about them. I see no reason to explain identical programs again.&lt;/p&gt;

&lt;p&gt;The biggest sin of a programmer is understanding tools such as Arduino IDE, AVR Studio, Bascom, Assembler, Notepad, and ultimately the HEX file. Ignorance is bliss. If we gather all the types of programmers mentioned, they will all talk and think about the same thing, they will all be right, they will achieve the desired result, yet they will write completely different commands. Where else to look for the truth but in the FLASH memory of the microcontroller. No one can forbid us to turn on the LED in both Arduino IDE and Assembler. All programmers know that to turn on the LED, which is called "L" on the Arduino MEGA 2560, it only takes three things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure the port as an output of the microcontroller&lt;/li&gt;
&lt;li&gt;Set the port to the logical state "1" (5V on the port turns on the LED)&lt;/li&gt;
&lt;li&gt;Stop further program execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nKhEOV2Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aewhnanf08idc39u1vnn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nKhEOV2Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aewhnanf08idc39u1vnn.jpg" alt="Image description" width="542" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Arduino IDE, we can achieve this task by calling just two Arduino functions named &lt;strong&gt;"pinMode(13, OUTPUT);"&lt;/strong&gt; and &lt;strong&gt;"digitalWrite(13, HIGH);"&lt;/strong&gt; as shown in the picture. pinMode() sets the LED port as an output, and digitalWrite() sets the output to a logical "1" state. The third item of "stopping the program" has already been done, but we don't see it because the Arduino IDE once again limits us to exact information. Don't worry, in main.cpp file and main() function, you can find the program line "for(;;)", which is an infinite loop from which the microcontroller never exits, and we can say that we stopped the program execution with an infinite loop. Well, not us, the Arduino IDE did it for us. All dreams have come true, at least until we look at what is written in the FLASH memory of the AVR microcontroller. Instead of explaining programming, I am futilely looking for a small enough font to display the FLASH memory of this simple program written in the ARDUINO IDE.&lt;br&gt;
As opposed to the Arduino IDE, we can include an identical LED in the purest and most powerful assembler and write just 3 instructions to the microcontroller's FLASH memory. This is not a joke; this is the real difference between the ARDUINO IDE and assembler. How is it possible that both programmers are thinking about the same three things that they need to do, they both need approximately the same number of commands, and as a result, they get such a different program size recorded in the FLASH memory? Since we are already fragmenting the program, let's take a closer look at the "hex" file written in assembler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_lmjvDvd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmslcq4zc84dbt4qry3h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_lmjvDvd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmslcq4zc84dbt4qry3h.jpg" alt="Image description" width="534" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;• Bytes: 06 - Number of bytes for the FLASH memory. As expected, we need 3 instructions of 2 bytes each. In the hardware and memory section, it is explained how AVR executes instructions of 2 or 4 bytes. In this case, the instructions "279A", "2F9A", and "FFCF" are each 2 bytes in size.&lt;br&gt;
• Address: 0000 - logically, the first instruction is located at the beginning of the FLASH memory, at address 0000.&lt;br&gt;
• Data: 00 - the HEX row contains information for the FLASH memory.&lt;br&gt;
• Instruction: 279A - The first instruction for the AVR CPU sets the LED port as an output.&lt;br&gt;
• Instruction: 2F9A - The second instruction for the AVR CPU sets the LED port to a HIGH state.&lt;br&gt;
• Instruction: FFCF - The third instruction for the AVR CPU stops further program execution.&lt;br&gt;
• Checksum: A2 - A control byte that proves the correctness of the HEX row record.&lt;br&gt;
• End: 00000001FF - Indicates the end of the HEX file.&lt;/p&gt;

&lt;p&gt;Someone is laughing again in the back row because they know that only instructions for the AVR CPU are written to the FLASH memory of the microcontroller, not a HEX file: 279A, 1F9A, FFCF. To understand these differences in programming, in the following text we will arrange higher-level and lower-level programming languages and introduce a new concept called "Compiler".&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Programming Microcontrollers (4) - Hardware and Memories</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sat, 06 May 2023 22:15:26 +0000</pubDate>
      <link>https://dev.to/jstivic/programming-microcontrollers-4-hardware-and-memories-1n2k</link>
      <guid>https://dev.to/jstivic/programming-microcontrollers-4-hardware-and-memories-1n2k</guid>
      <description>&lt;p&gt;At the moment when I provide a stable power supply voltage, stable reset line, and stable operating frequency, the AVR microcontroller becomes a perfectly functional system. The only drawback of such hardware is the fact that the microcontroller does not do anything useful. To make the microcontroller useful, we must modify its memory. There are several ways to modify the memory of a microcontroller and several types of memory that we can modify. In-System Programming (ISP) is the most commonly used method for programming AVR microcontrollers and it consists of 6 programming lines (MOSI, MISO, SCK, RESET, GND, and VCC). Since I used the ATMEGA8A as an example of basic hardware needs, I will use it for the final hardware design as well as for the presentation of microcontroller memories. The lines of the ATMEGA8A microcontroller that need to be connected to the programmer are shown in the picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1zIbufXu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p0k0amk278561ilb2t14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1zIbufXu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p0k0amk278561ilb2t14.png" alt="Image description" width="452" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be able to program the memories of AVR microcontrollers, it is necessary to provide voltage supply on the GND and VCC lines. There are USB programmers that have the option of supplying power to the microcontroller via USB voltage of 5V, but a better option is to supply the AVR from a voltage regulator. We can design AVR hardware to operate at 3.3V and use various components that operate at a maximum voltage of 3.6V. If we were to power such hardware from a USB programmer (5V), we would destroy all components that cannot operate at 5V. ISP allows us to program the AVR in-system, which means that we do not have to physically separate it from other electronics. It is enough to connect the ISP programmer to the finished device, turn on the device's power supply, and write the new memory state. The image shows two standard ISP connectors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F_Cxwanl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z9ykab9d5bnwbp6ru1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F_Cxwanl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z9ykab9d5bnwbp6ru1d.png" alt="Image description" width="302" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we compare the pin names again, there are only 6 pins, so it is better to use a smaller connector (2x3) to save space. There are programmers that have a 2x5 connector, so a converter is needed to connect them to the finished hardware. In some AVR microcontrollers, ISP is connected in a different way. As an example, I mention the ATMEGA64 which uses PE0 and PE1 for the MOSI and MISO pins. This is stated in the technical documentation, but only on page 306 titled "SPI Serial Programming Pin Mapping". You will not often find an AVR microcontroller that uses different pins for ISP, but it is enough to remember that it can happen. If you want to be sure about the ISP pinout, read the technical documentation. We have only 3 pins where we can make a mistake. GND and VCC are power supply pins, RESET is unique. Three pins remain, MISO, MOSI, and SCK. In almost all AVR microcontrollers, we connect them to pins with identical names, MISO, MOSI, SCK. But beware, ATMEGA64 may not be the only black sheep.&lt;/p&gt;

&lt;p&gt;When programming a microcontroller via ISP, there is another important rule: "The frequency of the ISP programmer must be lower than ¼ of the frequency of the AVR microcontroller." If we are programming ATMEGA8A for the first time, we need to know that it operates on an internal oscillator of 1 MHz and that the programmer's frequency must be lower than 250 kHz. This parameter can be set in the programmer's settings. When programming the microcontroller, it is necessary to set the MCU name, the file we want to program, and the memory we are programming. These settings are intuitive, so I won't describe them in detail right now. Many programmers will tell you that programming is problem-solving. Problems do not have to be mathematical in nature and directly related to program logic; they can also be related to the frequency of the ISP programmer. That's why I am listing these finer details that are a common problem but are relatively small in the documentation. To give our hardware some purpose, I added an LED to it, at least so we can turn it on or off. The final schematic and hardware design using the ATMEGA8A microcontroller are shown in the picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xrzhbMGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk59md82n7m8891153yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xrzhbMGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk59md82n7m8891153yu.png" alt="Image description" width="604" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OrLpvq6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d6x1id4vq2sqs6zy1a1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OrLpvq6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d6x1id4vq2sqs6zy1a1.png" alt="Image description" width="681" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xlimL6SA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgcv94ofcbtyovbem649.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xlimL6SA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgcv94ofcbtyovbem649.png" alt="Image description" width="681" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using an ISP programmer, it is possible to modify the following memories:&lt;br&gt;
• FLASH (8192 bytes)&lt;br&gt;
• EEPROM (512 bytes)&lt;br&gt;
• FUSES (2 bytes)&lt;br&gt;
• LOCKBITS (1 byte)&lt;br&gt;
It is not possible to permanently store data in SRAM memory and therefore we cannot program it. After turning off the device from the power supply, everything stored in SRAM memory will be forgotten.&lt;br&gt;
The LOCKBITS memory of 1-byte size is used to lock the program and permissions around instructions (SPM, LPM) that can write and read FLASH memory. After writing FLASH, EEPROM, and FUSE memories, it is possible to lock the MCU to protect the written program from memory reading and device copying. A locked microcontroller is not permanently inaccessible, so using the programmer, an "Erase Device" can be performed which will set the FLASH, EEPROM, and LOCKBITS memories to 0xFF and allow us to program all memories again.&lt;/p&gt;

&lt;p&gt;The FUSES memory, which is 2 bytes in size, is used for microcontroller operation settings such as clock selection, low-voltage protection, starting address of FLASH memory after reset, bootloader size, WDT protection, and more. This is the only memory in which we cannot make a mistake. In the FUSES memory, it is possible to disable the external RESET pin, and if you do so, the MCU will become inaccessible for ISP programming. We also set the clock of the microcontroller in the FUSE memory, so it is possible to accidentally select "External Clock" and make the MCU inaccessible again. It is also possible to set the clock to "External Crystal," but if you have not connected an external crystal oscillator in hardware, the MCU becomes inaccessible again. An HV parallel programmer can access the microcontroller regardless of any mistakes made, but it is cheaper to buy another microcontroller than a parallel programmer. In the example of the ATMEGA8A hardware, we can select "External Crystal" for the clock to make the MCU run at a maximum speed of 16MHz. The FUSES memory is not identical for all AVR microcontrollers, so it is best to rely on the technical documentation of the microcontroller for its configuration.&lt;/p&gt;

&lt;p&gt;The EEPROM memory with a size of 512 bytes is most commonly used to store variable data that we want to preserve even when the device is turned off. If we want to make a device that counts every time it's turned on, obviously we need to store information about the number of device turn-ons somewhere. EEPROM memory is ideal for storing such information. We can use it to store the device name, various parameters on which the program is executed, the device password that the user can change, etc.&lt;/p&gt;

&lt;p&gt;The FLASH memory with a size of 8192 bytes is the largest memory of the microcontroller. Everything we program, regardless of the programming language, ends up in the FLASH memory as a combination of "0" and "1". With all other memories, things are pretty simple. We store something in the EEPROM or SRAM memory and read back the identical data, but the data in FLASH memory is far more complex. The FLASH memory contains instructions for the CPU, and everything the microcontroller does comes down to executing the instructions in the FLASH memory. To better understand the role of FLASH memory, I will explain the execution of the simplest and largest program called "New Microcontroller". I won't call it empty because in digital electronics, we only know the states of memory "0" or "1". The new ATMEGA8A microcontroller is shipped with the FLASH memory state where all bits are set to logic "1". If the ATMEGA8A has 8192 bytes, it is easy to calculate how many different states of "0" or "1" can be stored in the FLASH memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8192 byte*8 bit=65536 bit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you take a new Word document and use the copy/paste method to print 65536 logical "1"s, you will have the most precise insight into the FLASH memory of the purchased ATMEGA8A microcontroller. The AVR CPU only knows 2 types of instructions, those that occupy 2 bytes and those that occupy 4 bytes of FLASH memory, the third case does not exist. You can find all instructions for the AVR CPU and their encoding in the purest form of the combination of "0" and "1" in the document called "AVR Instruction Set". The laziest assembler instruction you can find in the aforementioned document is called "NOP" or "No Operation". We call it the laziest instruction because "NOP" does absolutely nothing, except that it takes one clock cycle of the microcontroller to execute the instruction. If the AVR executes one instruction for 62.5 ns at 16 MHz, "NOP" serves only to waste time. All high-level language instructions such as "Delay" and "Wait" are essentially identical to the assembler instruction "NOP". However, the microcontroller does not understand the instruction name "NOP" because the CPU executes only combinations of "0" and "1", and even such an instruction has an encoding that is understandable to the AVR processor. The "NOP" instruction in FLASH memory is recorded as 16 zeros, truly shown like this: "0000 0000 0000 0000". The instruction is 2 bytes long, which corresponds to the rule that the CPU only understands instructions that are 2 or 4 bytes long. The FLASH memory of the purchased ATMEGA8A consists of 65536 logical "1"s, not "0"s. What is the difference? Almost none, the instruction that is recorded as 16 zeros is called "NOP", and the instruction that is recorded as 16 ones is not an instruction at all. The microcontroller is absolutely indifferent as to whether it executes the instruction of 16 zeros or 16 ones, it will execute both combinations as the "NOP" instruction. The only difference is in our understanding and presentation of the instruction. 16 zeros are called "NOP", and 16 ones are called "Unknown Instruction". The image shows the FLASH memory of the purchased ATMEGA8A microcontroller:&lt;/p&gt;

&lt;p&gt;If we consider FLASH memory in which all bits are set to logic "1", the microcontroller will execute the laziest instruction "NOP". This realization leads us to the conclusion that the microcontroller is still doing something, even when it is not doing anything useful. It will execute the first 2 bytes of logical "1s" and do "Nothing", then take the next 2 bytes of logical "1s" and again do "Nothing". We can analyze the instructions all the way to the end of FLASH memory and execute "Nothing". The microcontroller is still a limited computer that, when it reaches the end of FLASH memory, starts executing the same program again. You might be wondering, how long does it take for a new ATMEGA8A microcontroller to execute the entire FLASH "Nothing"? The purchased ATMEGA8A operates on an internal oscillator with a frequency of 1 MHz, and it takes 1 microsecond to execute one instruction. If we have 4096 instructions per 2 bytes, and each of them takes 1 microsecond, the AVR needs 4096 microseconds to execute all FLASH memory instructions. After the last instruction is executed, the program returns to the beginning of FLASH memory and the "Nothing" circus starts again. Even a microcontroller that you can call "empty" executes the most programs, and you will never use it to execute all FLASH memory instructions in such an extensive way. Okay, the program does nothing, but you must agree that such a program takes up the entire FLASH memory because it executes all possible "Nothing" instructions. All programs you write in life will never use the entire FLASH memory like our new microcontroller. Now, whether you consider the new microcontroller full or empty, is up to you. I would say it's full, full of nothing.&lt;/p&gt;

&lt;p&gt;It is easy to analyze FLASH memory when it comes to the "NOP" instruction. The real complications come with writing a program that has a purpose, i.e., the program we program. All 130 assembly instructions are recorded as 16 or 32 bits in a combination of "0" and "1". It is terribly tedious to analyze such FLASH memory. To make matters worse, no written program executes instructions in the order of FLASH memory. We often check, compare, and condition something, so the results of operations scatter us throughout FLASH memory. The picture shows the beginning of FLASH memory of a program written in C and translated into assembler (HEX format).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--93YRHvTG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjm14wb8e6sh80a9xeyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--93YRHvTG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjm14wb8e6sh80a9xeyf.png" alt="Image description" width="482" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A knowledgeable expert in AVR architecture will immediately know that the first instruction "10C0" skips the ISR vectors and redirects the program to the 15th or 20th instruction, depending on how many vectors the MCU has. We don't currently need to know what ISR vectors are or why the first instruction skips them. It is enough to conclude that the already complicated FLASH memory layout becomes even more complicated by the fact that instructions are not executed in order. There is nothing more complicated in microcontrollers than analyzing FLASH memory and the instructions that the MCU executes. It is much easier to write a completely new program than to understand what the microcontroller is doing at the FLASH memory level.&lt;/p&gt;

&lt;p&gt;With this description of the basics of hardware and memory, I conclude the introductory text on microcontroller programming. In the next text, we can start with ARDUINO and programming in C/C++. Regardless of how much I write about programming in higher-level languages, I will often return to the smallest details of the AVR architecture, just so we can objectively look at all programming languages and better understand the true operation of the microcontroller.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microcontroller Programming (3) - Hardware</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sat, 06 May 2023 17:34:16 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-3-hardware-38kp</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-3-hardware-38kp</guid>
      <description>&lt;p&gt;In the development of electronic devices, we often encounter the design of our own hardware, but in the early stages of learning, it is better to buy a ready-made development board that already provides the basic things for the proper operation of the microcontroller. Although I will be using the ready-made Arduino hardware and Arduino development environment in the initial programming texts, it is necessary to understand the basics of designing hardware, which I will explain in more detail. My generation was not as lucky as today's "Facebook" kids because there was no Arduino and we could only buy a microcontroller and programmer. We designed the hardware independently, but we were not familiar with the details to pay attention to, so our devices worked in such an unstable environment. Turning on and off an LED will bore an average programmer after 5 minutes, and there is an immediate need to connect the microcontroller to various sensors, LCD, keyboards, and designing devices that have a specific purpose. Therefore, proper hardware design is extremely important before programming because if there are errors in the device's operation, it is often difficult to distinguish whether it is a hardware or software error. Hardware design is identical for all microcontrollers and consists of the three most important rules for stable microcontroller operation:&lt;/p&gt;

&lt;p&gt;• Stable power supply voltage&lt;br&gt;
• Stable operating frequency&lt;br&gt;
• Stable microcontroller reset line&lt;/p&gt;

&lt;p&gt;It is necessary to remember these items because they are extremely important in hardware design and can often give us a headache if we do not adhere to them. The slightest mistake in them can result in "strange" microcontroller behavior that sometimes stops working or performs some magic that we cannot explain logically. As an example of hardware design, I will use the ATMEGA8A microcontroller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stable power supply voltage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We often think that connecting a microcontroller to the power supply voltage defined in the technical documentation is sufficient, but in practice, it simply won't be enough. The stability of the power supply voltage is one of the most important requirements for any microcontroller, and if the voltage is not stable, the microcontroller may execute a program instruction incorrectly, causing our device to freeze. The microcontroller is not an analog component with a constant energy consumption, but rather, when executing assembly instructions at the clock edges, there is a need for a large power consumption that lasts only a few ns (nanoseconds). Therefore, in hardware design, it is necessary to provide fast and always available energy that the microcontroller can use. Such a fast need for current cannot be delivered to the microcontroller via long power lines, so the main source should be a capacitor. There is a golden rule that ensures fast and always available energy for a stable microcontroller voltage: "Place a 100nF capacitor between GND and VCC as close as possible to each microcontroller power pin." It is good practice, but not necessary, to place a coil in series with the microcontroller power supply to reduce interference on the power supply lines caused by the microcontroller's fast and short current needs. The resistance of the coil must be low enough to ensure that the microcontroller's power supply voltage does not drop to a critical level. Note that larger microcontrollers often have more power pins, so they all need to be properly connected to the power supply voltage. Most AVR microcontrollers have an implemented analog-to-digital converter (ADC) that has special inputs for the power supply voltage and reference voltage, so AVCC and AREF need to be connected to 5V, and AGND to GND. The correct layout of the elements in the microcontroller power circuit is shown in the picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cFuFDEwv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2dsef6msym7821expizl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cFuFDEwv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2dsef6msym7821expizl.png" alt="Image description" width="383" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The operating voltage of a microcontroller is always specified in the technical documentation, but it is often dependent on the microcontroller's operating speed. Most AVR microcontrollers specify a voltage range of 4.5-5.5V in the technical documentation when the microcontroller is operating at maximum speed. The technical documentation often lists the maximum operating speeds for the same microcontroller (e.g. 0-8 MHz @ 2.7-5.5V, 0-16 MHz @ 4.5-5.5V), so AVR microcontrollers can often operate at lower voltages at lower speeds. The ATMEGA8A can operate at a voltage range of 2.7-5.5V, but it is most commonly used with a 5V power supply. In the design of the microcontroller hardware, it is also necessary to design voltage stabilization for 5V, which is already done on development boards. Do not be fooled into thinking that voltage stability can be measured with a simple voltmeter, as an oscilloscope is still required for this, because the problem lies in the microcontroller's operating speed. If the ATMEGA8A can operate at 16 MHz, it is easy to calculate how often the AVR will execute one assembly instruction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T=1/F=1/16000000=62,5ns (0.000 000 062 500 s)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, the AVR will execute one assembly instruction in just 62.5 ns (nanoseconds). In the event that the voltage on the microcontroller drops below the allowed level for an extremely short period of time (e.g. 500ns), there is a high probability that the microcontroller will execute the wrong instruction. A wrongly executed instruction is like winning the lottery and may not necessarily lead to a program crash. Perhaps the AVR was executing an instruction that was not very important for the program's further operation (e.g. adding 2 numbers whose result is room temperature, which will not crash the program if calculated as 1000 °C by mistake). The AVR microcontroller has protection against low operating voltage, but unfortunately, the only solution is to reset and restart the program. The lottery is not what you want to gamble on in development, and it is definitely better to design hardware that has a safe and stable operating voltage. For a 5V voltage stabilizer, you can start with LM7805, but be sure to rely on the voltage stabilizer's technical documentation and implement the recommended input and output capacitors in the hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stable operating frequency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In addition to the operating voltage, it is necessary to ensure a stable operating frequency for proper operation of the microcontroller, which affects the speed of instruction execution. AVR microcontrollers have an internal oscillator implemented, so no external components are needed for microcontroller operation. The technical documentation states that the ATMEGA8A is supplied with an internal oscillator set to a frequency of 1 MHz. If the internal oscillator of the controller is used for the clock, the XTAL1 and XTAL2 lines are not connected. In device development, the internal oscillator is rarely used due to its tolerance. An external crystal oscillator is much more accurate than an internal oscillator and is therefore used much more often. The only drawbacks of an external crystal oscillator are the increased size and cost of the device. The diagram and circuit board for connecting an external crystal oscillator are shown in the figure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X7_rfgrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4for9vc0kl905xu9tzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X7_rfgrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4for9vc0kl905xu9tzu.png" alt="Image description" width="461" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stable Reset Line of Microcontroller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The reset line of a microcontroller is used to restart the program, and although it may seem harmless, it can be a potential source of difficult-to-solve problems. ATMEGA8A has 4 sources of reset: Power-on Reset, External Reset, Watchdog Reset, and Brown-out Reset. Only 2 sources of reset are included in the delivered AVR microcontroller: Power-on Reset and External Reset, so I will explain them in more detail.&lt;/p&gt;

&lt;p&gt;Power-on Reset is used to reset the microcontroller when we first connect it to the power supply, and if we have designed a stable power supply, we will not have any problems with it. It will correctly start the program from the initial address when the power supply voltage exceeds the lower limit of 2.3V, and as long as the power supply voltage is higher than 2.3V, the microcontroller will execute the program correctly.&lt;/p&gt;

&lt;p&gt;External Reset is a pin of the microcontroller that will reset the microcontroller when the voltage on it is lower than 0.9V for at least 1.5 microseconds. If we do not connect the external reset pin, it would often fall to 0V due to external interference and unnecessarily reset the microcontroller. To keep the external reset pin above 0.9V, we connect it via a 4.7 kOhm resistor to the power supply voltage (5V) and place a 100nF capacitor towards GND that does not allow sudden and rapid changes in the reset line caused by external interference in the hardware. The correct connection of the reset line of the AVR microcontroller is shown in the figure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MaYrIgti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5aiy8d07mnfg1ecgk0p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MaYrIgti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5aiy8d07mnfg1ecgk0p8.png" alt="Image description" width="420" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following text will present a complete design of the schematic and hardware for the ATMEGA8A MCU that you can use as a reference when designing your own devices.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microcontroller Programming (2)</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sat, 06 May 2023 12:56:42 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-2-25bh</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-2-25bh</guid>
      <description>&lt;p&gt;In the dilemma regarding microcontrollers, we often use the term "processor," which is not even remotely accurate. Processor and microcontroller are two completely different concepts. If you take apart your personal computer and take a closer look at the motherboard, you can see that the processor is the best-cooled component of your computer and is completely separate from RAM memory and the hard disk. The operating system on the computer is loaded from the hard disk, partially processed in RAM memory, partially on the hard disk, and managed by the processor or CPU (Central Processing Unit). The processor does not have memory in which to store the entire program it performs. The role of the processor is only to perform machine instructions, and where exactly these instructions come from is a completely different story. It is important to note that all components in a personal computer (RAM, CPU, HDD, etc.) are scattered across the motherboard or connected to it and are not just one component of the computer.&lt;/p&gt;

&lt;p&gt;A microcontroller is an entire small computer located in just one integrated circuit, of course, without a monitor. By the very statement that it is an entire computer, we come to the basic parts of the microcontroller. We do not have a hard disk, but we do have FLASH memory, whose role is to store the program that the microcontroller will perform. We have our own RAM memory, our own processor (CPU), and our own peripheral of the microcontroller. Most importantly, everything is located in just one integrated circuit, albeit with far smaller memory capacities and far lower operating speeds than a personal computer, but given its size, we cannot expect more. It is important that in one integrated circuit, we have all the most important components of any computer.&lt;/p&gt;

&lt;p&gt;When we talk about microcontrollers, we don't have to look far to find them. In today's world, almost every electronic device contains a microcontroller, and the reasons couldn't be simpler. We certainly don't want a personal computer in the trunk of our car to control the ABS, GPS, and all other car systems because it's not practical. We don't want to carry a personal computer with us in search of a power outlet to send an SMS. We don't want to connect a washing machine to a personal computer to run a wash cycle. These are the main reasons why microcontrollers, as small computers, have become so widespread, and therefore very cheap, and why they are used in almost every device. Their low cost plays a big role in their prevalence, which, I dare say, is practically free for what they can do. When I tell you that you can buy a complete computer for 2 or 3 euros that can perform a specific task in any technology field, then it's truly free. The dimensions of such computers can be 5mm x 5mm x 1mm or even smaller, which means that we can integrate them into any device we design. Of course, we can't perform demanding tasks on such computers like we do on personal computers, mainly due to their limited memory and speed, but that's not their purpose. Personally, I don't need a washing machine that runs Windows 7. I'm not going to play games on it or do complex graphic processing.&lt;/p&gt;

&lt;p&gt;However, learning to program microcontrollers is not easy. Hardware and software often combine into a logical unit, even though they are separated in all the books. Certain terms are related only to hardware, or only to software. Every technical documentation for a good microcontroller contains over 500 pages of text with strange terms, and every programming language has the same amount. If you only connect hardware and software books, even if we ignore the electrical engineering part, you still have 1000 pages of text in front of you talking about thousands of new and unknown terms. No beginner can easily navigate through such extensive documentation. It's crazy to mention how many programming languages and different microcontrollers and their architectures exist. Therefore, when we talk about learning programming, we talk about the path we take to learn.&lt;/p&gt;

&lt;p&gt;The story about programming microcontrollers cannot begin peacefully because in today's world, there is a certain war between all microcontrollers and programming languages. Every beginner is forced to choose a microcontroller and programming language to program in, and that's where we all make a big mistake. I made it a long time ago, and I'm almost sure that there is no forum related to microcontrollers that doesn't contain a comparison of AVR and PIC microcontrollers. Groups of programmers have formed to support one or the other microcontroller, and in that war, beginners suffer the most. The sad truth about these dilemmas is that it doesn't matter which microcontroller we choose. They are all good and work perfectly if we know how to properly start them and write good programs. In the professional world of microcontrollers, we often cannot choose the microcontroller we want to use for a project. Certain companies prefer certain microcontrollers, certain projects require certain microcontrollers. We dare to say "We know them all!" but... there is always a but! The microcontroller we first encounter and write our first programs for often becomes dear to us and takes a special place in the world of microcontrollers. Its architecture becomes the first one we get to know, we unconsciously remember the names of registers, configuration methods, and programming methods.&lt;/p&gt;

&lt;p&gt;I understand that it may seem that choosing a microcontroller is not a big deal, but we often make mistakes in selecting programming languages or even make such a big mistake that we don't realize it until many years of programming. We might choose BASIC because we believe it is the best and easiest for beginners, but over the years of programming in BASIC, we become so accustomed to it that the mere thought of a better programming language seems like science fiction. As time passes, it becomes increasingly difficult to decide to learn C or assembler. I assume that certain authors or readers who program in BASIC will not agree with my way of thinking. I cannot help them, but I can point out the mistakes they have made by choosing BASIC through my texts. Through experience, I could compare any two microcontrollers, but I would write so many technical terms that no beginner would understand what I mean. For that reason, I will currently write about AVR microcontrollers. All my programming texts will be focused exclusively on programming AVR microcontrollers. Only when we understand certain concepts through these texts will I take the liberty to compare them not only with other microcontrollers, but also with all programming languages. The programming texts I will write for you will be complicated, difficult to understand, but they will be the truth. Quality knowledge has never been easy to achieve. It is often the harder path that I will guide you through in my programming texts for microcontrollers.&lt;/p&gt;

&lt;p&gt;As I wrote a lot of text trying to explain to readers the way of professional programming, often finding myself in situations where I had to explain the smallest details of architecture, I decided to take the only logical path of learning, which makes it very easy to switch to professional programming. Although I am not a fan of development tools such as ARDUINO, primarily because I am extremely limited in such an environment that only has 5 buttons, I must admit that such a tool is certainly the best for learning programming. There are several well-established reasons that lead me to this conclusion. ARDUINO is based on the C/C++ programming language. The entire program and all libraries are open-source, meaning that we can use them but we don't have to. The fact that we don't have to use ready-made libraries leads us to advanced programming, where we can influence even the smallest detail of the microcontroller. At the same time, we can be both amateurs and professionals, depending on how we look at ARDUINO. Each ARDUINO development board has a bootloader, which means that we don't need a programmer and for the start, we don't have to struggle with FUSE settings of the microcontroller, and we can upload the program with just one click on the "Upload" button.&lt;/p&gt;

&lt;p&gt;Readers often do not know what ARDUINO is and what it has to do with Microchip and AVR, so I will explain the basic differences between the three mentioned concepts. Microchip is a company that produces microcontrollers, but since there are a lot of microcontrollers, they are easiest to classify by architecture, so we have 8051, AVR, ARM, etc. Therefore, AVR is a microcontroller architecture and is produced only by Microchip. So, what about ARDUINO in that story? It is a completely new company that has made a development board and development environment for programming and has chosen an Microchip microcontroller with AVR architecture. ARDUINO is just a development environment and the name of the board, but don't be fooled, in the end, you are programming an Microchip AVR. People often ask me if ARDUINO can be programmed with Microchip development tools. Of course, it can, because on the board, there is nothing else but an Microchip microcontroller. That is why I will often use the term "Microchip company" and the term "AVR architecture", and I will call the development environment and the board "ARDUINO".&lt;/p&gt;

&lt;p&gt;Buying any ready-made development board forgets the chapter "Designing Hardware", which for the sake of general culture, I cannot skip. Regardless of the fact that colleagues from ARDUINO nicely drew the board and took care of important hardware details for us, before we start writing software, we simply must know the basic requirements for the proper operation of any microcontroller. I don't expect anyone to start drawing boards in the first steps, but I also know that it is impossible to say "I program microcontrollers" and not know the basic 3 hardware requirements. Therefore, in the next text, we must go through the hardware, and only after that, we can start writing the first programs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microcontroller Programming (1)</title>
      <dc:creator>jstivic</dc:creator>
      <pubDate>Sat, 06 May 2023 10:47:57 +0000</pubDate>
      <link>https://dev.to/jstivic/microcontroller-programming-1-41i0</link>
      <guid>https://dev.to/jstivic/microcontroller-programming-1-41i0</guid>
      <description>&lt;p&gt;Before we start learning anything, I must explain the reason why I decided to write this. When I first encountered microcontrollers, the internet did not exist, at least not in the small village near Slavonski Brod (Croatia) where I lived. Our English was at a zero level, and all the texts we could use as a reference were translations written only in books that we did not understand at all. Oh, how I wish I could give my knowledge and experience to myself some 15 years ago, but I cannot. I believe in the younger generation, the generations that have experienced a better school of today's technology. It is difficult to understand that my generation only met mobile phones and the internet in high school. Today, kids learn about them at the age of four. Times have drastically changed, and only new generations can keep up with new technology trends. My generation learned everything the hard way, no one could tell us where to go, we had to do everything ourselves. We did not even know if we were doing well, learning in the right direction, we were lost. Every new term was a new mystery for us, and the main reason for that was the fact that no one could properly instruct us, explain certain things that interested us at that time. Only in high school, in the nineties, did we start connecting to the internet and actively participating in electronics and programming forums. But even on the internet, we did not find answers to our mysterious questions. We asked questions on forums and received so many expert answers that we did not understand anything from them, and just when we thought we would connect the beginning and the end, someone would move the ends, and only then we would not understand anything. They often talked to us about concepts of different colors and shapes that did not mean anything to us. Today, after 15 years, I can understand the people who answered our questions. They were exactly today's "me", and if I really want to shake someone up with terms in order to show my own potential and experience to other readers, then I will respond with such a brutal text, full of professional terms, that only professionals can understand me. Even today, forums have not changed much. If I see a question on the forum "What is a microcontroller?", I will probably advise the guy to focus on cooking, agriculture, politics, or anything else. There is a reason why we answer like this on forums today, and the most important one is the fact that we cannot help him with just one text. We would need to write 100 pages of text to explain everything a beginner needs to know before becoming a somewhat decent programmer, and no experienced programmer has enough time or will for that.&lt;/p&gt;

&lt;p&gt;Programming microcontrollers is not just a job, I would rather say it's a certain love for technology. Curiosity is the most important characteristic of a good programmer, but along with it comes laziness and stubbornness. By combining these three traits over time, we become good programmers. We are stubborn because we can endlessly search for the solution to the same problem, lazy because we love thinking more than anything else while others think we are doing nothing, and curious because we want to know everything and no matter how much we learn, it is never enough. I cannot teach you how to program, I can only show you the path you need to take. If you decide to take the learning path, I must immediately warn you not to skip my texts because you will not understand anything in the future. I am experienced enough to know how to properly dose the truth and concepts that you need to know at a certain moment. I will disregard the experience and knowledge you have gained about programming because the world I am leading you to is completely different from standard programming instructions. Beginners often strive for quick results, and I must disappoint you there. Do not expect quick results, there won't be any. By seeking quick results, we miss out on the whole magic of programming and development, neglecting intellectual thinking tools that make us good programmers. I don't just want to teach you how to program, I want to teach you how to think, and that is the harder part of this story.&lt;/p&gt;

&lt;p&gt;Regardless of my current experience in development and programming, which has stretched for quite a few years, I somehow feel that nothing has changed. Answers to questions that I was looking for 15 years ago, I still cannot find anywhere today, no one writes about them. As I read a lot about programming, it seems to me that certain authors, with exceptions, are still stuck in the technology of their own time from as far back as 1957, and for years they speak like automatons from a lost era. Younger generations are the future, they accept new methods, adopt new knowledge, and open up to a new future. Because of them, I will write about what no one writes about, about the truth of programming that most authors sweep under the rug, presumably out of fear that beginners will not understand them. However, I must admit that beginner instructions over the years have brought me more harm than good, especially because they are not accurate. They teach us programming in a way that is not programming and create a "bug" in our minds that is difficult to correct in the future. So, sit comfortably, buckle up, and I hope that at least some of the readers through my texts will get to know the power of programming imagination. I say buckle up because by entering programming, whether we want to or not, we have to leave real-time and look into a completely new world of intellectual thinking.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
