{"id":19507,"date":"2023-11-30T20:40:17","date_gmt":"2023-11-30T20:40:17","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/?p=19507"},"modified":"2024-10-31T20:51:49","modified_gmt":"2024-10-31T20:51:49","slug":"arduino-nano-every-a-deep-dive","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive","title":{"rendered":"Arduino Nano Every &#8211; a deep dive"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this Post<\/h2>\n\n<p>If you are using an Arduino Nano or Arduino UNO R3 in a project and are reaching the limits of the SRAM or flash, the <a href=\"https:\/\/store.arduino.cc\/products\/arduino-nano-every?\" target=\"_blank\" rel=\"noopener\">Arduino Nano Every Board<\/a> could be a suitable alternative. If you limit yourself to the functions of the &#8220;Arduino language&#8221; and do not address any registers directly, you can transfer your sketches without any problems. On the surface, therefore, the differences are small.<\/p>\n<p>However, if you look deeper, you will see that the underlying ATmega4809 (<a href=\"https:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/ATmega4808-09-DataSheet-DS40002173C.pdf\" target=\"_blank\" rel=\"noopener\">data sheet ATmega4808\/4809<\/a>) as a member of the megaAVR\u00ae series differs significantly from the ATmega328P. And it is precisely this look &#8220;under the hood&#8221; that this article is about.<\/p>\n<p>In addition to the original Arduino Nano Every, I will also look at an interesting brother from China, which is based on the ATmega4808 and is known as the &#8220;Nano Thinary&#8221; or &#8220;Nano 4808&#8221;. The ATmega4808 is very similar to the ATmega4809. For this reason, the manufacturer Microchip has described both microcontrollers together in a <a href=\"https:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/ATmega4808-09-DataSheet-DS40002173C.pdf\" target=\"_blank\" rel=\"noopener\">data sheet<\/a>. And it also makes sense to cover both boards in one article.<\/p>\n<p>What topics I will cover:<\/p>\n<ul>\n<li><a href=\"#characteristics\">Features of the Arduino Nano Every \/ &#8220;Nano 4808&#8221;<\/a>\n<ul>\n<li><a href=\"#technical_data\">Technical data<\/a><\/li>\n<li><a href=\"#pinout\">Pinout<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#board_packages\">Board packages<\/a><\/li>\n<li><a href=\"#first_steps\">Getting Started<\/a><\/li>\n<li><a href=\"#reg_programming_in_c\">Register programming in C for the megaAVR\u00ae series<\/a><\/li>\n<li><a href=\"#portx_module\">I\/O Control &#8211; PORTx Module<\/a><\/li>\n<li><a href=\"#portmux_module\">Reassigning Inputs \/ Outputs &#8211; PORTMUX Module<\/a><\/li>\n<li><a href=\"#evsys_module\">The Event System &#8211; EVSYS Module<\/a><\/li>\n<li><a href=\"#timer\">The Timers of the Arduino Nano Every \/ &#8220;Nano 4808&#8221;<\/a><\/li>\n<li><a href=\"#timer_a\">Timer A &#8211; Module TCAn<\/a><\/li>\n<li><a href=\"#timer_b\">Timer B &#8211; TCBn Module<\/a><\/li>\n<li><a href=\"#rtc_module\">Real-Time Counter &#8211; RTC Module<\/a><\/li>\n<li><a href=\"#adc_module\">A\/D Converter &#8211; ADCn Module<\/a><\/li>\n<li><a href=\"#wdt_module\">Watchdog Timer &#8211; WDT Module<\/a><\/li>\n<li><a href=\"#ccl_module\">Configurable Custom Logic &#8211; CCL Module<\/a><\/li>\n<li><a href=\"#slpctrl_module\">The Arduino Nano Every goes to sleep &#8211; SLPCTRL Module<\/a><\/li>\n<\/ul>\n\n<h2 class=\"wp-block-heading\" id=\"characteristics\">Features of the Arduino Nano Every \/ &#8220;Nano 4808&#8221;<\/h2>\n\n<p>The available options of the boards and their limitations depend on three factors:<\/p>\n<ul>\n<li>the underlying microcontroller,<\/li>\n<li>the board architecture (especially which MCU pins are available as board pins)<\/li>\n<li>the board package used.&nbsp;<\/li>\n<\/ul>\n\n<h3 class=\"wp-block-heading\" id=\"technical_data\">Technical data of the boards<\/h3>\n\n<p>Here are some key data for the Arduino Nano Every board:<\/p>\n<ul>\n<li>Max. 20 MHz clock frequency (depending on the board package)<\/li>\n<li>Operating voltage: 5 Volt <ul>\n<li>VIN: 7- 21 volts<\/li>\n<\/ul>\n<\/li>\n<li>Max. Current per I\/O pin: 20 milliamps<\/li>\n<li>Flash: 48 KB<\/li>\n<li>SRAM: 6 KB<\/li>\n<li>EEPROM: 256 byte<\/li>\n<li>Interfaces: 1x SPI, 1x I2C, max. 4x USART (depending on the board package)<\/li>\n<li>I\/O pins: 22 (+2) <ul>\n<li>I&#8217;ll come to the &#8220;+2&#8221; later.<\/li>\n<\/ul>\n<\/li>\n<li>PWM pins: 5<\/li>\n<li>External interrupts on all I\/O pins<\/li>\n<li>event system&nbsp;<\/li>\n<li>Configurable Customer Logic<\/li>\n<li>1x 16-bit Timer A, 4x 16-bit Timer B<\/li>\n<\/ul>\n<p>The same applies to the &#8220;Nano 4808&#8221; (Nano Thinary), with the following exceptions:<\/p>\n<ul>\n<li>max. 3x USART<\/li>\n<li>PWM pins: 8<\/li>\n<li>I\/O pins: 25&nbsp; (+1)<\/li>\n<li>1x 16-bit Timer A, 3x 16-bit Timer B<\/li>\n<\/ul>\n\n<h3 class=\"wp-block-heading\">Sources of supply<\/h3>\n\n<p>You can get the Arduino Nano Every from the <a href=\"https:\/\/store.arduino.cc\/collections\/boards-modules\/products\/arduino-nano-every?_pos=11&amp;_fid=cf4be4029&amp;_ss=c\" target=\"_blank\" rel=\"noopener\">Arduino Store<\/a>. I paid \u20ac12.50 plus tax and shipping, which is relatively cheap for the original boards. For comparison: The Arduino Nano costs \u20ac20.50 in the Arduino Store (as of 10\/23).<\/p>\n<p>I found the &#8220;Nano 4808&#8221; for about \u20ac7.50 on AliExpress. But allow a few weeks for delivery, at least if you live in Europe.<\/p>\n\n<h3 class=\"wp-block-heading\" id=\"pinout\">Pinout<\/h3>\n\n<p>The Arduino Nano Every uses the 48-pin version of the ATmega4809, the &#8220;Nano 4808&#8221; is based on the 32-pin version of the ATmega4808:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-1024x541.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"541\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-1024x541.webp\" alt=\"The basis of the Nano Every \/ Nano 4808: 32-pin ATmega4808 and 48-pin ATmega4809\" class=\"wp-image-19142\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-1024x541.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-300x159.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-768x406.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC-1320x698.webp 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ATmega4808_4809_IC.webp 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">32-pin ATmega4808 and 48-pin ATmega4809<\/figcaption><\/figure>\n\n<p>Both microcontrollers belong to the megaAVR\u00ae0 series, which differs fundamentally from the &#8220;traditional&#8221; AVR\u00ae series. For example, programming is done via UPDI (Unified Program Debug Interface) and not as usual via ISP or using the Optiboot bootloader via the UART interface. This is why the boards discussed here do not have a USB-to-serial adapter, but a UPDI programmer. UPDI is a 1-wire interface that you may recognize from my article about the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/using-megatinycore\" target=\"_blank\" rel=\"noopener\">megaTinyCore<\/a> package from Spence Konde.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Pinout Arduino Nano Every<\/h4>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/03\/nano_every_pinout.webp\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/03\/nano_every_pinout-1024x473.webp\" alt=\"\" class=\"wp-image-20295\"\/><\/a><figcaption class=\"wp-element-caption\">Pinout Arduino Nano Every<\/figcaption><\/figure>\n\n<p>As you can see, the pins of the ATmega4809 are only partially available on the Arduino Nano Every Board. The rest is lost. In some cases, however, you can use PORTMUX to reassign the functions of non-available pins to existing pins.<\/p>\n<p>The pin designations and pin numbers (light blue \/ pink) essentially correspond to those of the ATmega328P-based Arduino Nano. However, there are some differences:<\/p>\n<ul>\n<li>A6 and A7 can be used as I\/O pins.<\/li>\n<li>A4 and A9 have two pin numbers, namely 18\/22 and 19\/23.<\/li>\n<li>AREF&#8217;s pin number is 39, but only when using the MegaCoreX package (therefore not mentioned in the pinout).<\/li>\n<\/ul>\n<p>The port pins <em>Pxy <\/em>on which the Arduino pins are based are entirely different from those of the Arduino Nano or Arduino UNO. Sketches that address the ports directly must be rewritten if you transfer them to the Arduino Nano Every.<\/p>\n<p>We will come to the other functions, such as TCA0-<em>x<\/em> or EVENT<em>y<\/em>, in the course of this article.<\/p>\n\n<h4 class=\"wp-block-heading\">Pinout &#8220;Nano 4808&#8221;<\/h4>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-1024x563.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"563\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-1024x563.webp\" alt=\"Pinout &quot;Nano 4808&quot; (Thinary)\" class=\"wp-image-19150\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-1024x563.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-300x165.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-768x422.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-1536x844.webp 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1-1320x725.webp 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_4808_pinout-1.webp 1995w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Pinout &#8220;Nano 4808&#8221; (Thinary)<\/figcaption><\/figure>\n\n<p>The pinout diagram of the &#8220;Nano 4808&#8221; differs from the Arduino Nano Every as follows:<\/p>\n<ul>\n<li>Pins 22 and 23 are separate, pin 24 is added.<\/li>\n<li>The PWM pins are assigned differently.<\/li>\n<li>A UPDI pin is available. You can therefore use a UPDI-capable programmer such as the Atmel ICE instead of the existing on-board programmer, provided the board package has implemented the programmer.<\/li>\n<li>The port pins on which the Arduino pins are based are different again.<\/li>\n<\/ul>\n\n<h2 class=\"wp-block-heading\" id=\"board_packages\">Board packages<\/h2>\n\n<p>I will not explain here in detail how to install board packages. Instructions can be found <a href=\"https:\/\/support.arduino.cc\/hc\/en-us\/articles\/360016466340-Add-or-remove-third-party-boards-in-Boards-Manager\" target=\"_blank\" rel=\"noopener\">here<\/a>, for example.<\/p>\n\n<h3 class=\"wp-block-heading\">Board packages for the Arduino Nano Every <\/h3>\n\n<p>The easiest way is to install the &#8220;Arduino megaAVR Boards&#8221; package, as you do not need to enter an additional board manager URL in the settings. After installation, select the Arduino Nano Every as the board and set the option &#8220;None (ATMEGA4809)&#8221; under Tools \u2192 &#8220;Registers emulation&#8221;.<\/p>\n<p>As an alternative, I recommend the <a href=\"https:\/\/github.com\/MCUdude\/MegaCoreX\" target=\"_blank\" rel=\"noopener\">MegaCoreX<\/a> package, as it contains libraries for many of the ATmega4809 functions that the standard package does not have. This is particularly useful for those who do not want to deal with registers. You can apply many more settings with this package, such as conveniently converting the reset pin into a normal I\/O pin or changing the clock rate. The documentation on GitHub is exemplary. You can find installation instructions <a href=\"https:\/\/github.com\/MCUdude\/MegaCoreX\/tree\/master#boards-manager-installation\" target=\"_blank\" rel=\"noopener\">here<\/a>. Don&#8217;t worry, it&#8217;s done in just a few minutes.<\/p>\n<p>After installation, make the following settings in the Tools menu:<\/p>\n<ul>\n<li>Board: MegaCoreX \u2192 ATmega4809<\/li>\n<li>Pinout: Nano 4809<\/li>\n<li>Programmer: JTAG2UPDI<\/li>\n<\/ul>\n\n<p>The rest is best left unchanged for now.<\/p>\n\n<h3 class=\"wp-block-heading\">Board packages for the &#8220;Nano 4808&#8221; (Thinary)<\/h3>\n\n<p>I tried two options for the &#8220;Nano 4808&#8221;. One of them was again the <a href=\"https:\/\/github.com\/MCUdude\/MegaCoreX\" target=\"_blank\" rel=\"noopener\">MegaCoreX<\/a> package, but I also tried the <a href=\"https:\/\/github.com\/Thinary\/ThinaryArduino\" target=\"_blank\" rel=\"noopener\">ThinaryArduino<\/a> package. Do yourself a favor and take the MegaCoreX package!<\/p>\n<p>I do not recommend the ThinaryArduino package, as it is apparently not really maintained. It works in principle, but has some special features:<\/p>\n<ul>\n<li>Serial must be replaced by Serial1.<\/li>\n<li><code>analogWrite()<\/code> is only available on pins A6 and A7.<\/li>\n<li>The documentation leaves a lot to be desired.<\/li>\n<\/ul>\n\n<h3 class=\"wp-block-heading\">Using Reset and AREF pins as GPIO<\/h3>\n\n<p>You can use the AREF pin as a GPIO without any further action. The only limitation: It has a higher capacitance than other pins and is therefore somewhat less responsive. The MegaCoreX package has assigned its own number for the pin, namely 39 for the Arduino Nano Every and 25 for the &#8220;Nano 4808&#8221;. When using the megaAVR package, you could use it directly via port manipulation (PD7).<\/p>\n<p>Since the ATmega4808\/4809 is flashed via UPDI, you do not need the reset pin to upload the sketches. The MegaCoreX allows you to set the pin as a GPIO via the Tools \u2192 Reset menu. But be careful: If you configure the pin as OUTPUT and press the reset button, you will create a short circuit!<\/p>\n<p>With the megaAVR package, you can apply this change in the boards.txt file. On my computer it is under: &#8220;C:\\Users\\Ewald\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\megaavr\\1.8.8&#8221;. Replace the following line in the file:<\/p>\n<p><code>nona4809.bootloader.SYSCFG0=0xC9<\/code> by:<\/p>\n<p><code> nona4809.bootloader.SYSCFG0=0xC1<\/code>.<\/p>\n<p>This clears the RSTPINCFG bit (no. 3) in the SYSCFG0 register as part of the next upload. As the register can only be written to via UPDI, you have to take the detour via boards.txt. But only go for it if you know exactly what you&#8217;re doing!<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"first_steps\">Getting Started<\/h2>\n\n<p>If you limit yourself to the Arduino functions, your sketches should work as usual. It all &#8220;feels like Arduino Nano&#8221;.<\/p>\n<p>This could be the end of this article. But there is still the exciting world of the megaAVR0 series to discover beneath the Arduino surface. Nevertheless, a little familiarization is required, even if you should already have experience with register programming of AVR microcontrollers. Here is a simple blink sketch as a taster (Arduino Nano Every):<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"blink_sketch.ino\" data-enlighter-title=\"blink_sketch.ino\">void setup() {\n    PORTE.DIRSET = PIN2_bm; \/\/ set PE2 (D13, LED_BUILTIN) to OUTPUT\n}\n   \nvoid loop() {\n    PORTE.OUTSET = PIN2_bm;  \/\/ set PE2 to HIGH \n    delay(200);\n    PORTE.OUTCLR = PIN2_bm;  \/\/ set PE2 to LOW\n    delay(200);\n}<\/pre>\n\n<p>For the &#8220;Nano 4808&#8221;, replace PORTE with PORTC to make the board LED flash.<\/p>\n<p>A statement like <code>PORTE |= (1&lt;&lt;PE2)<\/code> generates an error message that &#8220;PE2&#8221; is not defined.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"reg_programming_in_c\">Register programming in C for the megaAVR\u00ae series<\/h2>\n\n<p>I will now try to explain the register programming briefly. For more details, please refer to the application note <a href=\"https:\/\/ww1.microchip.com\/downloads\/en\/Appnotes\/AVR1000b-Getting-Started-Writing-C-Code-for-AVR-DS90003262B.pdf\" target=\"_blank\" rel=\"noopener\">TB3262<\/a> from Microchip. <\/p>\n<p>The register concept of the megaAVR series can also be found for the megaTiny\u00ae series. If you have worked through this article, you can also use your knowledge there.<\/p>\n\n<h4 class=\"wp-block-heading\">Register<\/h4>\n\n<p>The registers are organized as structures (data type struct), which you can see from the dot notation in the blink sketch. The name of the structure is the module, the registers are elements of this structure, e.g.<\/p>\n<ul>\n<li>PORTE.DIRSET: <ul>\n<li>Module: PORTE<\/li>\n<li>Register: DIRSET<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n<h4 class=\"wp-block-heading\">Bit Masks and Bit Group Configuration Masks<\/h4>\n\n<p>To understand bit masks and bit group configuration masks, let&#8217;s take a look at the Control A Register (CTRLA) of Timer B1 as an example. The module is called TCB. However, as the ATmega4809 has four identical Timer B (0, 1, 2, 3), the number is appended to the module name, in general term: &#8220;<strong>MODULNAMEn<\/strong>.REGISTERNAME&#8221;. The CTRLA register of Timer B1 is therefore called: TCB1.CTRLA.<\/p>\n<p>The TCBn.CTRLA registers contain various bits and the CLKSEL bit group:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"268\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCBn.CTRLA\" class=\"wp-image-19060\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-300x78.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-768x201.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example.png 1266w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCBn.CTRLA Register<\/figcaption><\/figure>\n\n<p>Bit masks are used to set single bits. Their names are formed according to the following scheme:<\/p>\n<ul>\n<li><strong>MODUL_BIT_bm<\/strong><\/li>\n<\/ul>\n<p>The module number is omitted. To set the ENABLE bit for Timer B1:<\/p>\n<p><code>TCB1.CTRLA |= TCB_ENABLE_bm;<\/code><\/p>\n<p>The bit group configuration masks are used for bit groups (also known as bit fields), the names of which are formed as follows:<\/p>\n<ul>\n<li><strong>MODUL_BITGRUPPE_CONFIGURATION_gc<\/strong><\/li>\n<\/ul>\n<p>As an example, we set the TCA clock as clock source for Timer B1:<\/p>\n<p><code>TCB1.CTRLA |= TCB_CLKSEL_CLKTCA_gc;<\/code><\/p>\n\n<p>CLKTCA corresponds to the CLKSEL value 0x2 or 0b10. In the register, CLKSEL is located at bit position 1 and 2, i.e. it is shifted 1 bit to the left. This is why the value of TCB_CLKSEL_CLKTCA_gc is 0x4 or 0b100.<\/p>\n<p>If you want to mask the bit group TCB_CLKSEL, you can use the bit group mask. Here in the general form:<\/p>\n<ul>\n<li><strong>MODUL_BITGRUPPE_gm<\/strong><\/li>\n<\/ul>\n<p>The value of TCB_CLKSEL_gm is 0x6 or 0b110, as you can easily check with <code>Serial.println(TCB_CLKSEL_gm, BIN)<\/code>.<\/p>\n\n<h4 class=\"wp-block-heading\">Bit Positions and Bit Group Positions<\/h4>\n\n<p>In addition, there are the bit and bit group positions:<\/p>\n<ul>\n<li><strong>MODUL_BIT_bp<\/strong><\/li>\n<li><strong>MODUL_BITGRUPPE_gp<\/strong><\/li>\n<\/ul>\n<p>Unsurprisingly, they indicate the position of the bit or bit group in the register. So if you want to determine the current CLKSEL value of timer TCB1, you could do it like this:<\/p>\n<p><code>Serial.println( ((TCB1.CTRLA&nbsp; &amp;&nbsp; TCB_CLKSEL_gm) &gt;&gt; TCB_CLKSEL_gp) );<\/code><\/p>\n\n<p>It may all sound a little complicated at first, but you soon get used to this type of notation. It involves a certain amount of writing, but it pays off because the code is still easy to understand even after a few months.<\/p>\n\n<p>If you want to see how the structures for the modules and registers are set up, then take a look at &#8220;C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr\\avr\\include\\avr\\iom4809.h&#8221; or &#8220;&#8230;iom4808.h&#8221;.<\/p>\n\n<h4 class=\"wp-block-heading\">Orientation in the Data Sheet <\/h4>\n\n<p>This new way of programming registers takes some getting used to at first. The ATmega4808\/4809 data sheet will help you find your way around. It is organized according to the modules and for each module there is a &#8220;Register Summary&#8221; with links to the individual registers.&nbsp;<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_portx-1.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1011\" height=\"464\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_portx-1.webp\" alt=\"tinyAVR Register Summary\" class=\"wp-image-19472\" style=\"width:659px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_portx-1.webp 1011w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_portx-1-300x138.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_portx-1-768x352.webp 768w\" sizes=\"auto, (max-width: 1011px) 100vw, 1011px\" \/><\/a><figcaption class=\"wp-element-caption\">PORTx Register Summary<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"portx_module\">I\/O Control &#8211; PORTx Module<\/h2>\n\n<h3 class=\"wp-block-heading\">PORTx Register <\/h3>\n\n<h4 class=\"wp-block-heading\">DIR, OUT and IN registers<\/h4>\n\n<p>As demonstrated by the register summary above, there are a number of registers whose names begin with &#8220;DIR&#8221; or &#8220;OUT&#8221;. The &#8220;DIR &#8230;&#8221; registers control which pins are used as INPUT or OUTPUT. With the help of the &#8220;OUT &#8230;&#8221; registers you set the pin level, i.e. HIGH or LOW. The second part of the name means:<\/p>\n<ul>\n<li>SET: sets bits in OUT and DIR \u2192 OUTPUT or HIGH<\/li>\n<li>CLR: clears bits in OUT and DIR \u2192 INPUT or LOW<\/li>\n<li>TGL: toggles the status.<\/li>\n<\/ul>\n<p>You can also write directly to the DIR and OUT registers, but the beauty of OUTSET, OUTCLR, OUTTGL and their &#8220;DIR&#8221; counterparts is that the instructions are pin-selective. Example:<\/p>\n<ul>\n<li><code>PORTx.OUT = PINy_bm;<\/code> sets pin y of port x to HIGH and all other pins of port x to LOW.<\/li>\n<li><code>PORTx.OUTSET = PINy_bm;<\/code> only acts on pin y, i.e. the statement corresponds to <code>PORTx.OUT |= PINy_bm;<\/code>.<\/li>\n<\/ul>\n<p>You can read the status of the pins from the IN registers (<code>digitalRead()<\/code>, so to speak). However, if you write a bit to the PORTx.IN register, the corresponding bit is toggled in PORTx.OUT. The IN register is the counterpart to the PINx register of traditional AVR microcontrollers. <\/p>\n\n<h4 class=\"wp-block-heading\">Control Register PINxCTRL <\/h4>\n\n<p>Each pin has its own control register, namely PINxCTRL:<\/p>\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL-1024x82.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"82\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL-1024x82.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register - PORTn.PINxCTRL\" class=\"wp-image-19308\" style=\"width:840px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL-1024x82.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL-300x24.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL-768x61.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_PORTx_PINx_CTRL.png 1239w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">PORTn.PINxCTRL Register<\/figcaption><\/figure>\n\n<p>The INVEN bit allows you to invert the INPUT and OUTPUT values. PULLUPEN activates the internal pull-up resistor. With ISC you can define the interrupt conditions or switch off the digital function of the pin completely (INPUT_DISABLE):<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/PINxCTRL_ISC_table.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"987\" height=\"310\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/PINxCTRL_ISC_table.webp\" alt=\"ISC[2:0] Bit Group Configurations\" class=\"wp-image-19306\" style=\"width:599px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/PINxCTRL_ISC_table.webp 987w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/PINxCTRL_ISC_table-300x94.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/PINxCTRL_ISC_table-768x241.webp 768w\" sizes=\"auto, (max-width: 987px) 100vw, 987px\" \/><\/a><figcaption class=\"wp-element-caption\">ISC[2:0] Bit Group Configuration<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">Example Sketches for PORTx<\/h3>\n\n<h4 class=\"wp-block-heading\">Switching Pins<\/h4>\n\n<p>I&#8217;ll come back to the blink sketch and show that there are other ways to achieve the same effect:<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"blink_sketch_alternatives.ino\" data-enlighter-title=\"blink_sketch_alternatives.ino\">void setup() {\n    PORTE.DIRSET = PIN2_bm; \/\/ set PE2 (D13) to OUTPUT\n    \/\/ PORTE.DIR |= (1&lt;&lt;2);\n    \/\/ PORTE.DIR |= (1&lt;&lt;PIN2_bp); \/\/ bp = bit position\n}\n\nvoid loop() {\n    PORTE.OUTSET = PIN2_bm;  \/\/ set PE2 to HIGH\n    \/\/ PORTE.OUT |= PIN2_bm;\n    delay(200);\n    PORTE.OUTCLR = PIN2_bm;\n    \/\/ PORTE.OUT &amp;= ~PIN2_bm; \n    delay(200);\n   \n    \/\/ Alternative: toggle pin:\n    \/\/ PORTE.OUTTGL = PIN2_bm;\n    \/\/ delay(200);  \n}<\/pre>\n\n<p>I think the alternatives are fairly self-explanatory. And as already mentioned, to adapt the code to a &#8220;Nano 4808&#8221;, swap PORTE for PORTC.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Reading Pin Levels <\/h4>\n\n<p>Here is an example of how you can read the level of individual pins:<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"digital_read_from_port.ino\" data-enlighter-title=\"digital_read_from_port.ino\">void setup() {\n    Serial.begin(115200);\n    PORTB.DIRCLR = PIN2_bm; \/\/ PB2 = D5 (for the Nano4808 select a different pin)\n}\n\nvoid loop(){\n    if(PORTB.IN &amp; PIN2_bm){\n        Serial.println(\"HIGH\");\n    }\n    else{\n        Serial.println(\"LOW\");\n    }\n    delay(1000);\n}<\/pre>\n\n<h4 class=\"wp-block-heading\">Setting up Interrupts<\/h4>\n\n<p>The following is a simple example of an external interrupt at PB2 (=D5 on the Nano Every).&nbsp; Note that the interrupt is not automatically cleared by calling the ISR. You must &#8220;manually&#8221; clear the bit in the relevant interrupt flag register.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"external_pin_interrupt.ino\" data-enlighter-title=\"external_pin_interrupt.ino\">volatile bool event = false;\n\nISR(PORTB_PORT_vect){\n    PORTB.INTFLAGS = PIN2_bm; \/\/ clear interrupt\n    event = true;\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    PORTB.DIRCLR = PIN2_bm;  \/\/ redundant in this case\n    PORTB.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc; \n}\n\nvoid loop(){\n    if(event){\n        Serial.println(\"Interrupt!\");\n        event = false;\n    }\n}<\/pre>\n\n<h4 class=\"wp-block-heading\">Virtual Ports<\/h4>\n\n<p>If you use port manipulation like <code>PORTB.OUT = (1 &lt;&lt; 2);<\/code>, you should use the virtual port registers instead of the port registers. To do this, simply place a &#8220;V&#8221; before PORTx, i.e.: <code>VPORTB.OUT = (1 &lt;&lt; 2);<\/code>. The virtual ports are copies of the ports in the lower address space. Port manipulations are performed faster with virtual ports. It took 629 milliseconds to execute the following code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">for(unsigned long i=0; i&lt;1000000;i++){\n        PORTE.OUT = 0;\n        PORTE.OUT = (1&lt;&lt;2);\n}<\/pre>\n\n<p>The same code, only with VPORTE instead of PORTE took 503 milliseconds. These are not major differences, but they are differences nonetheless.<\/p>\n<p>The VPORT registers available are DIR, OUT, IN and INTFLAGS.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"portmux_module\">Reassigning Inputs \/ Outputs &#8211; PORTMUX Module<\/h2>\n\n<p>The registers of the PORTMUX module allow you to assign a series of inputs and outputs to alternative pins. Here is the register summary:<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_PORTMUX.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1016\" height=\"206\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_PORTMUX.png\" alt=\"Register Summary PORTMUX\" class=\"wp-image-19393\" style=\"width:799px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_PORTMUX.png 1016w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_PORTMUX-300x61.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_PORTMUX-768x156.png 768w\" sizes=\"auto, (max-width: 1016px) 100vw, 1016px\" \/><\/a><figcaption class=\"wp-element-caption\">Register Summary PORTMUX<\/figcaption><\/figure>\n\n<p>As an example, we redirect the Timer A outputs. The relevant PORTMUX register is TCAROUTEA. The bit group configuration mask for TCA0[2:0] is PORTn with n = A to F. You would therefore assign the Timer A output pins to Port B in this way:<\/p>\n<ul>\n<li><code>PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTB_gc;<\/code><\/li>\n<\/ul>\n<p>And this is exactly what is implemented on the Arduino Nano Every, both with the megaAVR and the MegaCoreX package. On the &#8220;Nano 4808&#8221;, the Timer A outputs are redirected to Port D.<\/p>\n\n<p>If you want to redirect other inputs or outputs, you only need to search for the corresponding bit masks or bit group configuration masks.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"evsys_module\">The Event System &#8211; EVSYS Module<\/h2>\n\n<p>The event system is really cool! It allows the peripherals, i.e. timers, ADC, USART, etc., to send signals to other peripherals without involving the CPU. Later, I will show you an example of how a timer can regularly trigger ADC measurements. Normally, you would realize this via <code>delay()<\/code>, <code>millis()<\/code> or interrupts. All these options take a certain amount of time and can make the code complex.<\/p>\n<p>8 channels (Channel0 to Channel7) are available for transmitting the signals. The sender of the signal is called the generator, the receiver is the user. Most users have their own event control register in which further settings can be made. These registers are part of the peripheral modules.<\/p>\n\n<h3 class=\"wp-block-heading\">EVSYS Register<\/h3>\n\n<h4 class=\"wp-block-heading\">CHANNELn Register &#8211; Definition of the Generator <\/h4>\n\n<p>In the CHANNELn registers (with n = 0 to 7) you define the generator:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn-1024x85.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"85\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn-1024x85.webp\" alt=\"Arduino Nano Every \/ Nano 4808 Register: CHANNELn\" class=\"wp-image-19167\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn-1024x85.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn-300x25.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn-768x64.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_CHANNELn.webp 1262w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register EVSYS.CHANNELs<\/figcaption><\/figure>\n\n<p>Most generators can utilise all channels. But there are also exceptions. For example, the pins of Port A can only use channels 0 and 1. Here is a small extract from the table in the data sheet (section 14.5.2):<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1293\" height=\"235\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators.webp\" alt=\"Event generators of the Arduino Nano Every \/ Nano 4808 - some examples\" class=\"wp-image-19169\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators.webp 1293w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators-300x55.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators-1024x186.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_generators-768x140.webp 768w\" sizes=\"auto, (max-width: 1293px) 100vw, 1293px\" \/><\/a><figcaption class=\"wp-element-caption\">Event Generators &#8211; some Examples<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Register USERn &#8211; Definition of Users<\/h4>\n\n<p>You define the event users in the USERn tab:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER-1024x88.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"88\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER-1024x88.webp\" alt=\"Register EVSYS.USERn\" class=\"wp-image-19165\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER-1024x88.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER-300x26.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER-768x66.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_EVSYS_USER.webp 1209w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register EVSYS.USERn<\/figcaption><\/figure>\n\n<p>Replace the &#8220;n&#8221; in USERn with the name of the user. The complete table can be found in the data sheet in section 14.3.2.4. Here is a snippet:<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_users.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"955\" height=\"341\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_users.webp\" alt=\"Event user\" class=\"wp-image-19171\" style=\"width:639px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_users.webp 955w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_users-300x107.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/EVSYS_users-768x274.webp 768w\" sizes=\"auto, (max-width: 955px) 100vw, 955px\" \/><\/a><figcaption class=\"wp-element-caption\">Event users &#8211; some examples <\/figcaption><\/figure>\n<\/div>\n<h3 class=\"wp-block-heading\">A simple Event System Example<\/h3>\n\n<p>For a better understanding, let&#8217;s take a look at a small example. For the Arduino Nano Every, connect a button to PB0 (D9) that pulls the pin to LOW when pressed. Connect a suitable LED to PB2 (D5).<\/p>\n<p>Now we use the PB0 as event generator and EVOUTB (PB2 \/ D5) as event user. Channels 0 and 1 are available for Port B. In the example, we use Channel 0.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"simple_event.ino\" data-enlighter-title=\"simple_event.ino\">void setup() {\n&nbsp; &nbsp; PORTB.DIRSET = PIN2_bm; \/\/ PB2 (D5) as OUTPUT\n&nbsp; &nbsp; PORTB.DIRCLR = PIN0_bm; \/\/ PB0 (D9) as INPUT\n&nbsp; &nbsp; PORTB.PIN0CTRL = PORT_PULLUPEN_bm;\n&nbsp; &nbsp;\n&nbsp; &nbsp; EVSYS.CHANNEL0 = EVSYS_GENERATOR_PORT1_PIN0_gc;  \/\/ PB0 is event generator for channel 0\n&nbsp; &nbsp; EVSYS.USEREVOUTB = EVSYS_CHANNEL_CHANNEL0_gc;  \/\/ EVOUTB is user of event channel 0\n}\n\nvoid loop(){}<\/pre>\n\n<p>PB5, or EVOUTB, reflects the status of PB0. The LED lights up in the normal state and switches off when the button is pressed. This may not be impressive at first glance, but at second glance it is. We do not query the level of PB0, nor have we set up an external interrupt for this purpose. In addition, there are no instructions for switching the LED in the running program. The processes are all controlled in the background without your running program having to do anything. More useful applications will follow later.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Variant for the &#8220;Nano 4808&#8221;<\/h4>\n\n<p>Rewriting the sketch for the &#8220;Nano 4808&#8221; is not difficult. This would be an option:<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"simple_event_nano_4808.ino\" data-enlighter-title=\"simple_event_nano_4808.ino\">void setup() {\n    PORTA.DIRSET = PIN2_bm; \/\/ PA2 (D4)\n    PORTA.DIRCLR = PIN0_bm;  \/\/ PA0 (D2)\n    PORTA.PIN0CTRL = PORT_PULLUPEN_bm;\n        \n    EVSYS.CHANNEL0 = EVSYS_GENERATOR_PORT0_PIN0_gc; \n    EVSYS.USEREVOUTA = EVSYS_CHANNEL_CHANNEL0_gc;\n}\n\nvoid loop(){}<\/pre>\n\n<h2 class=\"wp-block-heading\" id=\"timer\">The Timers of the Arduino Nano Every \/ &#8220;Nano 4808&#8221;<\/h2>\n\n<p>The ATmega4809 has:<\/p>\n<ul>\n<li>One 16-bit Timer A (TCA0)<\/li>\n<li>four 16-bit Timers B (TCB0, TCB1, TCB2, TCB3),<\/li>\n<li>a Real-Time Counter (RTC),<\/li>\n<li>a Periodic Interrupt Timer (PIT),<\/li>\n<li>and a Watchdog Timer (WDT).<\/li>\n<\/ul>\n<p>The ATmega4808 differs only in that it has three Timer B.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"timer_a\">Timer A &#8211; Module TCAn<\/h2>\n\n<p>First, a few general comments on Timer A:<\/p>\n<ol>\n<li>The system clock is the clock source for Timer A, but it can be slowed down with a divider you set in register TCA0.SINGLE.CTRLA.<\/li>\n<li>The megaAVR board package sets the divider of Timer A to 64 and uses the Timer A clock for Timer B. Timer B3 is in turn responsible for time-dependent functions such as <code>millis()<\/code> or <code>delay()<\/code>. <strong>You should therefore not change the divider if you are using the Arduino megaAVR package.<\/strong> The Timer A clock is thus set to 16000000 MHz \/ 64 = 250 kHz. The MegaCoreX package also uses Timer B3 (or B2 for the &#8220;Nano 4808&#8221;) for <code>delay()<\/code> and <code>millis()<\/code>. However, Timer B3 uses the system clock, so you can adjust the Timer A divider without side effects on Timer B.<\/li>\n<li>In Normal (single) Mode, Timer A counts up to the maximum value PER. Three compare channels are available. The compare values are called CMP0, CMP1 and CMP2.<\/li>\n<li>In split mode, the 16-bit timer turns into two 8-bit timers with 3 compare values each.<\/li>\n<li>You address the registers for the Normal Mode with TCA0.SINGLE.<em>Registername<\/em>, and the registers for Split Mode with TCA0.SPLIT.<em>Registername<\/em>.<\/li>\n<li>By default, the outputs for Timer A are assigned to Port B on the Arduino Nano Every. Assignment to other ports is possible, but this redirection always applies to all output pins. Pin 0 is responsible for Channel 0 (TCA0-0), pin 1 for Channel 1 (TCA0-1) and pin 2 for Channel 2 (TCA0-2). In Split Mode, this scheme continues accordingly with Pin 3 for Channel 3 (TCA0-3), etc. On the &#8220;Nano 4808&#8221;, the Timer A outputs are assigned to Port D.<\/li>\n<\/ol>\n\n<h3 class=\"wp-block-heading\">Timer A Registers for Normal (Single) Mode<\/h3>\n\n<p>Some registers are identical in Normal and Split Mode. I have noted this accordingly.<\/p>\n<p>This article is not a complete register documentation. I recommend that you also take a look at the data sheet when reading this article.<\/p>\n\n<h4 class=\"wp-block-heading\">Control A Register TCAn.CTRLA<\/h4>\n\n<p>In the control register CTRLA you set the clock divider and enable Timer Counter A.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA-1024x82.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"82\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA-1024x82.png\" alt=\"TCAn.CTRLA Register\" class=\"wp-image-19072\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA-1024x82.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA-300x24.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA-768x62.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLA.png 1273w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCAn.CTRLA Register<\/figcaption><\/figure>\n\n<p>The CLKSEL (Clock Select) bit group defines the divider. The following bit group configuration masks are available for selection:<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_CLKSEL_options.png\"><img loading=\"lazy\" decoding=\"async\" width=\"702\" height=\"329\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_CLKSEL_options.png\" alt=\"Arduino Nano Every: CLKSEL options for TCA0 in Normal Mode\" class=\"wp-image-19087\" style=\"aspect-ratio:2.127659574468085;object-fit:cover;width:496px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_CLKSEL_options.png 702w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_CLKSEL_options-300x141.png 300w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><\/a><figcaption class=\"wp-element-caption\">CLKSEL &#8211; Options<\/figcaption><\/figure>\n<\/div>\n<p>Use the ENABLE bit to enable TCA0. You can check the setting of CTRLA with <code>Serial.println(TCA0.SINGLE.CTRLA)<\/code>. The output should be 0b1011, i.e. the timer is enabled, and the divider is 64, so you do not need to enable the timer yourself. And once again: When using the megaAVR package, you should not change this setting.<\/p>\n\n<h4 class=\"wp-block-heading\">Control B Register TCAn.CTRLB<\/h4>\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"83\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLB-1024x83.png\" alt=\"TCAn.CTRLB Register\" class=\"wp-image-19074\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLB-1024x83.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLB-300x24.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLB-768x62.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLB.png 1236w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">TCAn.CTRLB Register<\/figcaption><\/figure>\n\n<p>Setting the Compare n Enable Bits (CMPnEN) enables the Compare Channel outputs. I will not go into the Auto Lock Update Bit (ALUPD) here. The bit group WGMODE[2:0] defines the Wave Form Generation Mode:<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1106\" height=\"352\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_WGMODES.png\" alt=\"Arduino Nano Every: WGMODE options for TCA0 in Normal Mode\" class=\"wp-image-19093\" style=\"aspect-ratio:3.1578947368421053;object-fit:cover;width:722px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_WGMODES.png 1106w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_WGMODES-300x95.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_WGMODES-1024x326.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_WGMODES-768x244.png 768w\" sizes=\"auto, (max-width: 1106px) 100vw, 1106px\" \/><figcaption class=\"wp-element-caption\">Wave Form Generation Mode Options<\/figcaption><\/figure>\n<\/div>\n<p>Take it as it is for now, it will become clearer later.<\/p>\n\n<h4 class=\"wp-block-heading\">Control D Register TCAn.CTRLD<\/h4>\n\n<p>The Split Mode is set in the Control D register. It is not relevant whether you make the setting via TCA0.SINGLE.CTRLD or TCA0.SPLIT.CTRLD.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD-1024x78.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"78\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD-1024x78.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCAn.SINGLE.CRTLD\" class=\"wp-image-19078\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD-1024x78.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD-300x23.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD-768x58.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_CTRLD.png 1249w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register TCAn.SINGLE.CTRLD \/ TCAn.SPLIT.CTRLD<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Interrupt Control Register TCAn.INTCTRL<\/h4>\n\n<p>In the Interrupt Control Register, you set which interrupts are to be activated. Interrupts are available for compare matches and overflow:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL-1024x79.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"79\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL-1024x79.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCAn.SINGLE.INTCTRL \/ TCAn.SINGLE.INTFLAGS\" class=\"wp-image-19076\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL-1024x79.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL-300x23.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL-768x60.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/Reg_TCA_INTCTRL.png 1251w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCAn.SINGLE.INTCTRL \/ TCAn.SINGLE.INTFLAGS<\/figcaption><\/figure>\n\n<p>The Interrupt Flag Register INTFLAGS is similar to INTCTRL and uses the same bit names and positions.<\/p>\n\n<h4 class=\"wp-block-heading\">Event Control Register TCAn.EVCTRL<\/h4>\n\n<p>You can set Timer A so that it is not controlled by the system clock but by external events. To do this, set the &#8220;Enable Count On Event Input&#8221; bit CNTEI in the Event Control Register EVCTRL.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL-1024x89.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"89\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL-1024x89.webp\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCAn.SINGLE.EVCTRL\" class=\"wp-image-19221\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL-1024x89.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL-300x26.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL-768x66.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_EVCTRL.webp 1259w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCAn.SINGLE.EVCTRL<\/figcaption><\/figure>\n\n<p>Use the Bit Group Configuration EVACT to select which events are counted and how they are counted:<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1148\" height=\"263\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_EVCTRL_EVACT_table.webp\" alt=\"EVACT Bit Group Configurations\" class=\"wp-image-19214\" style=\"width:746px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_EVCTRL_EVACT_table.webp 1148w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_EVCTRL_EVACT_table-300x69.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_EVCTRL_EVACT_table-1024x235.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCA0_EVCTRL_EVACT_table-768x176.webp 768w\" sizes=\"auto, (max-width: 1148px) 100vw, 1148px\" \/><figcaption class=\"wp-element-caption\">EVACT Bit Group Configurations<\/figcaption><\/figure>\n\n<p>With the first two settings, you count the edges, i.e. the number of events. With the other two settings, the system clock (with divider if necessary) is used to count for as long as the state caused by the event lasts.<\/p>\n\n<h4 class=\"wp-block-heading\">Further registers<\/h4>\n\n<p>Then there are a number of other registers that only contain numbers:<\/p>\n<ul>\n<li><strong>CNT<\/strong> (16 bit): is the counter register for timer A.<\/li>\n<li><strong>PER<\/strong> (16 bit): is the TOP value for most wave form generation modes.<\/li>\n<li><strong>CMP0<\/strong>, <strong>CMP1<\/strong>, <strong>CMP2<\/strong> (16 bit): contain the compare values.<\/li>\n<li><strong>PERBUF<\/strong>: you can write PER directly to the PER register. This can lead to undefined states if PER is changed in the middle of a PWM period, for example. When transferring from PERBUF to PER, the system waits until the current PER value is reached.  So this route is safer.<\/li>\n<li><strong>CMP0BUF<\/strong>, <strong>CMP1BUF<\/strong>, <strong>CMP2BUF<\/strong>: see PERBUF.<\/li>\n<\/ul>\n\n<p>In normal (single) mode, Timer A counter has a size of 16 bits. However, it can also be split into two 8-bit timers (Split Mode). In Normal Mode there are three Compare Channels available, in Split Mode there are six. Accordingly, Timer A can be used to provide 3 or 6 PWM outputs.&nbsp;<\/p>\n<p>The board packages for the Arduino Nano Every discussed here assign the Timer A outputs to PORTB and use them for <code>analogWrite()<\/code>. As only PB0 (pin 9), PB1 (pin 10) and PB2 (pin 5) are available as board pins, there are only these three <code>analogWrite()<\/code> pins that are controlled by Timer A.<\/p>\n<p>The MegaCoreX board package assigns the Timer A to Port D when using the &#8220;Nano 4808&#8221;. As PD0 to PD5 are all brought out as board pins and Split Mode is activated, six PWM pins are available (through Timer A).<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketches for Timer A in Normal Mode<\/h3>\n\n<p>After all the theory, let&#8217;s have some example sketches.<\/p>\n\n<h4 class=\"wp-block-heading\">Overflow Interrupt<\/h4>\n\n<p>We start quite simply with an overflow interrupt. We use this to toggle the board LED of the Arduino Nano Every.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_a_simple_ovf_interrupt.ino\" data-enlighter-title=\"timer_a_simple_ovf_interrupt.ino\">ISR(TCA0_OVF_vect){  \/\/ ISR f\u00fcr den Timer A over\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; \/\/ Clear the interrupt flag (needed!)\n    PORTE.OUTTGL = PIN2_bm; \/\/ Toggle PE2 (Board-LED) \n}\n\nvoid setup() {\n    PORTE.DIRSET = PIN2_bm; \/\/ PE2 auf OUTPUT\n    \/\/ TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV64_gc | TCA_SINGLE_ENABLE_bm; \/\/ redundant\n    \/\/ TCA0.SINGLE.CTRLB = 0; \/\/ no output, wave form: normal; redundant\n    TCA0.SINGLE.PERBUF = 49999; \/\/ Set TOP for Timer A \n    TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm; \/\/ enable Timer A overflow interrupt\n}\n\nvoid loop() {}<\/pre>\n\n<p>With a clock rate of 16 MHz, a divider of 64 and a PER of 49999 (= 50000 steps), the overflow frequency is 16000000 \/ 64 \/ 50000 = 5 Hz.<\/p>\n<p>If you want to use the sketch on the &#8220;Nano 4808&#8221;, simply replace PORTE with PORTC.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Single Slope PWM<\/h4>\n\n<p>In the next example, we use the Arduino Nano Every to generate a PWM signal with a frequency of 250 Hz and a duty cycle of 20 % at PB1 \/ D10. We achieve a frequency of 250 Hz by setting PER to 999 (at 16 MHz). PB1 is the output of compare Channel 1, so we have to set the CMP1EN bit accordingly. The duty cycle is CMPn \/ (PER +1).<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_a_single_slope_pwm.ino\" data-enlighter-title=\"timer_a_single_slope_pwm.ino\">void setup() {\n    PORTB.DIRSET = PIN1_bm;  \/\/ PB1 (D10)\n    TCA0.SINGLE.CTRLD &amp;= ~TCA_SINGLE_SPLITM_bm; \/\/ needed for the MegaCoreX board package\n    TCA0.SINGLE.PERBUF = 999;\n    TCA0.SINGLE.CMP1BUF = 200;\n    TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;\n}\n\nvoid loop() {}<\/pre>\n\n<p>To translate the sketch for use on the &#8220;Nano 4808&#8221; board, replace Port B with D. You will obtain the PWM signal on pin A1. If you are not sure why this is the case, take another look at the pinout diagrams.<\/p>\n<p>Please note that the MegaCoreX package has Split Mode activated by default. You must therefore deactivate it. I&#8217;ll come back to that shortly.<\/p>\n\n<h4 class=\"wp-block-heading\">Counting Events<\/h4>\n\n<p>In this example for the Arduino Nano Every, we control Timer A via events. A rising edge at PB1 (pin 10) serves as an event. To do this, connect PB1 to GND via a push-button. PB1 is pulled to HIGH by its internal pull-up resistor. The event is therefore generated when the button is released. You can also invert the logic, but then you will need an additional external pull-down resistor.<\/p>\n<p>The following sketch informs us when the button has been pressed 10 or 20 times:<\/p>\n\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_a_single_event_count.ino\" data-enlighter-title=\"timer_a_single_event_count.ino\">volatile bool tca0Ovf = false;  \/\/ Flag f\u00fcr TCA OVF\nvolatile bool cmp0Match = false;  \/\/ Flag f\u00fcr CMP0 Match\n\nISR(TCA0_OVF_vect){\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; \/* Clear the interrupt flag *\/\n    tca0Ovf = true;\n}\n\nISR(TCA0_CMP0_vect){\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm; \/* Clear the interrupt flag *\/\n    cmp0Match = true;\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    PORTB.DIRCLR = PIN1_bm; \/\/ PB1 (Pin 10) as input \n    PORTB.PIN1CTRL = PORT_PULLUPEN_bm; \/\/ Pullup enable\n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc; \/\/ PB1 as event generator\n    EVSYS.USERTCA0 = EVSYS_CHANNEL_CHANNEL1_gc;  \/\/ TCA0 as event user\n    TCA0.SINGLE.CTRLD &amp;= ~TCA_SINGLE_SPLITM_bm;  \/\/ Set single mode\n    TCA0.SINGLE.CTRLA = 0;  \/\/ switch off the timer, set clock divider to DIV1 \n    TCA0.SINGLE.PER = 19;  \/\/ TCA0 counter limit\n    TCA0.SINGLE.CMP0 = 9;  \/\/ Compare match value\n    TCA0.SINGLE.CNT = 0;  \/\/ Set TCA0 counter to 0\n    TCA0.SINGLE.EVCTRL = TCA_SINGLE_EVACT_POSEDGE_gc | TCA_SINGLE_CNTEI_bm; \/\/ count pos. edge of events (RISING) &amp; enable event count\n    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc; \/\/ normal mode =&gt; TOP = PER\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; \/\/ clear the overflow interrupt flag\n    TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP0_bm | TCA_SINGLE_OVF_bm; \/\/ enable CMP0 and OVF interrupts \n    TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm;\n}\n\nvoid loop(){\n    if(cmp0Match){\n        Serial.println(\"Key has been pressed 10 times\");\n        cmp0Match = false;\n    }\n    \n    if(tca0Ovf){\n        Serial.println(\"Key has been pressed another 10 times\");\n        Serial.println(\"Timer\/Counter A restarts\");\n        tca0Ovf = false;\n    }\n    \/\/ Serial.println(TCA0.SINGLE.CNT);\n    \/\/ delay(100); \/\/ delay won't work with the Arduino board package!\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n\n<p>I have tried to explain the code in the comments. I hope that is sufficiently understandable. However, a few annotations are still necessary:<\/p>\n<ul>\n<li>Split Mode is preset in the MegaCoreX package. We therefore delete the SPLITM bit in CTRLD.<\/li>\n<li>We switch off Timer A so that it does not disturb us during the settings.<\/li>\n<li>We are informed via Compare 0 Interrupt and Overflow Interrupt when the button has been pressed ten or twenty times. <ul>\n<li>The interrupts are only triggered when CMP0 and PER are <em>exceeded<\/em>. This is why CMP0 is 9 and PER is 19.<\/li>\n<\/ul>\n<\/li>\n<li>Setting the Compare 0 register and the PER register via the buffer registers (CMP0BUF, PERBUF) does not work here, as the new PER value is only updated once the old PER value has been reached. In the worst case, you would have to press the button 2<sup>16<\/sup> times until this is the case. <\/li>\n<li>If you use the megaAVR package, <code>delay()<\/code> will no longer work for the reasons already mentioned several times. MegaCoreX does not have this problem.<\/li>\n<\/ul>\n<p>To adapt the sketch for the &#8220;Nano 4808&#8221;, you could replace PB1 by PA1 (pin 3) and then change the event generator to EVSYS_GENERATOR_PORT<em><strong>0<\/strong><\/em>_PIN1_gc.<\/p>\n\n<h3 class=\"wp-block-heading\">Timer A register in Split Mode<\/h3>\n\n<p>In Split Mode, Timer A is divided into a high and a low section. Accordingly, there is an 8-bit HCNT and an 8-bit LCNT register instead of the 16-bit CNT register. These two counter registers count independently of each other. The PER register and the compare registers are also split. PER turns into HPER and LPER, CMPn turns into HCMPn and LCMP and so on.<\/p>\n\n<p>The outputs for Timer A in Split Mode are activated in the Control B register (TCA0.SPLIT.CTRLB):<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1-1024x86.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"86\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1-1024x86.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCAn.SPLIT.CTRLB\" class=\"wp-image-19113\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1-1024x86.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1-300x25.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1-768x65.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_CTRLB_SPLIT-1.png 1238w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register TCAn.SPLIT.CTRLB<\/figcaption><\/figure>\n\n<p>The LCMPnEN bits are responsible for the TCA0-n outputs, the HCMPnEN bits for the TCA0-(n+2) outputs.<\/p>\n\n<p>You can set interrupts for the low Compare Channels in the Control D register. No interrupts are available for the high Compare Channels.<\/p>\n<p>In Split Mode, the HCNT and LCNT registers count downwards. Accordingly, there are no overflow interrupts, but underflow interrupts (&#8220;UNF&#8221;). The bits for activating the interrupts are HUNF and LUNF.<\/p>\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"87\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_INTCTRL_SPLIT-1024x87.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCAn.SPLIT.CTRLB\" class=\"wp-image-19111\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_INTCTRL_SPLIT-1024x87.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_INTCTRL_SPLIT-300x26.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_INTCTRL_SPLIT-768x65.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCA_INTCTRL_SPLIT.png 1258w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Register TCAn.SPLIT.CTRLB<\/figcaption><\/figure>\n\n<p>The corresponding names of the interrupt vectors are formed according to the scheme <em>TCA0_Interruptbit_vector<\/em>, e.g. TCA0_LCMP1_vector.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketches for Timer A in Split Mode<\/h3>\n\n<h4 class=\"wp-block-heading\">Split Mode Timer A &#8211; Arduino Nano Every<\/h4>\n\n<p>Then we try Timer A in Split Mode and start with the Arduino Nano Every. The aim is to generate a PWM signal with a duty cycle of 25 % at PB0 (TCA0-0). The low counter of Compare Channel 0 is responsible for this.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_a_split_mode_pwm.ino\" data-enlighter-title=\"timer_a_split_mode_pwm.ino\">void setup() {\n    PORTB.DIRSET = PIN0_bm;  \/\/ PB0 (D9 = Output)\n    TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm; \/\/ needed for the Arduino board package\n    TCA0.SPLIT.LPER = 255;\n    TCA0.SPLIT.LCMP0 = 64; \/\/ Duty cycle = 64 \/ (255 + 1) * 100 = 25&nbsp;%\n    TCA0.SPLIT.CTRLB = TCA_SPLIT_LCMP0EN_bm;\n}\n\nvoid loop() {}\n\n<\/pre>\n\n<p>As PB3, PB4 and PB5 are not available as board pins, you can only use LCNT for PWM, unless you assign the TCA0 outputs to another port with <code>PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTn_gc;<\/code>.<\/p>\n\n<h4 class=\"wp-block-heading\">Split Mode Timer A &#8211; &#8220;Nano 4808&#8221;<\/h4>\n\n<p>The MegaCoreX package for the &#8220;Nano 4808&#8221; assigns the TCA0 outputs to Port D. Here we can directly use all six PWM channels of Timer A in Split Mode. Here is an example of a PWM signal at PD4 (TCA0-4 = D22):<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_a_4808_split_mode_pwm.ino\" data-enlighter-title=\"timer_a_4808_split_mode_pwm.ino\">void setup() {\n    PORTD.DIRSET = PIN4_bm;  \/\/ PD4 (D22 = Output)\n    \/\/ TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm;\n    TCA0.SPLIT.HPER = 255;\n    TCA0.SPLIT.HCMP1 = 64;\n    TCA0.SPLIT.CTRLB = TCA_SPLIT_HCMP1EN_bm;\n}\n\nvoid loop() {}<\/pre>\n\n<h3 class=\"wp-block-heading\">analogWrite() on the 4808 \/ 4809 boards<\/h3>\n\n<p>The Arduino Nano Every and the &#8220;Nano 4808&#8221; or their board packages basically do what we have just done to provide <code>analogRead()<\/code> pins. The Arduino Nano Every uses TCA0-0, TCA0-1 and TCA0-2 and the Nano 4808 TCA0-0 to TCA0-5. The other <code>analogRead()<\/code> pins are Timer B outputs.<\/p>\n<p>If you want to mix your &#8220;self-made&#8221; PWM outputs on some pins with <code>analogRead()<\/code> on other pins in one sketch, then you have to make sure that this is all compatible. If you set PER, HPER or LPER, this can have a direct impact on <code>analogRead()<\/code>, depending on the board or board package. The same applies if you switch to Normal or Split Mode, or if you assign the TCA outputs to another port.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"timer_b\">Timer B &#8211; TCBn Module<\/h2>\n\n<p>The Arduino Nano Every, or the ATmega4809 on which it is based, has four 16-bit Timers B (TCB0 to TCB3). The &#8220;Nano 4808&#8221; has three of these timers (TCB0 to TCB2). The differences to Timer A become clear when discussing the registers.<\/p>\n<p>For time measurements (<code>millis()<\/code>, <code>delay()<\/code>)&nbsp; the board packages use the TCB3 (Arduino Nano Every) or the TCB2 (&#8220;Nano 4808&#8221;). Changes to the settings of these timers lead to problems with the functions mentioned.<\/p>\n<p>TCB0 and TCB1 are used by all boards and board packages discussed here to provide <code>analogWrite()<\/code> pins. If you use these timers for other purposes or change the settings, you will lose the <code>analogWrite()<\/code> function of the affected pins.<\/p>\n<p>No outputs are available for TCB2 and TBC3 on the Arduino Nano Every, as the relevant pins PC0\/PB4 and PC1\/PB5 are not implemented.<\/p>\n\n<h3 class=\"wp-block-heading\">Timer B Register<\/h3>\n\n<p>Once again, I would like to point out that this article does not cover all existing registers.<\/p>\n\n<h4 class=\"wp-block-heading\">Control A Register TCBn.CTRLA<\/h4>\n\n<p>The most important settings in the Control A registers of Timer B are the clock rate (CLKSEL[2:0]) and enable. The system clock, the system clock divided by two or the clock of timer A can be selected as the clock rate.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"268\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register TCBn.CTRLA\" class=\"wp-image-19060\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-1024x268.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-300x78.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example-768x201.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/10\/TCBn_CTRLA_example.png 1266w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register TCBn.CTRLA<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Control B Register TCBn.CTRLB<\/h4>\n\n<p>In the Control B Register, you define one of the eight Count Modes (data sheet calls them &#8220;Timer modes&#8221;) that make the Timer B a versatile tool. For now, I will only list the count modes here, as they are best explained by the example sketches.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1-1024x81.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"81\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1-1024x81.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register TCBn.CTRLB\" class=\"wp-image-19131\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1-1024x81.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1-300x24.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1-768x60.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_CTRLB-1.png 1181w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register TCBn.CTRLB<\/figcaption><\/figure>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1033\" height=\"327\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE.png\" alt=\"CTNMODE[2:0] Bit Group Configurations\" class=\"wp-image-19124\" style=\"aspect-ratio:3.1604938271604937;width:641px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE.png 1033w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE-300x95.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE-1024x324.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/TCB_CTRLB_CNTMODE_TABLE-768x243.png 768w\" sizes=\"auto, (max-width: 1033px) 100vw, 1033px\" \/><\/a><figcaption class=\"wp-element-caption\">CTNMODE[2:0] Bit Group Configurations<\/figcaption><\/figure>\n\n<p>The other bits have the following effects:<\/p>\n<ul>\n<li>ASYNC (Asynchronous Enable): allows asynchronous updates of the TCB output signal in Single Shot Mode.<\/li>\n<li>CCMPINIT (Compare \/ Capture Pin Initial Value): sets the initial level of the output pin (0 = LOW, 1 = HIGH).<\/li>\n<li>CCMPEN (Compare \/ Capture Output Enable): activates the Compare \/ Capture Output. In contrast to Timer A, there is only one Compare Output per Timer B, but you have a larger number of timers.<\/li>\n<\/ul>\n\n<h4 class=\"wp-block-heading\">Interrupt Control Register TCBn.INTCTRL <\/h4>\n\n<p>The Interrupt Control Register is simple. You can activate the Capture Interrupt there, that&#8217;s all. The condition for triggering the interrupt depends on the Count Mode. I will come back to this in the examples. An overview can be found in the data sheet in section 21.5.5.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL-1024x87.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"87\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL-1024x87.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCBn.INTCTRL\" class=\"wp-image-19126\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL-1024x87.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL-300x25.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL-768x65.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_INTCTRL.png 1204w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCBn.INTCTRL \/ TCBn.INTFLAGS<\/figcaption><\/figure>\n\n<p>The interrupt vector is called TCBn_INT_vect and not &#8211; as one would expect &#8211; TCBn_CAPT_vect. Unfortunately, this is somewhat confusing. <\/p>\n\n<h4 class=\"wp-block-heading\">Event Control Register TCBn.EVCTRL<\/h4>\n\n<p>The effect of the EDGE bit in the Event Control Register EVCTRL also depends on the Count Mode. Wait for the examples or take a look at the overview in the data sheet in section 21.5.3.<\/p>\n<p>The FILTER bit activates a noise filter that ensures that the event status must be constant for four clock cycles before the event is considered valid.<\/p>\n<p>The Capture Event Input Enable Bit CAPTEI activates the input capture event. In contrast to Timer A, Timer B cannot count edges (events), but the edge starts or stops the counter.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL-1024x87.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"87\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL-1024x87.png\" alt=\"Arduino Nano Every \/ Nano 4808 Register: TCBn.EVCTRL\" class=\"wp-image-19122\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL-1024x87.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL-300x25.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL-768x65.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_TCB_EVCTRL.png 1193w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">TCBn.EVCTRL<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Further registers <\/h4>\n\n<p>The 16-bit register CNT contains &#8211; unsurprisingly &#8211; the Counter status of Timer B. Strictly speaking, there are two registers that you can address together via TCBn.CNT or separately via TCBn.CNTL and TCBn.CNTH.<\/p>\n<p>As the name suggests, the Capture \/ Compare Register CCMP has various tasks. As a Compare Register, it controls interrupts and PWM, as a Capture Register it records counter readings as measured values.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketches for Timer B<\/h3>\n\n<p>We will now go through example sketches for each Count Mode. The sketches are written for the Arduino Nano Every. The translation to the &#8220;Nano 4808&#8221; should not be difficult.<\/p>\n\n<h4 class=\"wp-block-heading\">periodic interrupt<\/h4>\n\n<p>In Periodic Interrupt mode, the timer counts down to CCMP, triggers the CAPT interrupt (if activated) and starts again from the beginning. In the following example sketch, we use the CAPT interrupt to toggle the board LED. As we use the Timer A clock (default setting DIV64) and set CCMP to 50000, the toggle frequency is: 16000000 \/ (64 * 50000) = 5 Hertz.&nbsp;<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_periodic_interrupt.ino\" data-enlighter-title=\"timer_b_periodic_interrupt.ino\">ISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n    PORTE.OUTTGL = PIN2_bm; \/* Toggle PE2 (D13 \/ LED-BUILTIN) *\/\n}\n\nvoid setup() {\n    PORTE.DIRSET = PIN2_bm;\n    PORTE.OUTSET = PIN2_bm;\n    \/\/ TCA0.SINGLE.CTRLA |= TCA_SINGLE_CLKSEL_DIV1024_gc;\n    TCB0.CCMP = 50000; \/\/ Toggle frequency = 5 Hz\n    TCB0.INTCTRL = TCB_CAPT_bm;\n    TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm; \/\/ use TCA clock \/ enable\n    TCB0.CTRLB = TCB_CCMPEN_bm;\n}\n\nvoid loop() {}<\/pre>\n\n<p>If you uncomment line 9, you change the clock divider from 64 to 1024, i.e. by a factor of 16. This reduces the toggle frequency to 0.3125 Hz (\u2192 period 3.2 s).&nbsp; But don&#8217;t forget: changing the timer A clock leads to problems with <code>delay()<\/code> &amp; Co. when using the Arduino megaAVR board package for the Arduino Nano Every. This is not a problem for the MegaCoreX package.<\/p>\n\n<h4 class=\"wp-block-heading\">8-Bit PWM mode<\/h4>\n\n<p>PWM signals are easy to create using Timer B. The lower byte of the CCMP comparison register, namely CCMPL, determines the PWM frequency in conjunction with the Timer B clock. The duty cycle results from the ratio of CCMPH, the upper byte, to CCMPL. You can write to the CCMPH and CCMPL registers separately or together.<\/p>\n\n<p><\/p>\n<p><p class=\"ql-center-displayed-equation\" style=\"line-height: 41px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/ql-cache\/quicklatex.com-be99fa4c24c04c98e3387cad8f98eb12_l3.png\" height=\"41\" width=\"301\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#91; &#68;&#117;&#116;&#121;&#67;&#121;&#99;&#108;&#101;&#32;&#61;&#32;&#92;&#102;&#114;&#97;&#99;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#67;&#67;&#77;&#80;&#72;&#125;&#125;&#123;&#92;&#116;&#101;&#120;&#116;&#123;&#67;&#67;&#77;&#80;&#76;&#32;&#43;&#32;&#49;&#125;&#125;&#32;&#92;&#99;&#100;&#111;&#116;&#32;&#49;&#48;&#48;&#92;&#59;&#92;&#59;&#32;&#91;&#92;&#37;&#93; &#92;&#93;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p><\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_8_bit_pwm.ino\" data-enlighter-title=\"timer_b_8_bit_pwm.ino\">void setup() {\n    PORTF.DIRSET = PIN5_bm; \/\/ PF5 = D3\n    TCB1.CCMP = 0x40FF;\n    \/* Alternative:\n    TCB1.CCMPL = 0xFF; \/\/ 255\n    TCB1.CCMPH = 0x40; *\/ \/\/ 64\n    TCB1.CTRLB |= TCB_CCMPEN_bm | TCB_CNTMODE_PWM8_gc;\n    TCB1.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm;\n}\n\nvoid loop(){}<\/pre>\n\n<p>In this example, we use the Timer A clock. This means that the frequency is 16 MHz \/ (64 * 256) = ~976.56 Hz. The duty cycle is 25%.<\/p>\n\n<h4 class=\"wp-block-heading\">Single Shot Mode<\/h4>\n\n<p>In Single Shot Mode, the timer counts down to CCMP and then stops until it is reset to a value less than CCMP. To try out the following sketch, connect an LED to the TCB0 output PF4 (= pin 6).<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_single_shot_simple.ino\" data-enlighter-title=\"timer_b_single_shot_simple.ino\">void setup() {\n    PORTF.DIRSET = PIN4_bm; \/\/ PF4 (D6) as output\n    TCB0.CTRLA = 0; \/\/ disable TCB0\n    TCB0.CCMP = 50000; \/\/ 0.2s signal length\n    TCB0.CTRLB = TCB_CCMPEN_bm | TCB_CNTMODE_SINGLE_gc; \/\/ enable output \/ single shot mode\n    TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm; \/\/ enable TCB0, use TCA clock\n}\n\nvoid loop(){\n    delay(1000);\n    TCB0.CNT = 0; \/\/ restarts the counter\n}<\/pre>\n\n<p>If your Arduino Nano Every is running at 16 MHz and you have not changed the Timer A clock, the LED will light up every second for 0.2 seconds.<\/p>\n<p>Now we connect this with the Event System. To do this, connect a push-button to PB1 (pin 10), which you in turn connect to GND. Pushing the button (event generator) will start the TCB0 (event user).<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_single_shot_extended.ino\" data-enlighter-title=\"timer_b_single_shot_extended.ino\">ISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n}\n\nvoid setup() {\n    PORTF.DIRSET = PIN4_bm; \/\/ PF4 (D6) as output\n    PORTB.DIRCLR = PIN1_bm; \/\/ PB1 (D10) as input\n    PORTB.PIN1CTRL = PORT_PULLUPEN_bm;\n    TCB0.CTRLA = 0; \/\/ disable TCB0\n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc; \/\/ PB1 as event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL1_gc; \/\/ TCB0 as event user\n    TCB0.CCMP = 50000; \/\/ 0.2s signal length\n    TCB0.CTRLB = TCB_CCMPEN_bm | TCB_CNTMODE_SINGLE_gc; \/\/ single shot mode\n    TCB0.EVCTRL = TCB_EDGE_bm | TCB_CAPTEI_bm; \/\/ counter starts at both edges \/ enable capture event input\n    TCB0.INTCTRL = TCB_CAPT_bm; \/\/ enable interrupt\n    TCB0.CNT = 50000; \/\/ prevents an unwanted, initial signal at PF4\n    TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm; \/\/ enable TCB0, use TCA clock\n}\n\nvoid loop(){}<\/pre>\n\n<p>According to the data sheet, chapter 21.5.3, the timer should only be triggered on a falling edge when the EDGE bit is set, i.e. when the button is pressed and not when it is released. However, the LED lights up for both events. Perhaps simply an error in the data sheet. If the EDGE bit is not set, the LED does what it should: it only lights up when it is released (rising edge). At least this applies as long as your button does not bounce.<\/p>\n<p>You may have noticed line 16. If you comment out the line, you will see that the LED lights up with every reset. Starting the timer causes it to start counting at 0 and the LED lights up accordingly. If you set the timer counter to CCMP, this will not happen.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Input Capture Time-Out Check Mode<\/h4>\n\n<p>The Time-Out Check Mode only makes sense in combination with the Event System. In this mode, an event signal starts the timer at 0 and the next signal stops it. If EDGE is set, the falling edge starts the timer and the rising edge stops it. If EDGE is not set, the opposite applies. If the timer counter reaches CCMP, an interrupt is triggered and the timer counter continues to run.&nbsp;<\/p>\n\n<p>We try this out as follows: a push-button connected to PB2 (D5) serves as an event generator that starts TCB0 in Time-Out Mode. As long as the button is pressed, TCB0 counts up. CCMP and the timer clock are set so that CCMP is reached after one second. If this occurs, an interrupt is triggered and the ISR toggles the board LED. If the button is released before CCMP is reached, there is no interrupt and the board LED does not toggle. The next time the button is pressed, the timer restarts at zero.<\/p>\n<p>Under default conditions, CCMP is reached quickly. I have therefore slowed down Timer A and used it as clock source for Timer B. And once again, my warning: If you use the megaAVR board package for the Nano Every, this will affect all time functions. Nevertheless, you can of course just try out the sketch, as it does not contain <code>delay()<\/code> or <code>millis()<\/code>. This is not a problem for the MegaCoreX package anyway.<\/p>\n<p>Here is the sketch reduced to the essentials:<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_time_out.ino\" data-enlighter-title=\"timer_b_time_out.ino\">#define TCB_TIMEOUT_VALUE (15625) \/\/ = 1s with the settings below\n\nISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n    PORTE.OUTTGL = PIN2_bm; \/* Toggle PE2 (D13, LED_BUILTIN)*\/\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    PORTE.DIRSET = PIN2_bm; \/\/ PE2 (D13) as output\n    PORTB.DIRCLR = PIN2_bm; \/\/ PB2 (D5) as input\n    PORTB.PIN2CTRL = PORT_PULLUPEN_bm; \/\/ enable pull-up\n        \n    EVSYS.CHANNEL0 = EVSYS_GENERATOR_PORT1_PIN2_gc; \/\/ PE2 is event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL0_gc; \/\/ TCB0 is event user\n\n    TCB0.CCMP = TCB_TIMEOUT_VALUE;\n    TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm; \/\/ slow down Timer A\n    TCB0.CTRLB = TCB_CCMPEN_bm | TCB_CNTMODE_TIMEOUT_gc; \/\/ enable compare\/capture output, time-out mode\n    TCB0.INTCTRL = TCB_CAPT_bm; \/\/ enable capture interrupt\n    TCB0.EVCTRL = TCB_EDGE_bm | TCB_CAPTEI_bm; \/\/ start counter on negative edge\n    TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm; \/\/ use timer A clock, enable TCB0\n}\n\nvoid loop(){}<\/pre>\n\n<p>With a 16 MHz system clock, a divider of 1024 and a CCMP of 15625, the counter reaches CCMP after 15625 * 1024 \/ 16000000 = 1 second. If you keep the button pressed, the counter continues to run and reaches CCMP every 65536 * 1024 \/ 16000000 = ~4.2 seconds.<\/p>\n<p>So that you can see at which counter reading you have released the button, I have written a second version of the sketch:<\/p>\n\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_time_out_extended.ino\" data-enlighter-title=\"timer_b_time_out_extended.ino\">#define TCB_TIMEOUT_VALUE (15625) \/\/ = 1s with the settings below\nvolatile bool keyReleased = false;\n\nISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n    PORTE.OUTTGL = PIN2_bm; \/* Toggle PE2 (D13, LED_BUILTIN)*\/\n}\n\nISR(PORTB_PORT_vect){ \/\/ ISR for button release\n    PORTB.INTFLAGS = PIN2_bm;\n    keyReleased = true;\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    PORTE.DIRSET = PIN2_bm; \/\/ PE2 (D13) as output\n    PORTB.DIRCLR = PIN2_bm; \/\/ PB2 (D5) as input\n    PORTB.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_RISING_gc; \/\/ pull-up \/ interrupt\n        \n    EVSYS.CHANNEL0 = EVSYS_GENERATOR_PORT1_PIN2_gc; \/\/ PE2 is event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL0_gc; \/\/ TCB0 is event user\n\n    TCB0.CCMP = TCB_TIMEOUT_VALUE;\n    TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm; \/\/ slow down Timer A\n    TCB0.CTRLB = TCB_CCMPEN_bm | TCB_CNTMODE_TIMEOUT_gc; \/\/ enable compare\/capture output, time-out mode\n    TCB0.INTCTRL = TCB_CAPT_bm; \/\/ enable capture interrupt\n    TCB0.EVCTRL = TCB_EDGE_bm | TCB_CAPTEI_bm; \/\/ start counter on negative edge\n    TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc | TCB_ENABLE_bm; \/\/ use timer A clock, enable TCB0\n}\n\nvoid loop(){\n    if(keyReleased){\n        Serial.println(TCB0.CNT);\n        keyReleased = false;\n    }\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n\n<h4 class=\"wp-block-heading\">Input Capture On Event Mode<\/h4>\n\n<p>Now, we come to the four input capture modes that you can use to measure pulse widths and \/ or frequencies. For all examples, we use a PWM signal with a duty cycle of 75% on pin 10 (PB1) as the object to be measured, which we generate with <code>analogWrite(10, 192)<\/code>. Pin 10 is the event generator, Timer B is the event user.<\/p>\n<p>First, let&#8217;s look at the Input Capture On Event Mode. In this mode, the counter permanently counts from 0 to 65535, runs over and starts again from the beginning. Depending on whether you have set the EDGE bit or not, the timer writes the current counter value to the CCMP register on a falling or rising edge and triggers an interrupt. We read the CCMP register in the ISR of the Capture Interrupt. The difference to the last value is the period of the PWM signal, measured in timer counter increments.<\/p>\n<p>In the event of a counter overflow between two interrupts, the difference is negative, and we have to add 65636.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_capture_on_event.ino\" data-enlighter-title=\"timer_b_capture_on_event.ino\">volatile long cnt = 0;\nvolatile long lastCnt = 0;\n\nISR(TCB0_INT_vect){\n    cnt = TCB0.CCMP - lastCnt; \/\/ Read the period\n    lastCnt = TCB0.CCMP;\n    if(cnt &lt; 0){   \/\/ period is neg. when TCB0 was overflowed\n        cnt += 65536;\n    }\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    analogWrite(10, 192); \/\/ the event source \n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc; \/\/ PB1 (Pin 10) is event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL1_gc; \/\/ TCB0 is event user\n    TCB0.CTRLA = 0; \/\/ Stop TCB0\n    TCB0.CTRLB = TCB_CNTMODE_CAPT_gc;  \/\/ use input capture on event mode\n    TCB0.EVCTRL =  TCB_CAPTEI_bm; \/\/ enable capture event input\n    TCB0.INTCTRL = TCB_CAPT_bm;  \/\/ enable capture interrupt\n    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm; \/\/ use system clock, enable TCB0\n    delay(10);\n}\n\nvoid loop(){\n    Serial.println(cnt);\n    delay(1000);\n}<\/pre>\n\n<p>The result when using the megaAVR board package was 16384. <code>analogWrite()<\/code> is controlled via the Timer A clock, which uses the divider 64. Regardless of the duty cycle, rising and a falling edges are generated every 256 counter increments. The PWM signal therefore has a frequency of 16 MHz \/ (64 * 256) = 976.5626 Hz, or a period of 0.001024 seconds. The clock of Timer B corresponds to the system clock. This means that 16384 counter increments correspond to a frequency of 16 MHz \/ 16384 = 976.5625 Hz. So it fits perfectly!<\/p>\n<p>With the MegaCoreX I determined a period of 16320 (= ~980.4 Hz), which surprised me at first. The reaon is: the <code>analogWrite()<\/code> function of the MegaCoreX package comprises only 255&nbsp; steps: 16 MHz \/ (64 * 255) = ~980 Hz. This actually makes more sense than 256 steps, as <code>analogWrite(pin, 255)<\/code> provides a duty cycle of 100%. With the Arduino board package, <code>analogWrite(pin, 255)<\/code> generates a duty cycle of 255\/256 * 100%, i.e. 100% cannot be achieved.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Input Capture Frequency Measurement Mode<\/h4>\n\n<p>The Input Capture Frequency Measurement Mode basically does the same as the Input Capture On Event Mode, except that the counter is reset to 0 after the event signal has been received. This has the advantage that CCMP provides us with the period directly, and we do not have to calculate differences.<\/p>\n<p>The term &#8220;frequency measurement&#8221; is actually incorrect. It should be called &#8220;period measurement&#8221;.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_input_capture_frq.ino\" data-enlighter-title=\"timer_b_input_capture_frq.ino\">ISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    analogWrite(10, 192); \/\/ the event source\n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc; \/\/ PB1 (Pin 10) is event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL1_gc; \/\/ TCB0 is event user\n    TCB0.CTRLA = 0;\n    TCB0.CTRLB = TCB_CNTMODE_FRQ_gc; \/\/ enable input capture frequency mode\n    TCB0.EVCTRL = TCB_EDGE_bm | TCB_CAPTEI_bm; \/\/ enable capture event input \n    TCB0.INTCTRL = TCB_CAPT_bm;  \/\/ enable capture event input\n    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm; \/\/ use system clock, enable TCB0\n  \n}\n\nvoid loop(){\n    Serial.print(\"Period in TCB0 counts: \");\n    Serial.println(TCB0.CCMP + 1);\n    float frq = 16000000.0 \/ ((TCB0.CCMP + 1) * 1.0);\n    Serial.print(\"Frequency [Hz]: \");\n    Serial.println(frq);\n    delay(1000);\n}<\/pre>\n\n<p>In this example sketch, I have integrated the calculation of the frequency into the sketch. It is interesting to note that you have to add 1 to the CCMP value to get the correct result. A CCMP value of 16383 is 16384 steps &#8211; that actually makes sense. The only thing that hasn&#8217;t really become clear, at least to me, is why you <em>don&#8217;t<\/em> have to add 1 when using the Input Capture On Event Mode.<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/frq_measurement_output.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"749\" height=\"181\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/frq_measurement_output.webp\" alt=\"Output timer_b_input_capture_frq.ino, left: megaAVR package, right: MegaCoreX package\" class=\"wp-image-19259\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/frq_measurement_output.webp 749w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/frq_measurement_output-300x72.webp 300w\" sizes=\"auto, (max-width: 749px) 100vw, 749px\" \/><\/a><figcaption class=\"wp-element-caption\">Output timer_b_input_capture_frq.ino, left: megaAVR package, right: MegaCoreX package<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Input Capture Pulse-Width Measurement Mode<\/h4>\n\n<p>The Input Capture Pulse-Width Measurement Mode allows you to measure the pulse width of signals. In contrast to Frequency Measurement Mode, in which only the rising or falling edge had an effect, in this mode the counter is &#8220;zeroed&#8221; on one edge and the input capture, i.e. writing the counter reading to CCMP, takes place on the other edge.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_input_capture_pw.ino\" data-enlighter-title=\"timer_b_input_capture_pw.ino\">ISR(TCB0_INT_vect){\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    analogWrite(10, 192); \/\/&nbsp;the&nbsp;event&nbsp;source\n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc; \/\/ PB1 (Pin 10) is event generator\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL1_gc;  \/\/ TCB0 is event user\n    TCB0.CTRLA = 0;\n    TCB0.CTRLB = TCB_CNTMODE_PW_gc; \/\/ enable pulse width measurement mode\n    TCB0.EVCTRL = TCB_CAPTEI_bm; \/\/ enable capture event input\n    TCB0.INTCTRL = TCB_CAPT_bm; \n    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm; \/\/ use system clock, enable TCB0\n    delay(10);\n}\n\nvoid loop(){\n    Serial.print(\"High Period in TCB0 counts: \");\n    unsigned int highCnt = (TCB0.CCMP + 1);\n    Serial.println(highCnt);\n    float pw = (highCnt * 1.0) \/ 16.0;  \/\/ cnt divided by 16 MHz\n    Serial.print(\"Pulse width [\u00b5s]: \");\n    Serial.println(pw);\n    Serial.println();\n    delay(1000);\n}<\/pre>\n<p>&nbsp;<\/p>\n\n<p>As a result, I received both the megaAVR package and MegaCoreX:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_pw_method_ard_package.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"417\" height=\"51\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_pw_method_ard_package.webp\" alt=\"Output timer_b_input_capture_pw.ino\" class=\"wp-image-19262\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_pw_method_ard_package.webp 417w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_pw_method_ard_package-300x37.webp 300w\" sizes=\"auto, (max-width: 417px) 100vw, 417px\" \/><\/a><figcaption class=\"wp-element-caption\">Output timer_b_input_capture_pw.ino<\/figcaption><\/figure>\n\n<p>This corresponds exactly to expectations. The PWM period was 16384 counters long (megaAVR package). 75% of these are 12288. With MegaCoreX the period was 16320. 16320 \/ 255 * 192 = 12288 \u2192 this also fits well.<\/p>\n<p>If you set the EDGE bit in the event control register (line 12), the sketch evaluates the LOW phase.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">Input Capture Frequency and Pulse-Width Measurement Mode<\/h4>\n\n<p>The Input Capture Frequency and Pulse-Width Measurement Mode combines frequency and pulse-width measurement. Of course, not both values can be saved in CCMP. Instead, the mode works as follows (if the EDGE bit is not set):<\/p>\n<ul>\n<li>At first positive edge (pulse begins): The counter is reset and starts.<\/li>\n<li>Next negative edge (pulse ends): Input capture, i.e. the counter reading is written to CCMP.<\/li>\n<li>Second positive edge (period ends): Counter stops, an interrupt is triggered.<\/li>\n<\/ul>\n<p>Since we know the period (from CCMP) and the pulse width (counter status at interrupt), we can calculate the duty cycle. And that&#8217;s precisely what the next sketch does:<\/p>\n\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"timer_b_input_capture_frq_and_pw.ino\" data-enlighter-title=\"timer_b_input_capture_frq_and_pw.ino\">volatile unsigned int period = 0;\n\nISR(TCB0_INT_vect){\n    period = TCB0.CNT + 1; \/\/ Read the period\n    TCB0.INTFLAGS = TCB_CAPT_bm; \/* Clear the interrupt flag *\/\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    analogWrite(10, 192);\n    EVSYS.CHANNEL1 = EVSYS_GENERATOR_PORT1_PIN1_gc;\n    EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL1_gc;\n    TCB0.CTRLA = 0;\n    TCB0.CTRLB = TCB_CNTMODE_FRQPW_gc;\n    TCB0.EVCTRL = TCB_CAPTEI_bm; \/\/ TCB_EDGE_bm | TCB_CAPTEI_bm;\n    TCB0.INTCTRL = TCB_CAPT_bm;\n    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm; \/\/ use system clock, enable TCB0\n}\n\nvoid loop(){\n    Serial.print(\"Period in TCB0 counts: \");\n    Serial.println(period);\n    Serial.print(\"High Period in TCB0 counts: \");\n    Serial.println(TCB0.CCMP + 1);\n    float frq = 16000000.0 \/ (period * 1.0);\n    Serial.print(\"Frequency [Hz]: \");\n    Serial.println(frq);\n    float dc = (TCB0.CCMP + 1) * 1.0 \/ (period * 1.0) * 100.0;\n    Serial.print(\"Duty Cycle [%]: \");\n    Serial.println(dc);\n    Serial.println();\n    delay(1000);<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n\n<p>Here is the result:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_timer_b_frq_pw.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"780\" height=\"110\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_timer_b_frq_pw.webp\" alt=\"Output timer_b_input_capture_frq_and_pw.ino, megaAVR and MegaCoreX \" class=\"wp-image-19267\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_timer_b_frq_pw.webp 780w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_timer_b_frq_pw-300x42.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_timer_b_frq_pw-768x108.webp 768w\" sizes=\"auto, (max-width: 780px) 100vw, 780px\" \/><\/a><figcaption class=\"wp-element-caption\">Output timer_b_input_capture_frq_and_pw.ino, left: megaAVR, right: MegaCoreX <\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"rtc_module\">Real-Time Counter &#8211; RTC Module<\/h2>\n\n<p>The RTC module offers two functions, namely the 16-bit Real-Time Counter (RTC) and the Periodic Interrupt Timer (PIT). Both use the same clock source. Otherwise, the functions can be used independently of each other. The maximum clock rate is 32768 Hz, so you are more likely to control the slower processes with this module.<\/p>\n\n<h3 class=\"wp-block-heading\">The Registers of the RTC Module<\/h3>\n\n<h4 class=\"wp-block-heading\">Clock Selection Register CLKSEL<\/h4>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL-1024x82.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"82\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL-1024x82.webp\" alt=\"Register RTC.CLKSEL\" class=\"wp-image-19280\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL-1024x82.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL-300x24.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL-768x61.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CLKSEL.webp 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.CLKSEL<\/figcaption><\/figure>\n\n<p>The clock is set in the CLKSEL register. The following options are available:<\/p>\n<ul>\n<li><strong>INT32K_gc<\/strong>: 32768 Hz provided by the internal ultra low-power oscillator OSCULP32K.<\/li>\n<li><strong>INT1K_gc<\/strong>: Like INT32K, but with a divider of 32, i.e. 1024 Hz.<\/li>\n<li><strong>TOSC32K_gc:<\/strong> 32768 Hz through XOSC32K or an external clock at TOSC1.<\/li>\n<li><strong>EXTCLK_gc<\/strong>: External clock generator connected to EXTCLK.<\/li>\n<\/ul>\n\n<h4 class=\"wp-block-heading\">Crystal Frequency Calibration Register CALIB<\/h4>\n\n<p>A really great feature of the RTC module is that you can calibrate the underlying clock using the CALIB register.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB-1024x90.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"90\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB-1024x90.webp\" alt=\"tinyAVR Register RTC.CALIB\" class=\"wp-image-19278\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB-1024x90.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB-300x26.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB-768x68.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CALIB.webp 1190w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.CALIB<\/figcaption><\/figure>\n\n<p>ERROR[6:0] is the deviation in ppm. If SIGN is set, the clock is correspondingly faster. In this case, you must set the prescaler to at least DIV2. If SIGN is not set, the clock is slower.&nbsp;<\/p>\n\n<h4 class=\"wp-block-heading\">RTC Control Register A CTRLA<\/h4>\n\n<p>In the CTRLA register, you specify whether the RTC module should continue to run in standby mode (RUNSTDBY). Furthermore, you (de)activate the calibration (CORREN) and enable the module (RTCEN).<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA-1024x87.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"87\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA-1024x87.webp\" alt=\"RTC.CTRLA\" class=\"wp-image-19284\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA-1024x87.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA-300x26.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA-768x66.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CTRLA.webp 1195w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.CTRLA<\/figcaption><\/figure>\n\n<p>You can use the PRESCALER to slow down the RTC with a maximum factor of 32768:<\/p>\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table-1024x381.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"381\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table-1024x381.webp\" alt=\"PRESCALER[3:0] Bit Group Configurations \" class=\"wp-image-19290\" style=\"width:640px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table-1024x381.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table-300x112.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table-768x286.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_DIV_table.webp 1027w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">PRESCALER[3:0] Bit Group Configurations <\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">RTC Interrupt Control Register INTCTRL<\/h4>\n\n<p>A Compare Match and an Overflow Interrupt are available for the RTC. The corresponding Interrupt Flag Register INTFLAG is similar.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL-1024x85.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"85\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL-1024x85.webp\" alt=\"tinyAVR Register: RTC.INTCTRL \/ RTC.INTFLAGS\" class=\"wp-image-19286\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL-1024x85.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL-300x25.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL-768x64.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_INTCTRL.webp 1220w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.INTCTRL \/ RTC.INTFLAGS<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">PIT Control Register A CTRLA<\/h4>\n\n<p>The Periodic Interrupt Timer simply does what its name suggests: It triggers an interrupt at regular intervals. In the PITCTRLA register, you can activate the PIT and set the period.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA-1024x89.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"89\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA-1024x89.webp\" alt=\"tinyAVR Register: RTC.PITCTRLA\" class=\"wp-image-19282\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA-1024x89.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA-300x26.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA-768x67.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITCTRLA.webp 1220w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.PITCTRLA<\/figcaption><\/figure>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CYCLE_table.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"381\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CYCLE_table.webp\" alt=\"PERIOD[3:0] Bit Group Configurations\" class=\"wp-image-19288\" style=\"width:675px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CYCLE_table.webp 1023w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CYCLE_table-300x112.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_CYCLE_table-768x286.webp 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/a><figcaption class=\"wp-element-caption\">PERIOD[3:0] Bit Group Configurations<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">PIT Interrupt Control Register PITINTCTRL<\/h4>\n\n<p>In PITINTCRTL you activate the PIT interrupt. PITINTFLAGS is similar to PITINTCTRL.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL-1024x81.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"81\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL-1024x81.webp\" alt=\"tinyAVR Register: RTC.PITINTCTRL \/ RTC.PITINTFLAGS\" class=\"wp-image-19292\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL-1024x81.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL-300x24.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL-768x61.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_RTC_PITINTCTRL.webp 1241w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register RTC.PITINTCTRL \/ RTC.PITINTFLAGS<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\">Example Sketches for RTC and PIT<\/h3>\n\n<h4 class=\"wp-block-heading\">RTC example sketch<\/h4>\n\n<p>As a simple example for programming the RTC, here is a sketch that generates a &#8220;slow motion PWM&#8221; with a period of 2 seconds and a duty cycle of 75% at PE2 (= D13 = board LED).<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"rtc_example.ino\" data-enlighter-title=\"rtc_example.ino\">ISR(RTC_CNT_vect){\n    if(RTC.INTFLAGS &amp; RTC_CMP_bm){ \/\/ check for CMP interrupt\n        RTC.INTFLAGS = RTC_CMP_bm; \/\/ delete CMP interrupt flag\n        PORTE.OUTCLR = PIN2_bm; \/\/ PE2 = LOW\n    }\n    if(RTC.INTFLAGS &amp; RTC_OVF_bm){ \/\/ check for OVF interrupt\n        RTC.INTFLAGS = RTC_OVF_bm; \/\/ delete OVF interrupt flag\n        PORTE.OUTSET = PIN2_bm;  \/\/ PE2 = HIGH\n    }\n}\n\nvoid setup() {\n    delay(1);\n    PORTE.DIRSET = PIN2_bm;\n    RTC.CLKSEL = RTC_CLKSEL_INT32K_gc; \/\/ set internal clock @ 32768 Hz\n    RTC.PER = 16383;  \/\/ TOP = 16383\n    RTC.CMP = 12288;  \/\/ Compare value = 12288\n    RTC.INTCTRL = RTC_CMP_bm | RTC_OVF_bm;  \/\/ enable CMP and OVF interrupts\n    RTC.CTRLA = RTC_PRESCALER_DIV4_gc | RTC_RTCEN_bm; \/\/ Prescaler = 4 and enable RTC\n}\n\nvoid loop(){}<\/pre>\n\n<p>As only one interrupt vector (RTC_CNT_vect) is available for the Overflow and Compare Interrupt, we have to use the interrupt flags to check which event triggered the interrupt.<\/p>\n<p>The prescaler is set to 4, i.e. the RTC counts at a frequency of 32768 \/ 4 = 8192 Hz. PER is 16383 and therefore the RTC overflows every 16384 steps, which corresponds to an overflow frequency of 2 seconds. The Compare Value is 12288, i.e. 75% of PER +1.<\/p>\n\n<h4 class=\"wp-block-heading\">PIT example sketch<\/h4>\n\n<p>The example sketch for the PIT is even simpler. With a period of 16384 and a clock rate of 32768 Hz, an interrupt is triggered every 0.5 seconds. We use it in this sketch to toggle the board LED.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pit_example.ino\" data-enlighter-title=\"pit_example.ino\">ISR(RTC_PIT_vect){\n    RTC.PITINTFLAGS = RTC_PI_bm; \/\/ clear PIT interrupt flag\n    PORTE.OUTTGL = PIN2_bm; \/\/ toggle PE2\n}\n\nvoid setup() {\n    PORTE.DIRSET = PIN2_bm;\n    RTC.CLKSEL = RTC_CLKSEL_INT32K_gc; \/\/ set internal clock @ 32768 Hz\n    RTC.PITINTCTRL = RTC_PI_bm;  \/\/ enable PIT interrupt\n    RTC.PITCTRLA = RTC_PERIOD_CYC16384_gc | RTC_PITEN_bm; \/\/ interrupt frq: 2 Hz\n}\n\nvoid loop(){}<\/pre>\n\n<h2 class=\"wp-block-heading\" id=\"adc_module\">A\/D Converter &#8211; ADCn Module<\/h2>\n\n<p>The ADC of the Arduino Nano Every \/ &#8220;Nano 4808&#8221; would actually be worth its own article. However, I will keep this chapter short and ask you to look into the data sheet for further information. Here is the register summary:<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_ADC-1.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1018\" height=\"574\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_ADC-1.webp\" alt=\"Register Summary ADCn\" class=\"wp-image-19381\" style=\"width:778px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_ADC-1.webp 1018w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_ADC-1-300x169.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_Summary_ADC-1-768x433.webp 768w\" sizes=\"auto, (max-width: 1018px) 100vw, 1018px\" \/><\/a><figcaption class=\"wp-element-caption\">Register Summary ADCn<\/figcaption><\/figure>\n\n<p>I will go into a few selected register settings:<\/p>\n<ul>\n<li>RUNSTBY: Allows the ADC to be operated in standby mode.<\/li>\n<li>RESSEL: If you set this bit, the resolution is reduced from 10 to 8 bits.<\/li>\n<li>FREERUN: Continuous mode.<\/li>\n<li>SAMPNUM: You can add up to 64 results per measurement. 2^6 results times 2^10 resolution gives a result with a size of 2^16 bits, which still fits into the RES result register.<\/li>\n<li>PRESC: Divider for the clock rate of the ADC.<\/li>\n<li>REFSEL: Selection of the reference voltage. You can choose between: INTREF (Internal Reference), VDDREF and VREFA (External Reference). The data sheet incorrectly states &#8220;INTERNAL&#8221; and &#8220;VDD&#8221; instead of INTREF or VDDREF. <\/li>\n<li>COLLECT: Extends the measuring time up to a maximum factor of 31.<\/li>\n<li>MUXPOS: Defines the input for the ADC. The table with the bit group configurations can be found in the data sheet. <\/li>\n<li>STARTCONV: Starts a measurement.<\/li>\n<\/ul>\n\n<p>The internal reference is specified in the VREF.CTRLA register. To do this, set the bit group ADC0REFSEL[2:0]. The available Bit Group Configurations are <em>VREF_ADC0REFSEL_xxx_gc<\/em> with <em>xxx<\/em> = 0V55, 1V1, 2V5V, 4V34 V or 1V5 for 0.55, 1.1, 2.5, 4.34 or 1.5 volts.<\/p>\n\n<h3 class=\"wp-block-heading\">Example Sketches for the ADC<\/h3>\n\n<h4 class=\"wp-block-heading\">Simple ADC measurement<\/h4>\n\n<p>With the following example sketch, we measure the voltage at A2. We use the internal 4.34 V reference voltage.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"adc_example.ino\" data-enlighter-title=\"adc_example.ino\">void setup() {\n    Serial.begin(115200);\n    PORTD.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc; \/\/ Disable digital buffer\n    ADC0.CTRLA = ADC_ENABLE_bm; \/\/ Enable ADC\n    ADC0.CTRLC = ADC_REFSEL_INTREF_gc | ADC_PRESC_DIV16_gc; \/\/ use internal reference \/ prescaler: 16\n    VREF.CTRLA = VREF_ADC0REFSEL_4V34_gc; \/\/ use internal 4.34 V reference \n    ADC0.MUXPOS = ADC_MUXPOS_AIN1_gc; \/\/ use A2 (PD1) as input\n    ADC0.SAMPCTRL = 0;\n}\n\nvoid loop(){\n    ADC0.COMMAND = ADC_STCONV_bm; \/\/ Start Conversion\n    while((ADC0.INTFLAGS &amp; ADC_RESRDY_bm) == 0){} \/\/ Waiting for the result\n    float res = ADC0.RES * 4340.0 \/ 1024.0;\n    Serial.println(res);\n    delay(1000);\n}<\/pre>\n\n<h4 class=\"wp-block-heading\">ADC0 &#8211; RTC controlled<\/h4>\n\n<p>Let me come back to the events. The following sketch uses the RTC to initiate an ADC conversion every two seconds.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"rtc_controlled_adc.ino\" data-enlighter-title=\"rtc_controlled_adc.ino\">volatile bool adcReady = false;\n\nISR(ADC0_RESRDY_vect){\n    adcReady=true;\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    PORTD.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc;\n    ADC0.CTRLA = ADC_ENABLE_bm;\n    ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_REFSEL_INTREF_gc | ADC_PRESC_DIV16_gc;\n    VREF.CTRLA = VREF_ADC0REFSEL_4V34_gc;\n    ADC0.MUXPOS = ADC_MUXPOS_AIN1_gc; \/\/ A2 (PD1)\n    ADC0.SAMPCTRL = 0;\n    ADC0.EVCTRL = ADC_STARTEI_bm; \/\/ initiate measurement by event\n    ADC0.INTCTRL = ADC_RESRDY_bm; \/\/ enable result ready interrupt\n    RTC.CLKSEL |= RTC_CLKSEL_INT32K_gc; \/\/ use internal 32 kHz clock\n    RTC.PER = 63; \/\/ overflow after 63 (64 steps) \n    RTC.CTRLA = RTC_PRESCALER_DIV1024_gc | RTC_RTCEN_bm; \/\/ OVF frequency = 0.5 Hz\n    \n    EVSYS.CHANNEL0 = EVSYS_GENERATOR_RTC_OVF_gc; \/\/ RTC overflow is event generator\n    EVSYS.USERADC0 = EVSYS_CHANNEL_CHANNEL0_gc; \/\/ ADC0 is event user\n}\n\nvoid loop(){\n    if(adcReady){ \n        float res = ADC0.RES * 4340L \/ 1024.0;\n        Serial.println(res);\n        adcReady = false;\n    }\n}<\/pre>\n\n<p>Without the event system, you would have to set up a timer interrupt or apply a construction with <code>delay()<\/code> or <code>millis()<\/code> to start measurements at 2-second intervals. You would then have to wait or be informed via another interrupt when the conversion result is available. In the example above, however, a single interrupt is sufficient, everything else is done in the background.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"wdt_module\">Watchdog Timer &#8211; WDT Module<\/h2>\n\n<h3 class=\"wp-block-heading\">The registers of the WDT Module<\/h3>\n\n<p>Two features in particular distinguish the WDT of the ATmega4808\/4809 from the Arduino Nano Every and &#8220;Nano 4808&#8221;:<\/p>\n<ul>\n<li>The WDT has no interrupt.&nbsp;<\/li>\n<li>A WDT timeout always triggers a reset<\/li>\n<\/ul>\n<p>The Watchdog Timer (WDT) receives its clock from the ultra low-power oscillator, OSCULP32K.<\/p>\n\n<h4 class=\"wp-block-heading\">Control A Register CTRLA<\/h4>\n\n<p>You enter the timing parameters for the WDT in control register A, CTRLA.<\/p>\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA-1024x81.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"81\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA-1024x81.webp\" alt=\"tinyAVR Register: WDT.CTRLA\" class=\"wp-image-19323\" style=\"width:840px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA-1024x81.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA-300x24.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA-768x61.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_CTRLA.webp 1185w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register WDT.CTRLA<\/figcaption><\/figure>\n\n<p>You can make the following settings for PERIOD and WINDOW:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings-1024x404.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"404\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings-1024x404.webp\" alt=\"WINDOW[3:0] \/ PERIOD[3:0] Bit Group Configurations\" class=\"wp-image-19325\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings-1024x404.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings-300x118.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings-768x303.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/wdt_ctrla_settings.webp 1213w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">WINDOW[3:0] \/ PERIOD[3:0] Bit Group Configurations<\/figcaption><\/figure>\n\n<p>If you only set a value for PERIOD and keep WINDOW at 0, the WDT will run in Normal Mode. If no watchdog reset takes place within the time period defined with PERIOD, a system reset is carried out.<\/p>\n<p>If WINDOW is not zero, you are in Window Mode. This is a little more difficult to explain, and perhaps only becomes clear with the example sketch. The following applies in window mode:<\/p>\n<ul>\n<li>After initialization or a <code>wdt_reset()<\/code>, the WDT is in the period defined by WINDOW. The data sheet calls this period &#8220;closed window time-out period&#8221; (TO<sub>WDTW<\/sub>). The WDT cannot be reset during this period.&nbsp; A <code>wdt_reset()<\/code> within this period leads to an immediate system reset.<\/li>\n<li>After the TO<sub>WDTW<\/sub>, the &#8220;normal window time-out period&#8221; (TO<sub>WDT<\/sub>) begins, the length of which you specify with PERIOD. If a <code>wdt_reset()<\/code> is received during this time, the game starts again from the beginning with the TO<code>WDTW<\/code>.<\/li>\n<li>If there is no <code>wdt_reset()<\/code> in the TO<sub>WDTW<\/sub> + TO<sub>WDT<\/sub> period, a system reset is carried out.<\/li>\n<\/ul>\n\n<h4 class=\"wp-block-heading\">Status Register STATUS <\/h4>\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS-1024x80.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"80\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS-1024x80.webp\" alt=\"Arduino Nano Every \/ Nano 4808 Register: WDT.STATUS\" class=\"wp-image-19327\" style=\"width:845px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS-1024x80.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS-300x23.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS-768x60.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_WDT_STATUS.webp 1191w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register WDT.STATUS<\/figcaption><\/figure>\n\n<p>By setting the LOCK bit, you protect the WDT settings against changes. You can only delete it again in debug mode.<\/p>\n<p>If you write data to the CTRLA register, it must be transferred to the WDT clock domain. The SYNCBUSY bit is set during synchronization.<\/p>\n\n<h3 class=\"wp-block-heading\">Example Sketch for the WDT<\/h3>\n\n<p>The Normal Mode should not require a sample sketch. That&#8217;s why we&#8217;re only looking at one sketch for the Window Mode. The setting for the WDT is: TO<sub>WDTW<\/sub> = TO<sub>WDT<\/sub> = 4 seconds.<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"wdt.ino\" data-enlighter-title=\"wdt.ino\">#include &lt;avr\/wdt.h&gt;\nvoid setup(){\n    Serial.begin(115200);\n    Serial.println(\"*******************\");\n    Serial.println(\"Watchdog Timer Test\");\n    Serial.println(\"Sketch starts...\");\n    CPU_CCP = CCP_IOREG_gc; \/\/ allow changes\n    WDT.CTRLA = WDT_WINDOW_4KCLK_gc | WDT_PERIOD_4KCLK_gc; \/\/ 4s period and window\n    CPU_CCP = CCP_IOREG_gc;\n    WDT.STATUS = WDT_LOCK_bm;\n    while(WDT.STATUS &amp; WDT_SYNCBUSY_bm){} \/\/ wait until WDT is synchronized\n    wdt_reset();\n    int seconds = 0;\n    while(seconds &lt; 100){\n        \/\/ if(seconds == 5){  \/\/ try also 3\n        \/\/     wdt_reset();\n        \/\/ }\n        Serial.print(seconds);\n        Serial.println(\" seconds\");\n        delay(1000);\n        seconds++;\n    }\n}\n\nvoid loop(){}<\/pre>\n\n<p>If you let the sketch run unchanged, the while() loop counts up until TO<sub>WDTW<\/sub> + TO<code>WDT<\/code> = 8 seconds have passed. The last output is &#8220;7 seconds&#8221; because once the eighth second has been reached, there is no more time for the output of &#8220;8 seconds&#8221;.<\/p>\n<p>If you uncomment lines 15 to 17, there is a <code>wdt_reset()<\/code> at fifth second, i.e. in the &#8220;allowed&#8221; TO<sub>WDT<\/sub> period. The WDT then runs for a further eight seconds until the system reset is carried out.<\/p>\n<p>If you then change line 15 so that the <code>wdt_reset()<\/code> occurs after three seconds, there will be an immediate system reset as you are in the &#8220;forbidden&#8221; TO<sub>WDTW<\/sub> period.<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_wdt_sketch.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"871\" height=\"353\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_wdt_sketch.webp\" alt=\"Output wdt.ino - left: unchanged, center: &quot;if (seconds == 5)&quot;, right: &quot;if(seconds ==3)&quot; \" class=\"wp-image-19337\" style=\"width:840px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_wdt_sketch.webp 871w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_wdt_sketch-300x122.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/output_wdt_sketch-768x311.webp 768w\" sizes=\"auto, (max-width: 871px) 100vw, 871px\" \/><\/a><figcaption class=\"wp-element-caption\">Output wdt.ino &#8211; left: unchanged, center: &#8220;if (seconds == 5)&#8221;, right: &#8220;if(seconds ==3)&#8221; <\/figcaption><\/figure>\n\n<p>And what&#8217;s the point of all this? The watchdog normally bites if the sketch gets stuck somewhere. You can use the Window method to reset the system if an action is executed too early, for example because some other step was not executed for whatever reason.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"ccl_module\">Configurable Custom Logic &#8211; CCL Module<\/h2>\n\n<p>With the Configurable Custom Logic Module CCL, the Arduino Nano Every or &#8220;Nano4808&#8221; gains capabilities for which you would otherwise have to use external logic ICs. But it goes far beyond that.<\/p>\n<p>The CCL module is organized in four so-called Look-Up Tables (LUTs). Each LUT has three inputs and one output.<\/p>\n<p>In my pinout diagrams, I have labeled the inputs as x-INy, with x = 0 to 4 (number of the LUT) and y = 0 to 2. The outputs are labeled x-OUT with x = 0 to 3.&nbsp;<\/p>\n\n<h3 class=\"wp-block-heading\">Register of the CCL Module<\/h3>\n\n<p>I will only give a rough overview of this module. Here is the register overview:<\/p>\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_ccl-1.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"941\" height=\"551\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_ccl-1.webp\" alt=\"Register Summary Module CCL\" class=\"wp-image-19384\" style=\"width:732px;height:auto\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_ccl-1.webp 941w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_ccl-1-300x176.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/reg_summary_ccl-1-768x450.webp 768w\" sizes=\"auto, (max-width: 941px) 100vw, 941px\" \/><\/a><figcaption class=\"wp-element-caption\">Register Summary Module CCL<\/figcaption><\/figure>\n\n<p>Each LUT has its own TRUTH register. This is where you define which input level combination is true. Example: For LUT2, we define that 2-IN2 = HIGH, 2-IN1 = LOW and 2-IN0 = LOW should be the &#8220;true&#8221; state. I.e: HIGH\/LOW\/LOW \u21d2 0b100 = 4. This in turn means that bit no. 4 must be set in TRUTH2 (and not that TRUTH2 = 4!).<\/p>\n<p>Now comes the ingenious part: The inputs do not have to be just I\/O pins, but can also be events, timers, USARTs or the output of another LUT, for example. So if certain states of different modules in your program require an action, you can save yourself the trouble of querying these states and some if and switch combinations with the CCL. You define the inputs via the Input Select Bitgroups (INSELn[3:0]).<\/p>\n<p>If the &#8220;true&#8221; state occurs, you can be notified by an interrupt. Alternatively or additionally, you can set the OUTEN bit so that the corresponding output goes from LOW to HIGH when &#8220;true&#8221;.<\/p>\n<p>You can even combine 2 LUTs (LUT0 and LUT1 or LUT2 and LUT3) using the SEQSELn[3:0] bit groups.<\/p>\n\n<h3 class=\"wp-block-heading\">Example Sketch for the CCL Module<\/h3>\n\n<p>As a simple example, we check the status of the I\/O pins assigned to LUT2. The following applies to the Arduino Nano Every:<\/p>\n<ul>\n<li>2-IN2 = PD2 = A1<\/li>\n<li>2-IN1 = PD1 = A2<\/li>\n<li>2-IN0 = PD0 = A3<\/li>\n<li>2-OUT = PD3 = A0<\/li>\n<\/ul>\n<p>Our true condition should be: 2-IN2 = HIGH, 2-IN1 = LOW and 2-IN0 = LOW. We pull the inputs to HIGH with the internal pull-up resistors. Pressing the button should bring them to LOW. If the buttons on 2-IN1 and 2-IN0 are pressed, the true condition is fulfilled and output 2-OUT goes HIGH. This is indicated by an LED. This is the circuit:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1-1024x494.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"494\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1-1024x494.webp\" alt=\"Circuit for ccl_basic.ino\" class=\"wp-image-19354\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1-1024x494.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1-300x145.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1-768x371.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/ccl_test-1.webp 1260w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Circuit for ccl_basic.ino<\/figcaption><\/figure>\n\n<p>And here is the corresponding sketch:<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"ccl_basic.ino\" data-enlighter-title=\"ccl_basic.ino\">void setup() {\n    PORTD.DIRCLR = PIN2_bm | PIN1_bm | PIN0_bm; \/\/ PD0 = A3 = 2-IN0 as input, etc.\n    PORTD.PIN0CTRL = PORT_PULLUPEN_bm; \/\/ PULLUP for PD0 = A3 = 2-IN0\n    PORTD.PIN1CTRL = PORT_PULLUPEN_bm; \/\/ PULLUP for PD1 = A2 = 2-IN1\n    PORTD.PIN2CTRL = PORT_PULLUPEN_bm; \/\/ PULLUP for PD2 = A1 = 2-IN2\n    CCL.LUT2CTRLB = CCL_INSEL0_IO_gc | CCL_INSEL1_IO_gc; \/\/ select I\/O as input\n    CCL.LUT2CTRLC = CCL_INSEL2_IO_gc; \/\/ select I\/O as Input\n    CCL.TRUTH2 = 0x10; \/\/ 2-IN2 = HIGH, 1-IN2 = LOW, 0-IN2 = LOW ==&gt; TRUE\n    CCL.LUT2CTRLA = CCL_OUTEN_bm | CCL_ENABLE_bm; \/\/ OUT Enable \/ LUT2 enable\n    CCL.CTRLA = CCL_ENABLE_bm; \/\/ CCL_ENABLE\n}\n\nvoid loop(){}<\/pre>\n\n<p>The MegaCoreX board package has implemented its own library called <a href=\"https:\/\/github.com\/MCUdude\/MegaCoreX\/tree\/master\/megaavr\/libraries\/Logic\" target=\"_blank\" rel=\"noopener\">Logic<\/a> for the CCL module.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"slpctrl_module\">The Arduino Nano Every goes to sleep &#8211; SLPCTRL Module<\/h2>\n\n<p>Going to sleep &#8211; I think this is a good topic for the last chapter!<\/p>\n\n<h3 class=\"wp-block-heading\">Register Settings for SLPCTRL<\/h3>\n\n<p>The SLPCTRL module only has the CTRLA register, in which you select the sleep mode (SMODE[1:0]) and enable the SLPCTRL module using the SEN bit. However, setting the SEN bit alone does not put the microcontroller to sleep. To do this, use <code>sleep_cpu()<\/code> from avr\/sleep.h.<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA-1024x85.webp\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"85\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA-1024x85.webp\" alt=\"Arduino Nano Every \/ Nano 4808 Register: SLPCTRL.CTRLA\" class=\"wp-image-19377\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA-1024x85.webp 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA-300x25.webp 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA-768x64.webp 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/Reg_SLPCTRL_CTRLA.webp 1185w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Register: SLPCTRL.CTRLA<\/figcaption><\/figure>\n\n<p>You can select from the following options for Bit Group Configurations for SMODE[1:0]:<\/p>\n<ul>\n<li>IDLE: Idle &#8211; the lightest sleep; everything is active except the CPU.<\/li>\n<li>STANDBY: Stand-by &#8211; the most flexible setting.<\/li>\n<li>PDOWN: Power Down &#8211; deep sleep.<\/li>\n<\/ul>\n<p>The deeper the sleep, the lower the power consumption and the more limited the wake-up methods. Which peripherals are available in which sleep mode can be found in the data sheet, chapter 11.3.2.1. Stand-by mode is the most flexible. Many modules have a RUNSTBY bit that determines whether the module should be available in standby mode or not.<\/p>\n\n<h3 class=\"wp-block-heading\">Example sketch for SLPCTRL <\/h3>\n\n<p>In the following example, we bring the Arduino Nano Every \/ &#8220;Nano4808&#8221; in Power Down Mode and wake it up after one second using the Periodic Timer Interrupt (PIT).<\/p>\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"power_down_pit_wake_up.ino\" data-enlighter-title=\"power_down_pit_wake_up.ino\"> #include&lt;avr\/sleep.h&gt;\n\nISR(RTC_PIT_vect){\n    RTC.PITINTFLAGS = 1;\n}\n\nvoid setup(){\n    Serial.begin(115200);\n    RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;\n    RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;\n    RTC.PITINTCTRL = RTC_PI_bm;   \n    SLPCTRL.CTRLA = SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm;  \n}\n\nvoid loop(){\n    Serial.println(\"Going to sleep...\");\n    Serial.flush();\n    sleep_cpu();\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities. The article provides an in-depth insight. <\/p>\n","protected":false},"author":1,"featured_media":19145,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[543],"tags":[2270,556,2242,2244,2245,2247,2248,2249,2256,2264,2265,2251,2254,2255,2261,2257,2246,2268,2269,2250,2252,2263,2253,1890,1565,2266,2260,2243,2267,2258,2259,1885,1887,2262],"class_list":["post-19507","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-boards-and-microcontrollers","tag-adc0-en","tag-arduino-en-2","tag-arduino-nano-every-en","tag-atmega4808-en","tag-atmega4809-en","tag-bit-group-en","tag-bit-group-configuration-en","tag-bit-mask-en","tag-ccl-en","tag-ccmp-en","tag-configurable-custom-logic-en","tag-dirset-en","tag-event-system","tag-evsys-en","tag-input-capture-en","tag-lut-en","tag-megaavr-en","tag-megacorex-en","tag-nano-4808-en","tag-outset-en","tag-outtgl-en","tag-pit-en","tag-portmux-en","tag-reset-en-2","tag-rtc-en","tag-slpctrl-en","tag-split-mode","tag-thinary-en","tag-thinaryarduino-en","tag-timer-a-en","tag-timer-b-en","tag-tinyavr-en","tag-updi-en","tag-wdt-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2023-11-30T20:40:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-31T20:51:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"960\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"58 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Arduino Nano Every &#8211; a deep dive\",\"datePublished\":\"2023-11-30T20:40:17+00:00\",\"dateModified\":\"2024-10-31T20:51:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive\"},\"wordCount\":8919,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/nano_every_post_imagemaster.webp\",\"keywords\":[\"ADC0\",\"Arduino\",\"Arduino Nano Every\",\"ATmega4808\",\"ATmega4809\",\"bit group\",\"bit group configuration\",\"bit mask\",\"CCL\",\"CCMP\",\"configurable custom logic\",\"DIRSET\",\"event system\",\"EVSYS\",\"Input Capture\",\"LUT\",\"megaAVR\",\"MegaCoreX\",\"Nano 4808\",\"OUTSET\",\"OUTTGL\",\"PIT\",\"PORTMUX\",\"reset\",\"RTC\",\"SLPCTRL\",\"split mode\",\"Thinary\",\"ThinaryArduino\",\"Timer A\",\"Timer B\",\"tinyAVR\",\"UPDI\",\"WDT\"],\"articleSection\":[\"Boards and Microcontrollers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive\",\"name\":\"Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/nano_every_post_imagemaster.webp\",\"datePublished\":\"2023-11-30T20:40:17+00:00\",\"dateModified\":\"2024-10-31T20:51:49+00:00\",\"description\":\"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/nano_every_post_imagemaster.webp\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/nano_every_post_imagemaster.webp\",\"width\":960,\"height\":960},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/arduino-nano-every-a-deep-dive#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Arduino Nano Every &#8211; a deep dive\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste","description":"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive","og_locale":"en_US","og_type":"article","og_title":"Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste","og_description":"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive","og_site_name":"Wolles Elektronikkiste","article_published_time":"2023-11-30T20:40:17+00:00","article_modified_time":"2024-10-31T20:51:49+00:00","og_image":[{"width":960,"height":960,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp","type":"image\/webp"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"58 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Arduino Nano Every &#8211; a deep dive","datePublished":"2023-11-30T20:40:17+00:00","dateModified":"2024-10-31T20:51:49+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive"},"wordCount":8919,"commentCount":5,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp","keywords":["ADC0","Arduino","Arduino Nano Every","ATmega4808","ATmega4809","bit group","bit group configuration","bit mask","CCL","CCMP","configurable custom logic","DIRSET","event system","EVSYS","Input Capture","LUT","megaAVR","MegaCoreX","Nano 4808","OUTSET","OUTTGL","PIT","PORTMUX","reset","RTC","SLPCTRL","split mode","Thinary","ThinaryArduino","Timer A","Timer B","tinyAVR","UPDI","WDT"],"articleSection":["Boards and Microcontrollers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive","url":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive","name":"Arduino Nano Every - a deep dive &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp","datePublished":"2023-11-30T20:40:17+00:00","dateModified":"2024-10-31T20:51:49+00:00","description":"The Arduino Nano Every is much more than just an upgraded Arduino Nano. Its underlying ATmega4809 opens up a wide range of possibilities.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2023\/11\/nano_every_post_imagemaster.webp","width":960,"height":960},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/arduino-nano-every-a-deep-dive#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Arduino Nano Every &#8211; a deep dive"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/19507","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=19507"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/19507\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/19145"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=19507"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=19507"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=19507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}