Wir haben jetzt einen Github-Diskussionsbereich. Wenn es sich bei einem Problem definitiv um einen Defekt im Kern handelt, verkürzen Sie die Zeit, die für die Behebung benötigt wird, wenn Sie ein Problem erstellen, da ich Probleme Vorrang vor dem Nachholen von Diskussionen gebe.
Dadurch werden viele der in 2.6.x vorhandenen Fehler behoben
2.6.x führt einen erheblich verbesserten Flash-Footprint der seriellen Schnittstelle ein und fügt gleichzeitig Funktionen hinzu, Wire kann den Slave aus dem Ruhezustand wecken, ohne Daten zu beschädigen, und vieles mehr, siehe Changelog.
Es sollten nur Versionen der Arduino IDE verwendet werden, die von arduino.cc heruntergeladen wurden, NIEMALS von einem Linux-Paketmanager. Die Paketmanager verfügen oft über die Arduino IDE – haben diese aber modifiziert . Und das, obwohl sie nichts über Arduino oder Embedded-Entwicklung im Allgemeinen wissen, geschweige denn darüber, was sie wissen müssten, um es erfolgreich zu modifizieren. Diese Versionen sind für subtile, aber schwerwiegende Probleme berüchtigt, die durch diese unklugen Modifikationen verursacht werden. Es ist nicht zu erwarten, dass dieser Kern auf solchen Versionen funktioniert, und aus diesem Grund werden keine Änderungen vorgenommen, um Versionen der IDE zu reparieren, die von Paketmanagern stammen.
Dies ist ein Fehler im Arduino-Client.
IDE-Versionen zwischen 1.8.13 und 2.x entwickelten erhebliche neuartige Mängel. IDE-Versionen 1.8.2 und früher weisen jedoch lähmende, nicht behobene Mängel auf. Ich glaube, dass sie endlich eine funktionierende Version der IDE herausgebracht haben, und ich glaube, dass die neueste Version meinen Kern korrekt installieren kann.
Vor megaTinyCore 2.6.0 führte die manuelle Installation von megaTinyCore aufgrund dieses Fehlers zum Absturz von V1.8.14 der IDE, wenn Sie den Kern manuell in Ihrem Arduino-Ordner installierten. Benutzer von 1.8.14 und höher müssen Version 2.6.0 von megaTinyCore verwenden.
Ich kaufe viele Elektronikartikel auf AliExpress. Es ist ein toller Marktplatz für Dinge, die von chinesischen Unternehmen hergestellt werden und größtenteils allgemeiner Natur sind, einschließlich einer Menge Komponenten, die für Menschen im globalen Westen auf andere Weise nicht erhältlich sind (z. B. ist die Mindestbestellmenge eine Rolle oder so etwas in der Art – falls Sie überhaupt eine finden können). Komponentenlieferant, der mit dem namenlosen chinesischen Chiphersteller zusammenarbeitet). Es ist kein guter Ort für die neuesten Halbleiterproduktlinien großer westlicher Hersteller, insbesondere angesichts der historischen Knappheit dieser Chips. Die modernen AVR-Geräte, sofern sie überhaupt über diese Kanäle verfügbar sind, werden häufig als gefälscht oder defekt gemeldet (wie ATtiny412s, die denken, sie seien 416s und führen beim Einschalten möglicherweise keinen korrekten Reset durch). Im Übrigen möchten Sie wahrscheinlich keine AVR-Mikrocontroller auf AliExpress kaufen ... Bestückte Platinen wie Arduino-Nano-Klone funktionieren im Allgemeinen, wenn Sie die mit den LGT8-Chips von Drittanbietern meiden und auf die mit dem ATmega168p achten anstelle des '328p - aber es gibt viele Berichte über gefälschte Mikrocontroller, wenn sie als Bare-Chips verkauft werden (ich habe von gefälschten ATtiny85s gehört, die tatsächlich bemerkt wurden). ATtiny13s; nicht nur moderne AVRs werden gefälscht). Es gibt viele interessante Theorien darüber, wo diese gefälschten Chips herkamen, und Microchip hat sich zu diesem Thema überhaupt nicht geäußert.
Dieses Dokument lässt sich am besten online anzeigen (anstatt die Markdown-Datei in Ihrem bevorzugten Texteditor zu öffnen), damit Links anklickbar sind und Inline-Bilder angezeigt werden, und wahrscheinlich am wichtigsten, damit Tabellen manchmal korrekt dargestellt werden. Auch dieses [Dokument kann auf Github gefunden werden](https://github.com/SpenceKonde/megaTinyCore](https://github.com/SpenceKonde/megaTinyCore)
Ältere Versionen verwalten die Programmierer im Menü „Tools -> Programmierer“ nicht richtig, was die UX mit zunehmender Anzahl der installierten Kerne schnell verschlechtert. Sie sind nicht geeignet. Die neuesten Versionen ab 1.8.14 (einschließlich 1.8.17, 1.8.18 und 1.8.19) erzeugen möglicherweise den Fehler „Panik: Keine Hauptversion gefunden“, da sie platform.txt nicht richtig analysieren können. Seit 2.6.0 haben wir die Datei „platform.txt“ direkt vor der Veröffentlichung manuell geändert, sodass dies weniger problematisch ist
Wenn megaTinyCore über den Board Manager installiert wird, wird die erforderliche Version der Toolchain automatisch installiert. Alle Teile der 0/1/2-Serie werden ohne zusätzliche Schritte unterstützt. Bis 2.2.7 verwendeten wir die Arduino7-Version von avr-gcc (gcc 7.3.0 und avrlibc 3.6.1) mit den neuesten ATpacks vom Juni 2020. Ab 2.2.7 begannen wir, meinen Azduino-Build der Toolchain zu verwenden hat ATpacks für alle neu unterstützten Teile aktualisiert. 2.2.7 verwendete Azduino3, 2.3.0+ verwendete Azduino4 und ab 2.6.0 verwenden wir Azduino5 (obwohl es für uns keinen Vorteil bietet, abgesehen von der Einsparung von einem Viertel GB Festplattenspeicher und 40 MB Download-Bandbreite, wenn Sie beides installieren). megaTinyCore und DxCore durch Vorstandsmitglied.
Die manuelle Installation ist komplizierter – insbesondere, wenn Sie Unterstützung für die 2er-Serie wünschen; Weitere Informationen finden Sie im Installationshandbuch.
Ein Arduino-Kern für die tinyAVR 0-Serie, 1-Serie und jetzt die 2-Serie. Diese Teile verfügen im Vergleich zu den „klassischen“ tinyAVR-Teilen (die von ATTinyCore unterstützt werden) über eine verbesserte Architektur, mit verbesserter Peripherie und verbesserter Ausführungszeit für bestimmte Anweisungen (diese ähneln in beiden Punkten der erweiterten AVR Dx-Serie und auch MegaAVR-0-Serie-Chips wie der ATmega4809, wie er auf dem offiziellen Nano Every und Uno Wifi Rev. 2 verwendet wird (obwohl das Arduino-Team sein Bestes getan hat, um sie in die Knie zu zwingen) in den typischen kostengünstigen, kleinen Paketen der ATtiny-Linie. Alle diese Teile verfügen über mindestens einen Hardware-UART und eine SPI- und TWI-Schnittstelle (kein USI-Müll wie zum Beispiel der ATtiny85), ein leistungsstarkes Ereignissystem, konfigurierbare benutzerdefinierte Logik und mindestens einen analogen Komparator auf dem Chip , ein überraschend genauer interner Oszillator und im Fall der 1er-Serie ein tatsächlicher DAC-Ausgangskanal und im Fall der 2er-Serie ein schicker Differential-ADC.
Darüber hinaus sind die Teile der tinyAVR 0/1/2-Serie günstig – die hochwertigsten Teile, die 3226 und 3227, mit 32 KB Flash und 3 KB SRAM (im Vergleich zum 2 KB SRAM wie der ATmega328p, der in Uno/Nano/ProMini verwendet wird). Die Stückzahl beträgt knapp über 1 USD – weniger als viele klassische 8k-AVR-ATtiny-Teile („AVR-Befehlssatz zum PIC-Preis“). Alle diese Teile sind für den Betrieb mit 16 MHz oder 20 MHz (bei 4,5–5,5 V) ohne externen Quarz ausgelegt, und der interne Oszillator ist genau genug für die UART-Kommunikation.
Diese verwenden UPDI-Programmierung und nicht den traditionellen ISP, wie es die klassischen ATtiny-Teile taten. Weitere Informationen finden Sie weiter unten. Es ist einfach, einen UPDI-Programmierer zu bekommen: Sie können mit jtag2updi einen klassischen 328p-basierten Arduino als Programmierer verwenden. Für bessere Ergebnisse mit billigerer Hardware können Sie aber auch einen beliebigen USB-Seriell-Adapter und einen Widerstand (und vorzugsweise eine Diode) mit dem mitgelieferten SerialUPDI verwenden Tool, oder Sie können AVRdude mit einem der Microchip-Programmierer (den mEDBG/nEDBG/EDBG-basierten Programmierern auf ihrem Entwicklungsboard, Atmel-ICE oder SNAP) verwenden oder jedes UPDI-Programmiertool, das eines davon emuliert (was meines Wissens alle tun – wenn es eines gibt, das avrdude unterstützt, mein Kern jedoch nicht, öffnen Sie bitte ein Issue, um es mir mitzuteilen!).
Ein serieller Bootloader, Optiboot_x (basierend auf der gleichen Codebasis wie der klassische Arduino Uno-Bootloader, allerdings inzwischen stark verändert), wird auf diesen Teilen unterstützt (Unterstützung für die 0/1-Serie ist derzeit live, die 2-Serie wird für die erste Maiwoche erwartet). ; Anpassungen für die neuen Teile sind trivial), sodass sie über eine herkömmliche serielle Schnittstelle programmiert werden können. Weitere Informationen hierzu und die relevanten Optionen finden Sie im Abschnitt Optiboot weiter unten. Für die Installation des Bootloaders ist ein UPDI-Programmierer erforderlich. Die zusammengebauten Breakout-Boards, die ich auf Tindie verkaufe, sind vorgebootet erhältlich (sie werden auf Anfrage gebootet). Allerdings ist die Benutzererfahrung mit Optiboot sowohl bei den Teilen der 0/1-Serie als auch bei den 14-Pin-Teilen der 2-Serie etwas enttäuschend, da ihnen ein Hardware-Reset-Pin fehlt, der mit der üblichen Autoreset-Schaltung verwendet werden könnte automatisch in den Bootloader zurückgesetzt, wenn die serielle Schnittstelle geöffnet wird. Sie müssen entweder die UPDI-Programmierung vollständig deaktivieren (es ist ein HV-Programmierer erforderlich, wenn die Sicherungseinstellungen oder der Bootloader nach dem ersten Bootloaden geändert werden müssen) oder UPDI aktiviert lassen, aber jeden Upload innerhalb von 8 Sekunden nach dem Anlegen der Stromversorgung starten. Die 20-Pin- und 24-Pin-Teile der 2er-Serie unterstützen einen „alternativen Reset-Pin“, sodass diese eher wie ein herkömmliches Arduino funktionieren.
Die UPDI-Programmierschnittstelle ist eine Single-Wire-Schnittstelle zum Programmieren (und Debuggen – Universal P rogramming and D ebugging Interface ), die auf der tinyAVR 0/1/2-Serie sowie allen anderen modernen AVR-Mikrocontrollern zum Einsatz kommt . Man kann zwar jederzeit einen speziell angefertigten UPDI-Programmierer von Microchip erwerben, dies wird jedoch nicht empfohlen, wenn Sie die Arduino-IDE anstelle der (ungeheuer komplizierten) IDE von Microchip verwenden. Es gibt zahlreiche Berichte über Probleme unter Linux für die offiziellen Microchip-Programmierer. Es gibt zwei sehr kostengünstige alternative Ansätze zur Erstellung eines UPDI-Programmierers, mit denen die Arduino-Community beide mehr Erfahrung hat als diese offiziellen Programmierer.
Bevor megaTinyCore existierte, gab es ein Tool namens pyupdi – ein einfaches Python-Programm zum Hochladen auf mit UPDI ausgestattete Mikrocontroller mithilfe eines seriellen Adapters, der durch Hinzufügen eines einzelnen Widerstands modifiziert wurde. Da Pyupdi jedoch nicht ohne weiteres über die Arduino-IDE verwendet werden konnte, war dies keine Option. Ab 2.2.0 bringt megaTinyCore eine portable Python-Implementierung mit, die viele Türen öffnet; Ursprünglich hatten wir geplant, Pyupdi anzupassen, aber auf Drängen des Autors und mehrerer Mitarbeiter von Microchip haben wir diese Funktionalität stattdessen auf Pymcuprog basiert, einem „robusteren“ Tool, das von Microchip entwickelt und „verwaltet“ wurde und den gleichen Upload über die serielle Schnittstelle beinhaltet Funktion, nur ohne die Leistungsoptimierungen. Bei einer manuellen Installation müssen Sie das für Ihr Betriebssystem geeignete Python-Paket hinzufügen, um diese Upload-Methode verwenden zu können (eine Python-Systeminstallation reicht nicht aus und ist auch nicht erforderlich).
Informationen zur Verkabelung finden Sie in der SerialUPDI-Dokumentation .
Ab 2.3.2 ist dies aufgrund der dramatischen Leistungsverbesserungen und der nachgewiesenen Zuverlässigkeit des Verkabelungsschemas mit einer Diode anstelle eines Widerstands und angesichts der Unzulänglichkeit der jtag2updi-Firmware nun die empfohlene Programmiermethode. Ab dieser Version wurde die Programmiergeschwindigkeit um den Faktor 20 erhöht und übertrifft nun bei weitem das, was mit jtag2updi möglich war (die Programmierung über jtag2updi ist in der Geschwindigkeit in etwa vergleichbar mit der Programmierung über SerialUPDI bei der Geschwindigkeitsoption „SLOW“, 57600). Baud; die normale 230400-Baud-Version programmiert etwa dreimal schneller als die SLOW-Version oder jtag2updi, während die Option „TURBO“ (läuft bei 460800 Baud und erhöht die Upload-Geschwindigkeit um etwa 50 % gegenüber der normalen Version. Die TURBO-Geschwindigkeitsversion sollte nur mit Geräten verwendet werden, die mit 4,5 V oder mehr laufen, da wir den UPDI-Takt schneller laufen lassen müssen, um mithalten zu können (dies ist auch nicht zu erwarten). um mit allen seriellen Adaptern kompatibel zu sein (dies ist ein bewusster Kompromiss für eine verbesserte Leistung), aber es ermöglicht das Hochladen und Überprüfen einer 32-kB-Skizze in 4 Sekunden.
Es werden drei Designs entwickelt: Ein serieller Dual-Port-Adapter, bei dem es sich bei beiden um serielle Ports handelt, ein serieller Dual-Port-Adapter, bei dem ein Port immer UPDI ist, und ein Single-Port-Adapter mit einem Schalter zur Auswahl des Modus und einer optionalen Zusatzplatine LEDs zeigen den Status der Modem-Steuerleitungen an.
Diese ermöglichen die Verwendung eines SMT-JST-XH-Steckers oder eines Dupont-Steckers – in beiden Fällen mit 6 Pins für seriell (FTDI-Pinbelegung wie markiert) und 3 Pins (für UPDI).
Alle drei können 3,3 oder Vusb (nom. 5 V) liefern oder sowohl Vusb als auch 3V3 vom Strom trennen und davon ausgehen, dass das Zielgerät mit 5,5 V > Vdd > 1,8 V versorgt wird. Die in diesem Fall verwendeten Logikpegel sind die angelegten Spannungen. Seien Sie gewarnt, dass bei dualen seriellen Geräten die VccIO-Stromschiene gemeinsam genutzt wird! Sie müssen beide mit der gleichen Spannung betrieben werden, es muss sich um dasselbe Gerät handeln, oder der Adapter muss so eingestellt sein, dass er sie versorgt, und ihre Stromversorgung muss unterbrochen sein.
Es wurde festgestellt, dass je nach Adaptermodell und Betriebssystem unterschiedliche Timing-Einstellungen erforderlich sind; Die Einstellungen, die erforderlich sind, um zu verhindern, dass selbst 230400 Baud unter Linux/Mac mit den meisten Adaptern fehlschlagen, führen jedoch zu einer viel größeren Zeitstrafe unter Windows, wo die serielle Verarbeitung des Betriebssystems langsam genug ist, dass diese Verzögerung nicht erforderlich ist ...
Die hier erwähnte „Schreibverzögerung“ dient dazu, die Ausführung des Befehls „Seite löschen/schreiben“ zu ermöglichen; Dies dauert eine Zeit ungleich Null. Abhängig vom Adapter, der USB-Latenz und dem impliziten 2- oder 3-Byte-Puffer (es ist wie ein USART und wahrscheinlich intern als solcher implementiert. Das dritte Byte, das ankommt, kann nirgendwo hingehen, da der Hardware-Puffer nur 2 Byte tief ist). genug, damit es ohne explizite Verzögerung funktionieren kann. Oder es schlägt möglicherweise mittendrin fehl und meldet einen „Fehler mit st“. Je schneller das Latenzzeitlimit des Adapters und je schneller die serielle Verarbeitung des Betriebssystems ist, desto größer ist die Wahrscheinlichkeit, dass dies ein Problem darstellt. Dies wird durch den Befehlszeilenparameter -wd
gesteuert, wenn prog.py manuell ausgeführt wird. Ab 2.5.6 liegt diese Schreibverzögerung näher an der tatsächlich angeforderten Zeit (in ms), zuvor hatte sie eine Granularität von mehreren ms, wobei 1 alles war, was Sie brauchten, und infolgedessen war die Strafe, die sie verhängte, besonders brutal Windows.
Auswahlhilfe:
FTDI-Adapter (FT232, FT2232 und FT4232 usw.), einschließlich der gefälschten, die bei eBay/AliExpress für etwa 2 US-Dollar erhältlich sind, haben unter Windows standardmäßig eine quälend lange Latenzzeit von 16 ms. Auch wenn wir so viel Aufwand betreiben, um die Anzahl der Wartezeiten zu begrenzen, verlängert sich ein Upload von 2,2 Sekunden auf über 15 Sekunden. Sie müssen dies ändern, um tolerierbare Upload-Geschwindigkeiten zu erhalten:
Einer kann aus einem klassischen AVR Uno/Nano/Pro Mini hergestellt werden; Die übliche Wahl sind kostengünstige Nano-Klone, die so günstig sind, dass man sie verkabeln und dann so belassen kann. Für diese Prozesse stellen wir keine detaillierte Dokumentation mehr zur Verfügung; jtag2updi ist veraltet. Wenn Sie es noch verwenden, sollten Sie jtag2updi aus dem Menü „Tools->Programmer“ auswählen. Dies war zuvor unsere empfohlene Option. Aufgrund der anhaltenden jtag2updi-Fehler und der Abhängigkeit vom größtenteils nicht gepflegten Tool „avrdude“ (das unter anderem eine falsche Fehlermeldung in alle damit durchgeführten UPDI-Uploads einfügt) wird dies nicht mehr empfohlen.
Anscheinend packt Arduino keine 32-Bit-Versionen des neuesten Avrdude ein. Ich habe eine neue Tooldefinition definiert, die eine Kopie von arduino18 (der neuesten Version) ist, mit der Ausnahme, dass sie stattdessen Version 17 auf 32-Bit-Linux zieht, da dies das Beste ist, was für diese Plattform verfügbar ist. Die Arduino17-Version unterstützt das Hochladen mit einigen Microchip-Programmiertools nicht korrekt.
Dies wird derzeit nur für die letzten Versionen verwendet und sollte den Fehler „avrdude not available for this platform“ beheben.
Sehen Sie sich dieses Dokument an, das alle modernen AVRs abdeckt
Besonderheit | 0-Serie | 1er-Serie | 1+Serie | 2er-Reihe |
---|---|---|---|---|
Blitz | 2k-16k | 2k-8k | 16k/32k | 4k-32k |
Pincount | 8-24 | 8-24 | 14-24 | 14-24 |
SRAM | 128b-1k | 128b-512b | 2k | 512b-3k |
TCD | NEIN | Ja | Ja | NEIN |
TCB | 1 | 1 | 2 | 2 |
ADC | 1x10bit | 1x10-Bit | 2x10-Bit | 1x12-Bit mit PGA |
VREF-Pin | NEIN | NEIN | Ja | Ja |
Wechselstrom | 1 | 1 | 3 | 1 |
Ereignis * | 3 Chan | 6 Chan | 6 Chan | 6 Chan |
CCL ** | 2 LUT | 2 LUT | 2 LUT | 4 LUT |
*
Ereigniskanäle, außer bei den tinyAVRs der 2er-Serie (und allen nicht-tiny modernen AVRs), werden in zwei Typen unterteilt – synchron (zur Systemuhr) und asynchron. Nicht alle Generatoren können mit einem synchronen Kanal verwendet werden, und einige Event-Benutzer können nur die synchronen Kanäle verwenden, und die Kanallisten sind weniger konsistent und mehr. Dieser Wahnsinn wurde bei der ersten Gelegenheit aufgegeben – selbst die Mega0 hatte diese Unterscheidung abgeschafft.
**
Nur 2-Serien- und nicht-winzige Teile können einen Interrupt basierend auf dem CCL-Status auslösen.
Alle Teile verfügen über einen analogen Eingang an den meisten Pins (alle Pins an PORTA und PORTB 0-1 und 4-5). Der zweite ADC der 1er-Serie+ kann die Pins an PORTC ebenfalls als Eingänge verwenden (Informationen zur Verwendung dieser Pins finden Sie in der analogen Referenz).
Dies sind die Budgetoptionen. Obwohl sie unterstützt werden, werden sie nicht empfohlen. Diese erhalten nie den „Boost“, den die tinyAVR 1-Serie bei 16k erhält, haben in keiner Konfiguration einen zweiten TCB, keinen TCD, nur 3 Ereigniskanäle, von denen keiner die RTC-Ereignisausgabe übertragen kann. Diese Teile verfügen wie die 1er-Serie über 2 CCL-LUTs und sind mit bis zu 16.000 Flash in 14-, 20- und 24-Pin-Konfigurationen (nur 4.000 für 8-Pin-Teile) und bis zu 1.000 SRAM erhältlich.
Diese haben 2K, 4K oder 8K Flash und 128, 256 oder 512b RAM, genau wie die 0-Serie. Sie verfügen nicht über den zweiten ADC, die Dreifach-AC-Konfiguration oder den zweiten TCB, wohl aber über den TCD.
Plötzlich, bei 16k, werden die 1er-Teile viel interessanter. Begleitet wird der größere Flash von einem Arsenal an Peripheriegeräten, die für einen viel größeren Chip geeignet zu sein scheinen, und ob 16k oder 32k, alle verfügen über 2k SRAM. Der gesamte zweite ADC ist einzigartig unter den AVRs. Es scheint das Testgelände für viele Funktionen gewesen zu sein, die in verfeinerter Form in der AVR Dx-Serie zum Einsatz kamen. Der Preis scheint die weitaus besseren Peripheriegeräte der 16k-1er-Serie nicht zu berücksichtigen.
Wie Sie der Tabelle oben entnehmen können, handelt es sich bei der 2er-Reihe fast eher um einen Sidegrade denn um ein Upgrade. Sie haben einen viel besseren ADC, das Event-System und die CCLs sind „normal“, und sie haben mehr RAM, der 14-Pin-Teil ist mit 32k Flash verfügbar (ein 3214 war offenbar geplant, wurde dann aber abgesagt; es kam weit genug dazu eine Weile im ATPACK bleiben, bevor es entfernt wird)
Ich habe eine kurze Zusammenfassung geschrieben, wann Sie welche Serie verwenden möchten, wenn die richtige Wahl noch nicht klar ist.
In der offiziellen Arduino-Board-Definition für ihr „megaavr“-Hardwarepaket implizieren sie, dass die neue Architektur auf den Teilen der megaAVR 0-Serie (die fast die gleiche ist wie die der tinyAVR 0-Serie und 1-Serie) „megaavr“ heißt „ – das ist kein offizieller Begriff. Microchip verwendet den Begriff „megaAVR“ für jedes „ATmega“-Teil, unabhängig davon, ob es über alte oder moderne Peripheriegeräte verfügt. Es gibt keine offiziellen Begriffe, die sich auf alle AVR-Teile der einen oder anderen Familie beziehen, und ein Mitarbeiter von Microchip bestritt sogar, dass es intern einen solchen Begriff gebe. Ich bin mir nicht sicher, wie man zwei Sätze von Teilen herstellen kann, wobei die Teile in jedem Satz so viel miteinander und so wenig mit dem anderen Satz gemeinsam haben und niemand einen Begriff für einen der beiden Sätze prägt.
In diesem Dokument haben wir vor 2.0.2 die Arduino-Konvention verwendet, und obwohl seitdem weit über ein Jahr vergangen ist, finde ich immer noch Stellen, an denen ich sie MegaAVR nenne. Bitte melden Sie dies mithilfe eines Github-Problems, falls Sie eines sehen. Beachten Sie, dass die Begriffe avr
und megaavr
immer noch intern verwendet werden (z. B. in Bibliotheken, um zu kennzeichnen, mit welchen Teilen eine bestimmte Bibliothek kompatibel ist, oder um verschiedene Versionen einer Datei danach zu trennen, worauf sie ausgeführt werden sollen). Das wird so weitergehen – wir müssen dabei bleiben, um die Kompatibilität mit dem zu gewährleisten, was das Arduino-Team mit dem Kern für Uno WiFi Rev. 2 und Nano Every begonnen hat.
Auf jeden Fall bedarf es einiger Worte, um sich auf die beiden Gruppen zu beziehen, und Microchip hat keines bereitgestellt. In Ermangelung eines offiziellen Begriffs bezeichne ich die AVR-Geräte vor 2016 (mit PORTx-, DDRx- usw. Registern für Pins) als „ klassischer AVR “ und diejenigen, die Arduino Megaavr nennt, als „ moderne AVR “. Es gibt auch einige Teile, deren I/O-Module weitgehend klassischen AVRs ähneln, die aber auch eine deutlich schlechtere Version des Befehlssatzes und typische Flash-Größen von 1k oder weniger haben. Diese verwenden die AVRrc-Variante (für reduzierten Kern) von AVR, während die meisten klassischen AVRs AVRe oder AVRe+ verwenden und moderne AVRs AVRxt verwenden. Die AVRrc-Teile werden von diesem Kern nicht unterstützt, und in dem unglücklichen Fall, dass ich diese zutiefst enttäuschenden Teile besprechen muss, werde ich sie als „ Reduced Core AVR “-Teile bezeichnen, da dies ihr offizieller Name ist, auch wenn ich viele davon habe buntere Sätze für sie. Es wird empfohlen, dass kein Design einen reduzierten Kern-AVR verwendet. Nicht, dass sie veraltet wären, sie sind einfach nur mies. Es wird empfohlen, für alle neuen Designs „ moderne AVRs “ (solche mit den neuen Peripheriegeräten und dem AVRxt- Befehlssatz) – entweder Ex-Serie, Dx-Serie, tinyAVR 0/1/2 oder Mega0 – zu verwenden
Datenblatt für die neue tinyAVR 2-Serie – Während das Datenblatt nur die 16k-Teile „abdeckt“, heißt es eindeutig, dass es keine Unterschiede in den Merkmalen zwischen Teilen mit der gleichen Pin-Anzahl gibt (das heißt, es gibt keine „goldenen“ Teile wie die 16k/32k 1-Serie), nur zwischen Teilen mit unterschiedlicher Pin-Anzahl und nur wie durch die Pin-Anzahl vorgegeben (d. h. eine Funktion am 24-Pin-Teil befindet sich auch am 14-Pin-Teil). (es sei denn, der 14-polige hat nicht die benötigten Pins und kann ohne Pins nicht verwendet werden). 14-, 20- und 24-Pin-Teile sind alle mit 4k-, 8k-, 16k- und 32k-Flash aufgeführt; Diese Flash-Größenoptionen verfügen jeweils über 512, 1024, 2048 und 3072 Byte SRAM (d. h. die 4k- und 8k-Teile haben das Doppelte des SRAM), 4/8k-Teile erhalten 128 Bytes EEPROM, die größeren erhalten 256 14-polige Teile gibt es in SOIC und TSSOP, 20-polige in (breitem) SOIC, SSOP und so weiter klitzekleines QFN wie das 1616 (dieses Mal gaben sie uns auch den 32k-Teil in diesem Paket, aber viel Glück beim Erhalten eines, es ist überall nachbestellt – ich konnte kein einziges finden) und 24-polig im gleichen VQFN wie das 3217.
TWI, SPI, USART0, AC0 bleiben unverändert, ebenso NVMCTRL (die am Bootloader erforderlichen Änderungen betrafen ausschließlich die Unterstützung des zweiten USART). Uhroptionen unverändert. TCB0 und TCB1 wurden auf die Version der Dx-Serie aktualisiert: Clock-Off-Event-Option, Kaskade und separate INTCTRL-Bits für OVF und CAPT – nette Ergänzungen, aber nichts Relevantes für den Kern selbst), und alle Teile haben beide TCBs. Wir erhalten jetzt 4 CCL-LUTs und 2 Sequenzer, statt 2 und 1 – und sie können wie andere Teile mit CCL Interrupts auslösen (und im Gegensatz zur tinyAVR 0/1-Serie). Eines der aufregendsten Features ist, dass sie erwartungsgemäß über einen zweiten USART verfügen (das Geräusch, das Sie hören, ist das Schluchzen des ATtiny841 und des ATtiny1634 in der Ecke). PORTMUX-Register werden jetzt wie die übrigen modernen AVRs benannt – wir haben jedoch nicht die individuelle Kontrolle über die Pins für jeden TCA WO-Kanal verloren. EVSYS funktioniert jetzt genauso wie bei nicht winzigen Teilen der AVR-0/1-Serie (was eine willkommene Abwechslung ist – die 0/1-Serie war das Sondermodell, und einige der Unterschiede bei EVSYS waren beschissen ). Die 1er-Funktionen von TCD0, AC1/2, DAC0 und ADC1 sind weg . Stattdessen ist ADC0 viel schicker und fast nicht wiederzuerkennen, der erste neue AVR seit der Übernahme, der über einen echten Differential-ADC verfügt. (Ein weiterer gequälter Schrei des armen 841, der ebenfalls über einen unglaublich schicken ADC mit großartigen Differentialoptionen verfügt, der aber neben den neuen völlig veraltet aussieht) ... gemessen an der Menge an Beiträgen zu verschiedenen Themen, die ich habe Ich habe das Gefühl, dass der Differential-ADC auf den meisten Ihrer Wunschlisten nicht ganz oben stand – aber er stand ganz oben auf der Wunschliste der großen Chipkunden, und das ist es, was wir bekommen. Und es war fast an der Zeit, dass wir einen richtigen Differential-ADC anstelle des der Dx-Serie bekommen. Und es ist wirklich sehr, sehr schick. Siehe unten.
megaTinyCore bietet eine analogRead()-Implementierung und leistungsfähigere Funktionen zur Nutzung von Oversampling und PGA (siehe den Abschnitt über die analogen Funktionen unten).
Oh, und noch etwas … die UPDI-Pin-Konfiguration hat die alten Optionen – UPDI, I/O oder Reset … und eine neue: UPDI auf PA0, mit Hardware-RESET-Pin auf PB4! Optiboot wird endlich eine praktikable und komfortable Option sein, zumindest für die Teile, die über einen PB4 verfügen, also nicht für die 14-Pin-Teile. Was zufälligerweise auch die beliebteste Sorte ist (wenn man von meinen Tindie-Ladenverkäufen ausgeht).
Glauben Sie, dass es eine 3er-Reihe geben wird? Ich nicht. DD und die EAs verfolgen sie eindeutig und nehmen strategische Positionen rund um das TinyAVR-Territorium ein. Ich denke, es ist nur eine Frage der Zeit, bis die Marke eliminiert wird, wie es bei megaAVR nach der megaAVR 0-Serie der Fall war. Das ist nicht unbedingt eine schlechte Sache: Alle Teile der Dx- und EA-Serie sind in der Pinbelegung und im Verhalten sehr ähnlich, was sehr schön ist. Die Tinys sind weniger systematisch, obwohl sie die Pins an mehr Peripheriegeräte verteilen. Das Leitprinzip scheint gewesen zu sein: „Kein Peripheriegerät bleibt zurück“. Im Gegensatz zu den Pin-Zuordnungen der Dx- und EA-Serien, bei denen alles einem festen Masterplan folgt. Teile haben entweder einen bestimmten Pin oder nicht, und wenn nicht, steht ihnen diese Funktion nicht zur Verfügung. Ich glaube, dass es in beiden großen Gruppen einen Produktmanager gibt, dessen Aufgabe es ist, Ingenieuren, die darüber nachdenken, eine „Ausnahme“ von der Heiligen Pinbelegung zu machen, eine Peitsche zu verpassen (da sich diese Ausnahmen unweigerlich vermehren und wir am Ende zu den Pinbelegungen für die Dartscheibe mit verbundenen Augen gekommen sind). auf klassischem tinyAVR)
Die Pin-Nummerierung ist bei den tinyAVRs seltsam, und es ist die Schuld von Microchip – sie haben die Pins innerhalb der Ports seltsam nummeriert: Es beginnt in der richtigen Reihenfolge, außer dass PA0 UPDI ist und im Allgemeinen nicht verwendbar ist, dann sind die Pins von PORTB in umgekehrter Reihenfolge nummeriert. dann PORTC zurück zur gleichen Nummerierung gegen den Uhrzeigersinn wie PORTA. Gib mir eine Pause! Traditionell wird Pin 0 als erster Pin verwendet und die letzte Zahl ist der Pin, den Sie nicht verwenden können, ohne eine Sicherung zu setzen, die die Programmierung des Chips erschwert. Ich hätte sie viel lieber gegen den Uhrzeigersinn nummerieren können, beginnend mit A0, ohne ungeschriebene Konventionen des Arduino-Codes zu brechen. Man kann argumentieren, dass ich bei der Pinbelegung eine schlechte Entscheidung getroffen habe – vielleicht hätten sie mit PA0 (unbrauchbar, es sei denn, die Sicherung ist gesetzt, in diesem Fall ist der Chip schwer zu programmieren) als Pin 0 beginnen und dann die Pins gegen den Uhrzeigersinn nummerieren sollen. Aber wenn alle Ports in Ordnung wären, könnten Sie immer noch nicht die Tricks machen, die Sie könnten, es sei denn, Sie nummerieren die PORTB-Pins rückwärts. Wenn Sie die Erwartung loswerden könnten, dass alle Pins der Reihe nach nummeriert werden (und nur die PIN_Pxn-Notation verwenden), könnten erhebliche Einsparungen erzielt werden
Ich gehe davon aus, dass es in 2-4 Jahren einen AVR DA, DB, DD geben wird. DU- (USB-), EA- und D/E/F-Serienteile bis zu einer Pinanzahl von 8 (oder mindestens 14) und 64-Pin-Teile mit 128k-Flash und dem neuen ADC. Und nichts anderes mit der Marke ATtiny. Die größte verbleibende Frage ist möglicherweise, ob sie den ATmega2560 jemals durch einen modernen AVR mit insgesamt 100 Pins (wahrscheinlich 80-88 davon I/O) und Flash-Optionen bis zu 256 KB ersetzen werden. Das würde drei Probleme mit sich bringen: Erstens sind über 56 I/O-Pins hinaus keine VPORT-Register mehr übrig – der untere I/O-Bereich ist mit 28 VPORT und 4 GPIORs voll. Wie werden sie mit den 4 zusätzlichen Ports umgehen? (Beim 2560 handelte es sich nur um Ports zweiter Klasse, auf die langsamer zugegriffen wurde und die keinen Single-Cycle-Zugriff hatten. Ich habe einige Überlegungen dazu und die Machbarkeit angesichts der wenigen Opcodes, die hier in Anhang A verfügbar sind. Und zweitens, um einen Verstoß zu verhindern In der 128-K-Barriere müssen Sie zu einem 17-Bit-Programmschalter gehen. "D x Teil bei 256 km Flash hätte 32.000 Ram. Jetzt erinnern sich Zugeordneter Blitz, hinterlässt keinen Raum für die SFRs, die sich im gleichen Adressraum befinden.
Ich verkaufe Breakout -Boards mit Regulierungsbehörde, Updi Header und Serienheader in meinem Tindie -Shop sowie in den bloßen Brettern. Der Kauf in meinem Geschäft unterstützt die weitere Entwicklung im Kern und ist eine großartige Möglichkeit, diese aufregenden neuen Teile mit Arduino zu verwenden. Derzeit sind Attiny1624 Boards erhältlich, aber die 20- und 24-poligen Teile werden erst als versammelte Board verkauft, wenn ein neu überarbeitetes PCB-Design vom Board House zurückkommt, um Autoreset am Alt-Re-Re-Re-Re-Re-Re-Reset-Pin zu aktivieren. Es kommt auch eine 14 -polige Board -Revision - dachte, sie sei weitgehend kosmetisch. Die gelbe Lötmaske muss gehen, da sich die Lesbarkeit in den letzten verschiedenen Chargen verschlechterte. Die neuen Bretter standardisieren auch einen Abstand von 0,6 "zwischen den Stiftenreihen anstelle des Stromabstand Verwenden Sie sie mit unserer Prototyping -Karte, die für diesen Zeilenabstand optimiert ist. Die montierten Boards der 0er-Serie werden eingestellt und werden nicht wieder aufgenommen, sobald sie ausverkauft sind. Gleiches gilt für die Teile der 16K 2-Serie, sobald die 32K-Teile verfügbar sind.
Die ADC in der 2er- und EA-Serie sind die besten ADCs, die in der modernen AVR-Ära auf einem AVR veröffentlicht wurden. Neben diesen beiden. Die engsten Vergleiche sind die klassischen AVRs, die unterschiedliche ADCs mit erstklassigen Merkmalen erhielten (T841, MEGA2560 und (überraschend) der T861 ist die stärksten Konkurrenten). Obwohl es nicht in der Lage ist, den verrückten 100 -fachen und 200 -fachen Gewinn zu erzielen, den einige Teile in den klassischen AVR -Tagen prahlten, war mir nie klar, wie viel von dem, was verstärkt wurde Ich werde sagen "Wahrscheinlich das meiste davon, und das meiste davon, wenn Sie mich die Hardware entwerfen lassen, weiß ich nicht analog!"). Dieser neue ADC ist sicherlich sehr fähig, mit echten Differentialfähigkeiten (im Gegensatz zur DA- und DB -Serie) und eines, das über alles aufsteigt, was bisher auf anderen modernen AVRs verfügbar ist. Der programmierbare Verstärkerverstärker ist eine neue Fähigkeit, und es bleibt abzuwarten, welche Art von Leistungen der analogen Messung Menschen herausholen können. Es erscheint sicherlich vielversprechend. Es wird besonders interessant sein, die Unterschiede zwischen der Verwendung der PGA bei 1x Gewinn zu verstehen, gegenüber der Verwendung der PGA nicht und den Vorteilen und Nachteilen. (Microchip wäre durch ein Dokument, in dem in dem allgemeinen Fall die richtige ADC-Konfiguration für eine Aufgabe ausgewählt werden soll Die Situation wurde stark verbessert, es scheint immer noch, dass die DOC -Gruppe ausdrücklich angewiesen wurde, keine konkreten Empfehlungen jeglicher Art abzugeben .
Die Zugabe von 1024-Stichproben-Akkumulation für die Zwecke von Überabtastung und Dezimierung ist eine willkommene Ergänzung, die jedoch auch besteht, die Größe und Relevanz des Offset-Fehlers zu unterschätzen. (Entnehmen Sie 1024 Proben (alle haben einen gegebenen Versatzfehler Wurde, beispielsweise 5 LSB, bei einer einzigen Messung, wenn Sie 1024 Proben und Dezimate akkumulieren, haben Sie einen Offset -Fehler von 160, es ist äußerst leicht zu erkennen und zu glauben, dass es kein Geräusch ist.
Der erste Full-Size-Chip (Non-Ziny) mit dem neuen ADC ist in 28-48-Pin-Paketen mit einem Blitz von bis zu 64.000 erhältlich. Es gab die üblichen Spekulationen darüber, was, wenn sich etwas von 2 Serien in die EA-Serie ändern würde: Es sieht so aus, als ob die Antwort ist, einer der verwirrenden Knöpfe entfernt wurde und automatisches Schilderhacking für akkumulierte Messungen ((
Der Timer vom Typ D wird nur für PWM auf Teilen von 20/24 Pin 1-Serie in den Standard-PWM-Pin-Einstellungen verwendet. Bei den kleineren Teilen würde es uns nicht die Gesamtzahl der PWM -Stifte erhöhen. Nur die WOC- und WOD-Stifte (auf PC0 bzw. PC1) haben noch keine TCA-gesteuerte PWM. Da Analogwrite () keine Funktionen unterstützt, die durch das Ausschalten des Split-Modus (wie 16-Bit-PWM) oder durch die Verwendung des Timers vom Typ D (wie das Anpassen der Frequenz) aktiviert werden, wäre dies nur schlimmer, weil Es würde zusätzlichen Platz erfordern, um die Routine zu speichern, um PWM von zwei Timer -Arten ein- und auszuschalten. Dies ist bei den kleineren Blitzteilen nicht vernachlässigbar; Es befindet sich in der Größenordnung von 600 Bytes. 150 für digitalwrite () und 450 für analogwrite (), wenn diese jemals einen TCD -PWM -Pin aufgerufen werden. Der Optimierer sollte in der Lage sein, diesen Teil dieser Funktionen in diesem Fall zu optimieren, da lange die mit diesen Funktionen verwendeten Stifte keine TCD -PWM -Pins enthalten. Beachten Sie, dass der Optimierer sie unabhängig betrachtet, dh Digitalwrite () wird den Code zum Ausschalten von TCD PWM enthalten, wenn er mit einem PIN verwendet wird, der TCD für PWM verwendet, unabhängig davon, ob Sie analogwrite () an diesem Pin jemals aufrufen oder nicht.
Im Gegensatz zu fast jedem anderen AVR (ich kann mir vielleicht 3 Beispiele vorstellen, und nur einer von ihnen ist ein "Bonus", kein "Unnonus"), gibt es zusätzliche "Bonus" -Funktionen, die auf der Blitzgröße von Teilen innerhalb einer Familie basieren, in einer Familie, . Die 16K- und 32K -Versionen (nur) haben einige zusätzliche Funktionen (die auch anscheinend auch nicht für die Preisgestaltung in Betracht gezogen worden zu sein scheinen) alle 2K RAM, ob 16K oder 32K, sie haben 3 analoge Komparatoren (einschließlich eines Fenstermodus Option), eine zweite - dringend benötigte - Timer vom Typ B - und seltsamsten von allem, was sie haben, haben eine zweite ADC, die sich nur unterscheidet, in denen die Kanäle entsprechen!
Im Gegensatz zu klassischen AVRs wird der Blitz in diesen Teilen dem gleichen Adressraum wie der Rest des Speichers zugeordnet . Dies bedeutet pgm_read_*_near()
nicht direkt von Flash lesen wird. Aus diesem Grund setzt der Compiler automatisch jede variable deklarierte const
in Progmem ein und greift darauf zu. Sie müssen sie nicht mehr explizit als Progmem deklarieren. Dies schließt zitierte String -Literale ein, sodass das F () -Makro auch nicht mehr benötigt wird, um die Kompatibilität mit einigen Bibliotheken von Drittanbietern aufrechtzuerhalten.
Beachten Sie jedoch, dass Sie, wenn Sie explizit eine variable Progmem deklarieren, die pgm_read
-Funktionen verwenden müssen, um sie genau wie auf klassischen AVRs zu lesen. Wenn eine Variable auf Teilen mit dem speichergebundenen Blitz progmem deklariert wird, ist der Zeiger ausgefallen (die Adresse ist relativ zum Start des Flashs, nicht zum Start des Adressraums). Der gleiche Offset wird angewendet, wenn das pgm_read_*_near()
Makros verwendet wird. Beachten Sie, dass das Deklarieren von Dingen Progmem und Zugriff auf pgm_read_*_near
Funktionen, obwohl es einwandfrei funktioniert, langsamer ist und eine kleine Menge Blitz verschwendet (im Vergleich zur einfacher Deklaration der Variablen const); Gleiches gilt für das F () -Makro mit konstanten Zeichenfolgen in 2.1.0 und später (für einen bestimmten Zeitraum vor 2.1.0, F()
tat nichts - das verursachte Probleme für Bibliotheken von Drittanbietern). Die Autoren behaupteten, dass das Problem mit dem Kern und nicht mit der Bibliothek gewesen sei, und ich habe die Wahl darin, weniger Effizienz zu akzeptieren oder meinen Benutzern den Zugriff auf beliebte Bibliotheken zu verweigern). Die Verwendung des F()
-Makro kann für die Kompatibilität mit einigen Bibliotheken von Drittanbietern erforderlich sein (die spezifischen Fälle, die die Rückkehr von F()
auf uns erzwangen, waren nicht von dieser Art - wir konnten diejenigen, die ich wusste, mit dem wusste F ()-AS-NOOP-Code, und sie haben ein paar Bytes weniger Blitz aufgenommen).
Die Automobilversionen sollten ebenfalls funktionieren. Sie müssen immer die 16 MHz abgeleiteten Taktgeschwindigkeiten für diese Teile auswählen. Sie unterstützen keinen 20 -MHz -Betrieb, und es sollten nicht abgestimmte Taktoptionen verwendet werden.
Nun zum guten Teil, wo wir darüber sprechen können, wie all dies von Megatinycore entlarvt wird. Wir beginnen mit der Frage, wie Sie sich auf die besten Ergebnisse verweisen und dann zu den Kernfunktionen und Menüoptionen übergehen, bevor Sie mit einer Reihe von Links zu Dokumenten mit Details zu verschiedenen Subsystemen enden.
Die einfache Angelegenheit, wie man sich auf einen PIN für Analograd () und DigitalRead (), insbesondere auf nicht standardmäßige Hardware, bezieht, war bei Arduino-Benutzern eine anhaltende Quelle der Verwirrung. Ich bin der Meinung, dass ein Großteil der Schuld bei den Entscheidungen des Arduino -Teams (und Autor von Draht vor ihnen) darüber beruht, wie Stifte genannt werden sollten; Die Bezeichnung einiger Stifte als "analoge Pins" lässt die Menschen glauben, dass diese Stifte nicht für digitale Operationen verwendet werden können (sie werden besser als "Stifte mit analogen Eingang" angesehen - wie es "Stifte, die PWM ausgeben können"). Die Tatsache, dass Pins traditionell nummeriert wurde, hat das Wasser weiter verwirrt. Für nicht standardmäßige klassische AVR-Teile werden die Angelegenheiten oft noch schlechter durch mehrere, inkompatible "Pin-Mappings", die von verschiedenen Autoren im Laufe der Jahre erstellt wurden, um das Teil eher wie eine Uno oder für einen anderen Zweck zu handeln (ATTINYCORE ist eine besondere Mach auf diese Weise, wobei einige Teile drei völlig unterschiedliche Pin-Zuordnungen haben. In mindestens einem Fall ist eines der alternativen Zuordnungen ein von Teufel inspiriertes Werk von reinem Übel, das nichts weniger als eine zusätzliche Nachschlagtabelle erfordert, um analoge Stifte in Digital umzuwandeln Stifte).
Dieser Kern verwendet ein einfaches Schema zum Zuweisen der Arduino-Pin-Nummern: Die Stifte sind ab dem E/A-Pin nummeriert, der VCC als Pin 0 am nächsten liegt und gegen den Uhrzeigersinn weitergeht, wobei das (meistens) nicht ausgebaute Updi-Pin übersprungen wird. Der Updi -Pin wird dann der letzten Pin -Nummer zugeordnet (wie oben erwähnt, können Sie den Updi -Pin (sowohl analog als auch digitale Leswerte) lesen, auch wenn er nicht als GPIO festgelegt ist). Wir empfehlen dies als letztes Ausweg: Der Updi -Pin ist immer seinen Pullup aktiviert, wenn es nicht als GPIO -Pin festgelegt wird, und ein Signal, das der Updi -Aktivierung zu sehr aussieht, wird einen unerwünschten Betrieb verursachen.
Um jede Verwirrung über Pin -Identitäten zu verhindern und Mehrdeutigkeiten zu beseitigen, empfehlen wir die Verwendung der Pin_Pxn -Notation, um sich auf Pins zu verweisen, es sei denn, Sie verwenden eine Entwicklungskarte mit unterschiedlichen Zahlen oder Namen für die darauf gedruckten Stifte. Dies maximiert die Portabilität Ihres Codes für andere ähnliche Hardware und erleichtert die Überprüfung von Informationen zu den Stiften, die Sie in den entsprechenden Datenblättern verwenden, falls dies erforderlich ist.
x
ist die empfohlene PIN_Pxn
n
um sich auf Pins zu verweisen #defines
Diese lösen sich nur auf die digitale Pin -Nummer des fraglichen PINs - sie durchlaufen keinen anderen Codepfad oder irgendetwas. Sie haben jedoch einen besonderen Dienstprogramm beim Schreiben von Code, der in der Produktlinie mit Peripheriegeräten funktioniert, die mit bestimmten Stiften (nach Port) verbunden sind, wie die meisten Peripheriegeräte. Mehrere Demo -Code -Teile in der Dokumentation nutzen dies. Direkte Port -Manipulation ist auch möglich - und tatsächlich sind mehrere leistungsstarke zusätzliche Optionen verfügbar - siehe Direktanschluss -Manipulation .
PIN_Pxn
- nicht Pxn
und nicht PIN_xn
- diese bedeuten verschiedene Dinge!
Wenn eine einzelne Nummer verwendet wird, um sich auf einen PIN zu beziehen - in der Dokumentation oder in Ihrem Code - ist dies immer die "Arduino -Pin -Nummer". Dies sind die Pinzahlen in Orange (für Stifte, die analograd ()) und blau (für Nadeln, die nicht) in den Pin -Out -Diagrammen in der Lage sind. Alle anderen Möglichkeiten, sich auf Stifte zu beziehen, sind auf die entsprechende Arduino -Pin -Nummer angegeben.
Der Kern liefert auch An
und PIN_An
-Konstanten (wobei n
eine Zahl von 0 bis 11 ist). Wie beim offiziellen Kern ist PIN_An
als die digitale Pin -Nummer des Pin definiert, die mit dem analogen Kanal n geteilt werden. Diese beziehen sich auf die ADC0 -Kanalnummern . Dieses Benennungssystem ähnelt dem, was in vielen klassischen AVR -Kernen verwendet wurde , aber hier sind sie nur #definiert als entsprechende Arduino -Pin -Nummer . Wenn Sie die analoge Kanalnummer auf einem digitalen Pin erhalten müssen, verwenden Sie das Makro digitalPinToAnalogInput(pin)
Sie benötigen dies jedoch nur, wenn Sie eine erweiterte ADC -Bibliothek schreiben.
Diese Teile (na ja, zumindest die 1/2-Serie-war die 0-Serie als Budgetoption gemeint, außer dass sie das Budget nicht schrumpfen konnten, und sie sind nur ein paar Cent billiger) eine hervorragende Werkzeugkiste mit vielseitig und mächtige Peripheriegeräte; Die Top -End -Spiele sind gleich oder besser als klassische Megaavr -Teile - für einen TinyAVR -Preis. Eines der Leitprinzipien für die Gestaltung von Megatinycore ist, wie bei meinen anderen Kernen, darin, dass die unterstützten Teile ihr volles Potenzial erreichen - oder so nah wie möglich innerhalb der Grenzen von Arduino. Dieser (sehr große) Abschnitt deckt die Merkmale dieser Teile ab und wie sie durch Megatinycore sowie Merkmale des Kerns selbst ausgesetzt sind. Dieser (sehr große) Abschnitt versucht, die einzelnen Feature -Bereiche abzudecken. Versuchen Sie, die Funktion zu finden, mit der Sie arbeiten, wenn Sie versuchen, eine Chipfunktion zu verwenden und Probleme zu haben!
Wir geben keine Ansprüche über Spannungs- oder Temperaturbereiche für übertaktete Teile - nur wir behaupten, dass mindestens einer der Chips mit dieser Geschwindigkeit bei Raumtemperatur und einer bestimmten Skizze bei 5 V gearbeitet haben . Es wird erwartet, dass Ihre Kilometerleistung variiert, aber im Allgemeinen besser mit einer F -Spezifikation im Vergleich zu einem n- oder u -Spezifikum.
Wichtig - Lesen Sie das Tuning, bevor Sie eine abgestimmte Option auswählen!
Weitere Informationen zu diesen Taktgeschwindigkeiten finden Sie in der Taktreferenz
Spannungen sind diejenigen, die nach Herstellungsspezifikationen garantiert werden (es sei denn, die Grenzen des Betriebstemperaturbereichs werden diese Teile in der Regel weitaus besser abschneiden (2-Serien funktionieren im Allgemeinen bei 32 MHz und 5 V @ Raumtemperatur sogar vom internen Oszillator; die 0 /1 der Serie arbeitet ebenfalls normalerweise bei 32 MHz mit externer Uhr, sofern die Stromversorgung ein stabiler 5,0-5,5 V ist).
Es ist keine Aktion erforderlich, um die OSCCFG
-Sicherung festzulegen, wenn die Skizze über Update hochgeladen wird. Wenn Sie über Optiboot hochgeladen werden, kann die Sicherung nicht geändert werden. Was auch immer ausgewählt wurde, wenn der Bootloader verbrannt wurde, wird verwendet, und nur "Burn Bootloader" oder das Hochladen einer Skizze über Updi wird dies ändern.
Alle internen Oszillator -Takt -Geschwindigkeitsoptionen verwenden die Factory -Standardkalibrierung, sofern keine "abgestimmte" Option ausgewählt ist. In diesem Fall wird die Kalibrierung wie in der Tuning -Referenz dokumentiert. Dies kann verwendet werden, um 16 MHz einen Optiboot -Chip zu erhalten, der 20 MHz fusioniert und umgekehrt.
Weitere Informationen zu den Geschwindigkeitsnoten des Herstellers finden Sie in Speed Grade Referenz . Beachten Sie, dass dies die Spannungen und Taktgeschwindigkeiten sind, bei denen es garantiert funktioniert. Diese Teile sind für die Verwendung in Anwendungen geeignet, bei denen ein unerwarteter Fehler einer bestimmten Beschreibung eine Gefahr für Personen oder Eigentum darstellen könnte (denken Sie an Autos, Industriegeräte, Flugzeuge, Kernreaktoren - Orte, an denen Menschen sterben könnten, wenn das Teil nicht funktioniert) und i Glauben Sie auch für militärische Anwendungen, die aus dem entgegengesetzten Grund ähnliche Zuverlässigkeitsanforderungen haben. Typische Hobby -Nutzer werden über das Potenzial für Stabilitätsprobleme weitaus entspannter sein, wobei die Abstürze kaum mehr als ein Ärgernis sind und die Extreme der Teile der verlängerten Temperatur weit über das hinausgehen, was wir jemals brauchen würden. Unter der Annahme, dass das Board eine wasserdichte Beschichtung hatte, sollte thermisch ein Teil des N -Klassens in der Lage sein, gemäß der Geschwindigkeitsqualität in einem Topf mit kochendem Wasser zu funktionieren. Und das ist nur der N-Spec. Der F-Spec sollte gut zu 125 sein!
Es wurde festgestellt, dass die verlängerten Teile besser übertaktet, was sinnvoll ist. Ein Teil, der bei 125 ° C mit 20 MHz läuft
Ab Version 2.4.0 bieten wir jetzt eine Option "Offizielles Microchip Board". Dies tut nichts Besonderes als das Definieren LED_BUILTIN
als die Pin, die die LED auf dieser Platine anstelle von A7 hat, und das Definieren eines Makro PIN_BUTTON_BUILTIN
definiert als Pin mit der Benutzertaste und das "Upload" mit dem Non nicht -optiboot -Version Verwenden Sie immer den Onboard -Programmierer/Debugger. Tools -> Programmierer werden nur für "Burn Bootloader" und "mit dem Programmierer hochladen" verwendet. Im Falle des ATTINY416 Xplained Nano wird auch die Version des Bootloaders ausgewählt, die die alternativen Pins für den seriellen Port verwendet. Sie verwendet die alternativen Pins für USAT0 nicht automatisch, als ob Sie seriell.swap (1) noch gemacht hätten. - Funktionen zur Unterstützung des Standardtauschs von seriellen Stiften werden in einem zukünftigen Update vorhanden sein, zusammen mit einigen anderen Änderungen in der Maschinerie, die dem Pinswap -Mechanismus zugrunde liegt, der hoffentlich auch die Flash -Nutzung verringert.
Wie oben erwähnt, funktionieren diese möglicherweise nicht korrekt auf 32-Bit-Linux-Plattformen. Dies ist jenseits meiner Kontrolle; Ich baue keine Avrdude -Binärdateien auf, ich übernehme diese Aufgabe nicht auch. Ich habe schon zu viele.
blink()
mehr Blitz auf das xplainierte Mini gegen das Xplained Pro?Beide haben das gleiche ATTINY817! Wie können sie anders sein?
Aus dem gleichen Grund, warum Blink mehr Flash nimmt, wenn Sie es ändern, um PIN_PC0
zu verwenden, im Gegensatz zu PIN_PB4
: PC0, wird auf dem Xplained Mini ein PWM -Pin verwendet, während PB4, der vom Xplained Pro verwendet wird, nicht. Da dies der einzige Pin ist, an dem DigitalWrite () verwendet wird . Der Unterschied verschwindet, wenn DigitalWrite () auch auf einem PIN verwendet wird, der PWM auf beiden Geräten unterstützt (was zu einem höheren Flash -Gebrauchsergebnis führt), oder wenn digitalwrite () durch digitalwastfast () ersetzt wird, die weniger Blitz verwendet (jedoch angenommen, Sie haben gewonnen Nennen Sie es nicht auf einem Pin, der PWM ausgibt).
Wenn ein Updi -Programmierer verwendet wird, um Code hochzuladen Die integrierten Konfigurationsoptionen werden festgelegt. Sofern nicht bezeichnet wird, stimmt das Verhalten immer mit dem ausgewählten Tools -Menü überein. Zusammenfassend werden diese wie folgt behandelt:
WDTCFG will not be changed - it is not configured by megaTinyCore except to reset it to the factory default when doing "burn bootloader".
BODCFG will not be changed - not safe, you could set the BOD level to 4.3 on a 3.3v system, and then it would need to get > 4.3v applied to reprogram it. If it is on the same circuit board as parts that would be damaged, this is a difficult situation to recover from.
OSCCFG will be set
TCD0CFG will not be changed - it is not configured by megaTinyCore except to reset it to the factory default when doing "burn bootloader".
SYSCFG0 will not be changed - not safe
SYSCFG1 will be set
APPEND will not be changed - it is not configured by megaTinyCore. There is insufficient demand to justify the development effort.to make use of this as DxCore does
BOOTEND will be set
LOCKBIT will not be changed - it is not configured by megaTinyCore; supporting the lockbits presents several additional complications, and commercial users with need of this facility are unlikely to be using the Arduino IDE to program production units.
BODCFG
ist nicht sicher, da das Einstellen dieser auf eine höhere Spannung als die Board läuft und es ermöglicht, die Platine zu "abziegeln", bis eine höhere Betriebsspannung geliefert werden kann. Dies könnte besonders umständlich sein, wenn es auf die gleiche PCB wie Geräte gelötet wird, die diese Spannungen nicht tolerieren.
SYSCFG0
ist nicht sicher, da hier RSTPINCFG
lebt. Wenn Sie dies ändern, können Sie das Board nicht durch HV -Updi -Programmierung unprogrammierbar lassen, und nicht jeder hat einen HV -Updi -Programmierer. In Zukunft, wenn/wenn ein Programmierer, der HV -Updi -Funktion garantiert, die als Programmierer ausgewählt werden kann (dh, wird es möglich, eine Tools zu erstellen -> Programmiereroption, die nur mit HV -Programmierern funktioniert), wird diese Sicherung automatisch festgelegt, wenn sie verwendet werden dieser Programmierer.
Infolgedessen in 2.2.0 und später müssen Sie beim Hochladen mit Updi nicht mehr zwischen 16 MHz und 20 MHz abgeleitet werden, um zwischen 16 MHz und 20 MHz abgeladen zu wechseln
Dieser Kern verwendet immer die Link -Zeit -Optimierung, um die Flash -Verwendung zu reduzieren. Alle Versionen des Compilers, die die Teile von TinyAVR 0/1/2 -Serie unterstützen, unterstützen auch LTO. Daher müssen sie nicht optional gestaltet werden, wie es bei Attinycore geschehen ist. Dies war eine enorme Verbesserung der Codesize, wenn sie eingeführt wurde, normalerweise in der Größenordnung von 5 bis 20%!
Diese Teile haben alle eine große Anzahl von analogen Eingängen-DA und DB-Serie haben bis zu 22 analoge Eingänge erst unterstützt, wenn MVIO ausgeschaltet ist). Sie können wie bei einem normalen AVR mit analogRead()
gelesen werden, und wir sind standardmäßig eine Auflösung von 10 Bit; Sie können mit analogReadResolution()
in die gesamte 12-Bit () wechseln und die erweiterten analografischen Funktionen verwenden, um automatisch überabtastete, dezimierte Messwerte für eine höhere Auflösung zu erhalten und differentielle Messungen zu ergreifen. Es gibt 4 interne Spannungsreferenzen in 1.024, 2.048, 4.096 und 2,5 V sowie Unterstützung für die externe Referenzspannung (und natürlich VDD). ADC -Messwerte werden dreimal schneller als ein klassischer AVR eingenommen, und diese Geschwindigkeit kann erneut verdoppelt werden, wenn das, was Sie messen, eine geringe Impedanz ist, oder die Stichprobenzeit um einen Faktor verlängert, um Quellen mit sehr hoher Impedanz zu lesen. Dies ist in der analogen Referenz detailliert.
Die Teile der DX-Serie verfügen über einen 10-Bit-DAC, der eine reale analoge Spannung erzeugen kann (beachten Sie, dass dies einen niedrigen Strom liefert und nur als Spannungsreferenz oder Kontrollspannung verwendet werden kann. Sie kann nicht zur Leistung anderer Geräte verwendet werden). Dies erzeugt Spannungen zwischen 0 und dem ausgewählten VREF
(im Gegensatz zur TinyAVR 1-Serie kann dies VCC sein!). Legen Sie die DAC -Referenzspannung über die DACR reference()
-Funktion ein - übergeben Sie eine der ADC -Referenzoptionen, die im obigen ADC -Abschnitt aufgeführt sind (einschließlich VDD!). Rufen Sie analogWrite()
auf dem DAC-Pin (PD6) auf, um die Spannung einzustellen, die vom DAC ausgegeben werden soll (damit sie im 8-Bit-Modus verwendet). Um die DAC -Ausgabe auszuschalten, rufen Sie digitalWrite()
oder turnOffPWM()
auf diesem Pin auf.
Möglicherweise gibt es zusätzliche Optionen, um den DAC in der EA-Serie zu konfigurieren.
In der ADC- und DAC -Referenz finden Sie die vollständigen Details.
Die Verwendung der An
-Konstanten für analoge Stifte ist veraltet - die empfohlene Praxis besteht darin, nur die digitale Pin -Nummer zu verwenden, oder noch besser die PIN_Pxn
-Notation beim Aufrufen von analogRead()
.
Es gibt mehr Optionen als bei Classic AVR für das Zurücksetzen, einschließlich des Aufhängens des Codes. Der Wachhund -Timer kann nur zurücksetzen (verwenden Sie die RTC und die Grube für zeitgesteuerte Interrupts).
Siehe die Referenz für Reset and Watchdog (WDT) und die Megatinycore der Core-Auxiliary Library
Dieser Kern fügt hinzu, dass eine Reihe neuer Funktionen schnell digitaler E/A (1-14 Uhren abhängt, abhängig von der zum Kompilierungszeit bekanntesten und 2-28 Bytes Flash (PIN-Nummer muss zur Kompilierung für die ________Fast()
-Funktionen bekannt sein. und zum Konfigurieren aller Einstellungen pro Pin, die die Hardware mit pinConfigure()
hat.
Siehe die verbesserte digitale E/A -Referenz .
Alle Teile der 0/1-Serie verfügen über einen einzelnen Hardware-seriellen Anschluss (UART oder USAart). Die Teile der 2er-Serie haben zwei. Es funktioniert genauso wie der in offiziellen Arduino-Boards, außer dass es keine automatische Erholung gibt, es sei denn einen "Ersatz Reset Pin", wie an anderer Stelle in diesem Dokument beschrieben. In den Pinout -Diagrammen für die Standorte der seriellen Stifte finden Sie.
Bevor Sie den Teil in einen Schlafmodus einfügen oder auf andere Weise die Übertragungsfähigkeit deaktivieren, stellen Sie sicher, dass die Daten im Puffer gesendet werden Serial.flush()
Um die Übertragung einer Nachricht abzuschließen.
Eine vollständige Liste der Optionen finden Sie in der seriellen Referenz . Ab 2.5.0 wird fast jede Art von Funktionalität, die die serielle Hardware durchführen kann, unterstützt, einschließlich RS485-Modus, Halbduplex (über LBME und ODME) sowie Synchron- und Master-SPI-Modus, und 2.6.0 fügt Autobaud hinzu, Auch wenn es nicht sehr nützlich ist.
Alle diese Teile haben eine einzelne Hardware -SPI -Peripherie. Es funktioniert wie die in den offiziellen Arduino -Boards mit der SPI.H -Bibliothek. In den Pinout -Diagrammen für den Ort dieser Stifte finden Sie. Bei 8-poligen Teilen ist die einzige Option für den SS-Pin PA0 (der Updi/Reset-Pin). Dies spielt jedoch keine Rolle für die Zwecke dieses Kerns, da dies wie die offizielle Bibliothek nur als Meister fungiert und der SS -Pin nur verwendet wird, wenn er möglicherweise als Sklave fungiert.
An allen Teilen außer den 14-poligen Teilen können die SPI-Stifte an einen alternativen Ort verschoben werden (Hinweis: Auf 8-poligen Teilen kann der SCK-Pin nicht bewegt werden). Dies wird mit den Methoden SPI.swap()
oder SPI.pins()
konfiguriert. Beide erreichen dasselbe, unterscheiden sich jedoch darin, wie Sie die zu verwendende Stifte angeben. Dies muss aufgerufen werden, bevor Sie SPI.begin()
anrufen.
SPI.swap(1)
oder SPI.swap(0)
setzt die Zuordnung auf die alternativen ( 1
) oder Standard ( 0
) Stifte. Es wird wahr zurückgegeben, wenn dies eine gültige Option ist, und falsch, wenn dies nicht der Fall ist (Sie müssen dies nicht überprüfen, aber sie kann während der Entwicklung nützlich sein). Wenn eine ungültige Option angegeben ist, wird sie auf die Standardeinstellung festgelegt.
SPI.pins(MOSI pin, MISO pin, SCK pin, SS pin);
- Dadurch wird die Zuordnung auf die von den angegebenen Stiften angegebenen Zuordnungen festgelegt. Wenn dies keine gültige Zuordnungsoption ist, wird FALSE zurückgegeben und die Zuordnung auf die Standardeinstellung festgelegt. Dies verwendet mehr Flash als SPI.swap()
so dass diese Methode bevorzugt wird. Das SS pin
-Argument ist optional, da der Pin nicht verwendet wird, wenn sie als SPI -Meister fungieren, und weder diese Bibliothek noch die offizielle Unterstützung der SPI.H -Bibliothek als Sklave.
Wenn festgestellt werden kann, dass Argumente an SPI.swap()
oder SPI.pins()
zum Kompilierenzeitpunkt ungültig sind (am häufigsten, wenn die Argumente (en) Konstanten sind, die sie fast immer sind), erzeugt der Kern eine Kompilierung Fehler in diesem Effekt. Dies soll dazu beitragen, zu verhindern, dass solche erkennbaren Probleme die Debugg -Zeit für Hardware erfordern.
Dieser Kern deaktiviert den SS -Pin, was bedeutet, dass der "SS" -Pin für jeden gewünschten Zweck verwendet werden kann, und der Pin ist nur bei der Erstellung eines SPI -Sklaven relevant Raketenwissenschaft oder so). Wenn der klassische AVRs ein Eingang war und SPI aktiviert war, fungierte es als SS -Pin, und wenn es niedrig wurde, schaltete es das Gerät in den Slave -Modus (und SPI.h würde nicht funktionieren, bis es wieder in den Master eingebracht wurde Modus, der nicht automatisch durchgeführt wurde).
Alle diese Teile haben eine einzelne Hardware I2C (TWI) Peripherie. Es präsentiert eine API, die mit der Standard -Arduino -Implementierung kompatibel ist, aber mit zusätzlicher Unterstützung für mehrere Sklavenadressen, die Beantwortung allgemeiner Anrufadressen und - am aufregendsten - gleichzeitiger Master- und Sklavenbetrieb! (neu in 2.5.0).
In Draht.H -Dokumentation finden Sie eine vollständige Beschreibung und Details. Die Hardware I2C ist eine der komplizierteren Peripheriegeräte. Wire hat in letzter Zeit viele heiße neue Verbesserungen erhalten.
Der Kern bietet Hardware PWM über die Standard -Funktion "Standard analogWrite()
. Auf den 8-poligen Teilen (412, 212, 402, 204) sind 4 PWM-Stifte erhältlich. Bei allen anderen Teilen außer 1er-Teilen mit 20 oder 24 Pins sind 6 PWM-Stifte erhältlich, die alle vom Timer A (TCA0) angetrieben werden. Die Teile von 20 und 24 Pin 1 der Serie haben zwei zusätzliche Stifte, die von TCD0 angetrieben werden. Die 2er-Serie handelte offenbar TCD0 gegen einen zweiten seriellen Port und einen überlieferenden ADC-diese Teile haben auch 6 PWM-Stifte. Die Timer vom Typ B (TCBN) können nicht für zusätzliche PWM -Stifte verwendet werden. Ihre Ausgangsstifte sind die gleichen wie die mit Timer A verfügbar und sie sind oft zu nützlich, um es zu rechtfertigen, um eine ganze TCB für zu rechtfertigen. Sie können sie jedoch übernehmen, wenn Sie PWM bei unterschiedlichen Frequenzen erzeugen müssen, obwohl die Tatsache, dass sich der Prescaler nicht vom Timer vom Typ A unterscheiden kann, diese Verwendung ebenfalls einschränkt. In den Pinout -Diagrammen finden Sie eine Liste, von der PINs PWM unterstützen.
Ab 2,6.8 wurde ein Werkzeug-Untermenü hinzugefügt, damit Sie aus den plausibel nützlichen PWM-Zuordnungen auswählen können, und (auf 1 Serie), um das TCD-PWM zu deaktivieren, um Blitz zu speichern.
Beachten Sie, dass TCA0 (der Timer vom Typ A an allen Teilen) vom Kern beim Start im Split -Modus konfiguriert wird, um die bestmöglichen PWM -Pins mit analogWrite()
zu unterstützen. Ab den 2.2.x-Versionen wurde eine takeOverTCA0()
-Funktion hinzugefügt, die aufgerufen werden kann, um den Kern nicht an TCA0-Register zu schreiben oder einen bestimmten Modus oder Verhalten für TCA0 zu übernehmen. analogWrite()
erzeugt keine PWM, außer bei Stiften, die von TCD0 auf den 20/24-poligen Teilen angetrieben werden, und digitalWrite()
schalten es aus, wenn Sie TCA0 für andere Zwecke neu konfigurieren möchten. Siehe die folgende Anleitung und "Hard Reset". Der Timer kehrt auf Lagerkonfiguration zurück.
Die 3216, 1616, 816, 416 und die 3217, 1617 und 817 haben zwei zusätzliche PWM -Stifte, die von Timer D angetrieben werden (PC0 und PC1 - Pins 10 und 11 auf X16, 12 und 13 auf X17). Timer D ist ein asynchroner (asynchronischer) Timer, und die Ausgänge können nicht aktiviert oder deaktiviert werden, ohne den Timer kurz zu stoppen. This results in a brief glitch on the other PWM pin (if it is currently outputting PWM) and doing so requires slightly longer - though the duration of this glitch is under 1 us. If TCD is used as the millis timer - which is the default on any part that has a type D timer (in order to keep the timers that are more readily repurposed available - TCD0 is not an easy peripheral to work with), this will result in millis()
losing a very small amount of time (under 1 us) every time PWM is turned on or off on a TCD pin.
As of 2.2.0, analogWrite()
of 0 or 255 on a TCD-driven PWM pin does not disconnect the pin from the timer - instead it results in a constant HIGH
or LOW
output without disconnecting the timer (use digitalWrite()
for that ). This means that analogWrite(PIN_PC0, 0)
or analogWrite(PIN_PC1, 0)
can be used to connect the timer to the pin without outputting PWM (yet) - doing this on both pins prior to setting any other duty cycles would allow one to ensure that no glitch of any sort occurs on the other TCD0 pin when the second pin is connected to it. Only digitalWrite()
or turnOffPWM()
will disconnect the timer from the pin . When outputting a HIGH
in this way, the pin is "inverted"; this means that digitalRead()
on it will return 0, not 1 (if you're digitalRead()
'ing a pin, which you have set to output a constant HIGH
, using analogWrite()
, and it's one of those two pins, it will read LOW
. However, if you are using digitalRead()
on a pin that you've set to output a constant value, you may be doing something wrong in general.
Because TCD is async, and can run from the unprescaled internal oscillator, that means you can lower the system clock frequency without affecting the speed of the PWM. While there is a difference in PWM frequency between 16-MHz derived and 20-MHz derived clocks, there is no change in frequency for different system clock speeds for the TCD-controlled pins (the TCA-controlled pins will vary by a factor of two) The exception to this is when TCD0 is used as the millis/micros timing source at 1 MHz - running at full speed there resulted in spending an unreasonable fraction of runtime in the millis()
ISR (tens of percent of the time).
TCD0 is used for millis()
/ micros()
by default on parts that have it. Be aware that this does have a small flash penalty, so you can save flash by switching to use TCA or a TCB as the timer. That will also make micros()
return faster. There is a shortage of timers on most of these parts, and I have not seen anyone talking about or posting code that reconfigures the TCD. Meanwhile everyone seems to be reconfiguring the TCA and many libraries need a TCB. These factors have been the impetus for making TCD0 the default for millis()
/ micros()
: it is least likely to directly interfere.
On some versions of megaTinyCore prior to 2.2.0, PWM on the TCD0 pins was entirely broken.
For general information on the available timers and how they are used PWM and other functions, consult the guide: This also covers the PWM frequencies that these timers will give you at various system clocks. Timers and megaTinyCore
Support for tone()
is provided on all parts using TCB0, unless TCB1 is present and TCB0 is set as millis()
source. This is like the standard tone()
function. Unlike on some classic AVRs, it does not support use of the hardware 'output compare' to generate tones; due to the very limited PWM capabilities and restricted prescaler selection for the TCB timers, this is not practical. See caveats below if using TCB0 or TCB1 for millis()
/ micros()
settings. See the timer reference for more information
tone()
can only play a tone on one pin at a time. In theory you can play one tone per Type B timer, simultaneously, without anything more exotic than what tone()
does now other than adding a capability to manage the multiple pins. It is my opinion that those belong in a library, not the core. See comments in tone.cpp
for some thoughts if you want to implement something like that - I'd be happy to give more thoughts if you have questions.
megaTinyCore provides the option to use any available timer on a part for the millis()
/ micros()
timekeeping, controlled by a Tools submenu. It can be disabled entirely if needed to save flash, allow use of all timer interrupts or eliminate the periodic background interrupt. By default, TCD0 will be used by on parts that have one - otherwise TCA0 will be used (in versions prior to 1.1.9, TCA0 was used by default on parts that could output PWM with TCD0 on pins not available for TCA0 PWM). All timers available on the parts can be used: TCA0, TCD0 (on parts that have it), TCB0, TCB1 (where present) and the RTC. Many of these - particularly the non-default options, involve tradeoffs. In brief, TCA0 is a very versatile timer that users often want to reconfigure, TCD0 loses a small amount of time when PWM is turned on or off on the two TCD0 PWM pins (10,11 on 20-pin parts, 12,13 on 24-pin parts), TCB0 conflicts with Servo
and tone()
on parts that don't have TCB1, and when the RTC is used micros()
is not available at all because the clock isn't fast enough. With these limitations in mind, the timer selection menu provides a way to move millis()
/ micros()
to the timer most appropriate for your needs.
For more information, on the hardware timers of the supported parts, and how they are used by megaTinyCore's built-in functionality, see the Timers and megaTinyCore Reference .
2.3.0 fixed a long-standing (though surprisingly low impact) "time travel" bug.
millis()
If the RTC is selected as the timer for millis()
timekeeping, micros()
will not be available. Additionally, this timer will be configured to run while in STANDBY sleep mode. This has two important consequences: First, it will keep time while in sleep. Secondly, every 64 seconds, the RTC overflow interrupt will fire, waking the chip - thus, if you are using the RTC for millis()
and putting the part into sleep, you should declare a volatile global variable that you set in the ISR that is supposed to wake the part, eg volatile boolean ShouldWakeUp=0;
, set it to 1 in the ISR, and when you put the ATtiny to sleep, have it check this immediately after waking, going back to sleep if it's not set, and clearing it if it is set, eg:
void GoToSleep () {
do {
sleep_cpu ();
} while (!ShouldWakeUp)
ShouldWakeUp= 0 ;
}
This functionality will be made easier to use via ModernSleep when that library is available.
This board package also supports using an external 32.768khz crystal as the clock source for the RTC (not supported on 0-Series or 8-pin parts - not our fault, the hardware doesn't support it). If this is used, make sure that the crystal is connected between the TOSC1 and TOSC2 pins (these are the same as the TX and RX pins with the default pin mapping - very convenient right?), that nothing else is, that no excessively long wires or traces are connected to these pins, and that appropriate loading capacitors per crystal manufacturer datasheet are connected (and that it's not a full moon - I found the 32k crystal to be extremely uncooperative. To reduce power usage, they try to drive the crystal als weakly as they can get away with, which in turn makes it more susceptible to interference.
Yes, you can use an external oscillator for the RTC, at least on 1 and 2 series parts. When it's an oscillator not a crystal, it can be fed to either TOSC0 or EXTCLK; better support for this will come in the future. Note that while TOSC0 won't let you run the RTC at widlly faster speeds. EXTCLK will.
printf()
Support for "printable" Class Unlike the official board packages, but like many third party board packages, megaTinyCore includes the printf()
method for the printable class (used for UART serial ports and most everything else with print()
methods); this works like sprintf()
, except that it outputs to the device in question; Zum Beispiel:
Serial.printf( " Milliseconds since start: %ld n " , millis());
Note that using this method will pull in just as much bloat as sprintf()
and is subject to the same limitations as printf - by default, floating point values aren't printed. You can use this with all serial ports You can choose to have a full printf()
implementation from a Tools submenu if you want to print floating point numbers, at a cost of some additional flash.
printf()
and Variants Thereof Have Many Pitfalls There are a considerable number of ways to screw up with printf()
. Some of the recent issues that have come up:
printf()
- printf()
bugs are a common cause of software bugs in the real world. Be aware that while you can use F() on the format string, there are no warnings for invalid format strings in that case ; a conservative programmer would first make the app work without F() around the format string, and only switch to F() once the format string was known working.From cplusplus.com:
The length sub-specifier modifies the length of the data type. This is a chart showing the types used to interpret the corresponding arguments with and without length specifier
(if a different type is used, the proper type promotion or conversion is performed, if allowed): Strikethrough mine 'cause that don't work here (and it's not my fault nor under my control - it's supplied with avrlibc, and I suspect that it's because the overhead of implementing it on an 8-bit AVR is too large). When incorrect length specifiers are given (including none when one should be used) surprising things happen. It looks to me like all the arguments get smushed together into a group of bytes. Then it reads the format string, and when it gets to a format specifier for an N byte datatype, it grabs N bytes from the argument array, formats them and prints them to whatever you're printing to, proceeding until the end of the format Zeichenfolge. Thus, failing to match the format specifiers' length modifiers with the arguments will result in printing wrong data, for that substitution and all subsequent ones in that call toprintf()
.
The table below comprises the relevant lines from that table - many standard types are not a thing in Arduino (their original was several times longer, but including that mess would just complicate this discussion.
Länge | di | uox X | f F e E g G a A | C | S | P | N |
---|---|---|---|---|---|---|---|
(keiner) | int16 | uint16 | schweben | int | verkohlen* | Leere* | int* |
hh | int8 | uint8 | verkohlen* | ||||
l | int32 | uint32 | int32_t* |
Notice that there is no line for 64 bit types in the table above; these are not supported (support for 64-bit types is pretty spotty, which is not surprising. Variables of that size are hard to work with on an 8-bit microcontroller with just 32 working registers), and using uint64's is something you should try to avoid, similar to driving on the wrong side of the road, flying kites during thunder storms, or drinking bleach. While all have been suggested (Europe is really persistent about the side of the road; As far as I'm concerned, it comes down to physics; mirror image symmetry i. This applies to all versions of printf()
- the capability is not supplied by avr-libc.
There are reports of memory corruption with printf, I suspect it is misunderstanding of above that is actually at hand here.
printf()
Implementation A Tools submenu lets you choose from three levels of printf()
: full printf()
with all features, the default one that drops float support to save 1k of flash, and the minimal one drops almost everything and for another 450 bytes flash saving (will be a big deal on the 16k and 8k parts. Less so on 128k ones). Note that selecting any non-default option here will cause it to be included in the binary even if it's never called - and if it's never called, it normally wouldn't be included. So an empty sketch will take more space with minimal printf()
selected than with the default, while a sketch that uses printf()
will take less space with minimal printf()
vs default.
Also:
Menüauswahl | printf() or similar used? | Overhead |
---|---|---|
Standard | NEIN | 0 by definition |
Standard | Ja | apx 1500 |
Minimal | NEIN | apx 1000 |
Minimal | Ja | apx 1100 |
Voll | NEIN | apx 2800 |
Voll | Ja | apx 3000 |
Notice how when not using printf or similar functions, you are far better off leaving it on the default, as opposed to switching to minimal thinking you'll save flash, because you you'll use more flash not less.
All pins can be used with attachInterrupt()
and detachInterrupt()
, on RISING
, FALLING
, CHANGE
, or LOW
. All pins can wake the chip from sleep on CHANGE
or LOW
. Pins marked as Async Interrupt pins on the megaTinyCore pinout charts (pins 2 and 6 within each port) can be used to wake from sleep on RISING
and FALLING
edges as well. Those pins are termed "fully asynchronous pins" in the datasheet.
Advanced users can instead set up interrupts manually, ignoring attachInterrupt()
, manipulating the relevant port registers appropriately and defining the ISR with the ISR()
macro - this will produce smaller code (using less flash and RAM) and the ISRs will run faster as they don't have to check whether an interrupt is enabled for every pin on the port.
For full information and example, see the Interrupt Reference.
Like my other cores, Sketch -> Export compiled binary will generate an assembly listing in the sketch folder. A memory map is also created. The formatting of the memory map leaves something to be desired, and I've written a crude script to try to improve it, see the Export reference for more information. see Exported Files documentation
The EESAVE fuse can be controlled via the Tools -> Save EEPROM menu. If this is set to "EEPROM retained", when the board is erased during programming, the EEPROM will not be erased. If this is set to "EEPROM not retained", uploading a new sketch will clear out the EEPROM memory. Note that this only applies when programming via UPDI - programming through the bootloader never touches the EEPROM.
You must do "burn bootloader" in order to apply changes after modifying this setting, as EESAVE is on the same fuse as one the one that can be used to disable UPDI, making it an "unsafe" fuse (one that if written with the wrong options, can make the device difficult to reprogram). We don't write "unsafe" fuses like that when uploading sketches, because it should never be possible to brick your board just by uploading, which you can do without opening the tools menu and seeing that you forgot to change the options back to the intended ones for the current project.
These parts officially support BOD trigger levels of 1.8V, 2.6V, and 4.2V, with Disabled, Active, and Sampled operation options for when the chip is in ACTIVE and SLEEP modes - Disabled uses no extra power, Active uses the most, and Sampled is in the middle. As of 2.1.0, the ACTIVE/SLEEP modes have been combined into a single menu, the nonsensical options (such as using more aggressive BOD while sleeping than while awake) were removed, and the previously unexposed options were added. Sampled mode is now available with two sample rates (the faster one uses ever so slightly more power, as you would expect) and "Enabled hold wake": in that mode, BOD is disabled in sleep, enabled when not sleeping, and when waking up, code execution does not begin until the BOD is ready. See the datasheet for details on power consumption and the meaning of these options.
You must do Burn Bootloader to apply this setting. This fuse is considered "unsafe" as you can set the BOD level to a voltage higher than the highest voltage tolerated by other chips soldered to the same pcb and sharing a power rail with the AVR, and this will then prevent reprogramming without desoldering things (because you'll either be unable to program the AVR because it's in brownout reset, or if you power it at a high enough voltage to leave BOR, you would damage the afore-mentioned low voltage parts).
Between the initial header file and preliminary datasheet release, and the more recent versions of each, several BOD settings were removed from the tinyAVR 0/1-Series datasheets, and the atpack release notes described them as "unqualified" - (I understand that this has something to do with the factory testing process and possibly the vetting process for the safety critical applications these parts are certified for. ). The three official BOD levels are the voltages that the chip is guaranteed (Yup, they use that word in the datasheet!) to work at, within the manufacturer specified temperature range and running at a system clock frequency no higher than specified at that voltage. Nevertheless, the other 5 BOD levels are believed to work as one would expect (I have used them successfully), but Microchip does not provide any guarantee that they'll work, even if all other operating requirements are met, and I do not believe they are tested in production. These "not guaranteed" voltages are still supported by the megaTinyCore BOD dropdown menu, but (as of 2.0.4 - the first version that has the new headers) are marked as "(Unofficial)" in the submenu. Note that the new headers no longer provide the *_gc
enum entries for these BOD level.
| BOD level
0/1-series| BOD level
2-series | Guaranteed speed
Normal temp. range | Guaranteed speed
Elevated temp. range) |-----------|------------------|------------------| | 1.8V | 1.8V | 5 MHz | 4 MHz | | 2.1V | 2.15V | unofficial | unofficial | | 2.6V | 2.6V | 10 MHz | 8 MHz | | 2.9V | 2.95V | unofficial | unofficial | | 3.3V | 3.3V | unofficial | unofficial | | 3.7V | 3.7V | unofficial | unofficial | | 4.0V | 4.0V | unofficial | unofficial | | 4.2V | 4.3V | 20 MHz | 16 MHz |
Normal temperature range is -40-105C on 0/1-series parts and -40-85C on 2-series parts. These parts have a letter N (0/1-series) or U (2-series) at the end of the part number; this is marked on the physical chip as well on 0/1-series, but not on 2-series.
Extended temperature range is -40-125C, and these parts are denoted with the F temperature spec. The extended temperature range column applies when the temperature range is above the normal range and below 125C on F-spec parts. The normal temperature range column still applies to F-spec parts if they are running in the normal temperature range.
Most existing Arduino libraries work. See the Supported Libraries List for a more complete list and discussion of what kinds of libraries might have issues. Of the few libraries that don't work, a handful happened to also be extremely popular and heavily used, such that it was felt necessary to include a compatible version with megaTinyCore. In addition to these, libraries which expose hardware that is only present on the modern AVRs, are also included. These libraries are listed below.
This library supplies two functions to check tuning status of the chip it's running on, and now adds two software reset functions (via WDT or via software reset). It also holds the massive keywords.txt file that highlights register names and core-specific functions.
megaTinyCore helper library docs
The usual NeoPixel (WS2812) libraries, including the popular FastLED as well as AdafruitNeoPixel, have problems on these parts - they depend on hand-tuned assembly, but the execution time of several key instructions has been improved. The improvements enable significant simplification of the code for driving these LEDs. This core includes a compatible version of the tinyNeoPixel library for interfacing with these ubiquitous addressable LEDs. There are two versions, both tightly based on the Adafruit_NeoPixel library. One implements a truly identical API, differing only in name (and obviously the fact that it works on tinyAVR and Dx-Series and megaAVR 0-Series parts at clock speeds from 8 MHz to 48 MHz, instead of on most classic AVRs at 8, 12, and 16 MHz). The other version makes a slight change to the constructor and drops support for changing length at runtime, in order to realize significant flash savings (around 1k). See the tinyNeoPixel documentation and included examples for more information.
The standard EEPROM.h is available here - it works like it does on any AVR. USERSIG.h
(from "User Signature" which the datasheet has sometimes called the USERROW
) it has the same API as EEPROM, though there may be future additions to harmonize with Dx-friendly functions for updating multiple bytes. The Dx-Series parts can only erase the whole USERROW, so potentially each byte written could involve erasing and rewriting it all - the question of how to deal with that is why DxCore doesn't have a USERSIG library yet). The name "USERSIG" refers to the alternate name of the USERROW, the "User Signature" space - the name USERROW could not be used because it is defined by the io headers (it's the struct
of type USERROW_t
, made up of USERROW.USERROW0
through USERROW.USERROW31
. Not the most useful thing, but we never override the io header file definitions unless working around a bug.
Note: Prior to 2.1.0, we tried to get clever with supporting the USERROW
through the EEPROM library; that not only was shortsighted (as it's logically inconsistent on anything with more than 256b of EEPROM), it also introduced some serious bugs. Use the USERSIG.h
library for that instead.
The usual Servo library from library manager is incompatible with these parts (minor changes could make it "work", but with glaring issues and a dependence on the configuration of TCA0). This core provides a version of the Servo library which will select an appropriate timer (TCB0 is the only option on most parts, on parts with a TCB1 (2-Series and 3216, 3217, 1617, 1616 and 1614), TCB1 will be used instead, provided it's not being used for millis()
). Except on parts with a TCB1, Tone cannot be used at the same time as the Servo library. Servo output is better at higher clock speed; when using servos, it is recommended to run at the highest frequency permitted by the operating voltage, to minimize jitter.
Warning If you have installed a version of the Servo library to your /libraries folder (including via library manager), the IDE will use that version of the library (which is not compatible with these parts) instead of the one supplied with megaTinyCore (which Ist). As a workaround, a duplicate of the Servo library is included with a different name - to use it, just #include
instead of #include
- no other code changes are necessary.
Note that the Servo libraries were only fixed in version 2.2.0 - prior to that we had a Servo library, but it didn't work due to an astonishingly large number of bugs (I swear I tested it - apparently not well enough).
Written by @MCUDude, this provides a more accessible (much more accessible!) wrapper around the optiboot.h library (which was written by the famous @westfw) . This supports writing to the flash of any device using Optiboot, by having the application code call routines in the bootloader to write to the flash. All modern AVRs have built-in flash protection mechanisms that permit only code executing from the bootloader section ( BOOTCODE
, in their terminology) to write to the application section ( APPCODE
). While the hardware does support a third flash section ( APPDATA
) which can be written by code running in APPCODE
this is only usable if there is also a BOOTCODE
section defined (otherwise the entire flash is treated as BOOTCODE
which can never be self-programmed), and would require a separate implementation of this library to use. It would also be possible to get flash-write-from-app without use of an actual bootloader through an analog of the trick used by the DxCore Flash.h for this. Since there appears to be little demand for such a thing, that functionality is not currently implemented (they were implemented on DxCore's flash writing library because the additional effort was virtually nil, and because there was a user with a particular interest in that feature). If someone wants this, and will adapt the library, I can add the entry point to the core and give you little chunks of inline assembly that will call it. Note on terminology: on AVR Dx-Series, the fuses are called BOOTSIZE
and CODESIZE
whereas on 0/1-Series tinyAVRs they're called BOOTEND
and APPEND
. I'm not quite sure how they didn't foresee customer confusion when they called the "APPlication END" that... Regardless of the names they do the same thing, although the granularity on tinyAVRs is finer, as you would expect.
Optiboot_flasher documentation
Warning As noted above, there is a library for DxCore that is also named Flash.h
. Both allow an application to write to the flash using Optiboot if present. That is the only similarity they have . The API, NVM hardware, method used to call the bootloader, and basically everything about these libraries is different . Be sure you write code for the one that matches the hardware you're using. While I (Spence Konde) wrote the DxCore one, I don't have a particularly strong opinion about which way is "right". We made them independently, but not because we each thought the other one's idea of how it should be done was wrong. They largely reflect the way the hardware interacts with its flash. For example, the one for megaTinyCore is page-oriented with its own page buffer, and these parts write in a page-oriented manner, while the DxCore library only cares about pages when erasing - on those parts, the flash is written with word or even byte granularity!
All of these parts have at least a pair of Configurable Custom Logic (CCL) blocks; official Microchip terminology calls them "LUTs" in reference to the LookUp Table (aka truth table). We use the term "logic block" instead, to avoid confusion with other kinds of lookup table (the "lookup table" in a logic block is very different from most lookup tables; containing 8 entries, each of which is a 0 or a 1, it is a single byte, which isn't much of a table), and to prevent users who missed this paragraph from being confused by the terminology. Each block allows you to supply an arbitrary 3-input truth table, as well as configuring additional options like a synchronizer, filter, or edge detector. The CCL operates asynchronously (unless you using the synchronizer) - meaning that things can happen faster than the clock speed. Thesynchronizer that will synchronize the CCL output to one of several clock sources (probably the system clock will be what you would synchronize with). The inputs can come from pins, events, or other peripherals. There's a feedback input as well, which allows a great many exciting possibilities, and a "sequencer" that can act like a latch or flip-flop using the outputs of a pair of logic blocks as its inputs. This is an incredibly powerful peripheral - especially on the 2-Series parts, which have a second pair of logic blocks, as well as the capability to trigger an interrupt when the state of one changes.
The Logic ( #include Logic.h
) library provides a simple wrapper around the CCL hardware in the tinyAVR 0/1/2-Series devices. This library is also included in DxCore and MegaCoreX, covering all AVRs with CCL hardware. Written by @MCUDude.
Logic library documentation
These parts have either 1 (everything else) or 3 (1614, 1616, 1617, 3216, and 3217) on-chip analog comparators which can be used to compare two analog voltages, and, depending on which is larger, do one or more of the following: generate an event output, control an output pin, or fire an interrupt. One of the voltages can be the internal reference (0-Series) or an internal reference scaled by an 8-bit DAC (everything else). This library, written by @MCUDude, provides a simple wrapper around the analog comparator(s) which makes their configuration easier and resulting code more readable (also easier on the wrists - less stuff to type in all caps) than manually configuring registers, while exposing nearly the full featureset of the analog comparators on these parts. Do note does not support the Window Comparator option for the parts with 3 comparators; There doesn't exactly seem to be a lot of demand for that one, though!
The Comparator library ( #include Comparator.h
) is also included in DxCore and MegaCoreX, covering all modern AVRs with comparator hardware. Written by @MCUDude.
Comparator library documentation
In general you should expect the following about library compatibility:
__AVR_ARCH__ >= 102
.architectures=*
would suggest that it would work anywhere - all this means is that there are not separate folders with implementations for different architectures. It does not mean that the library does not make assumptions about architecture, test against architecture specific stuff with #ifdef
s and so on. Unfortunately, library authors often use this when they know it works with a couple of architectures, shrug their shoulders and assume it'll work anywhere and put down a * in that field.The amount of effort required to port a given library will vary widely depending on the library. Some are straightforward for anyone reasonably familiar with these parts and what to generally expect and approach it. Any library associated with some peripheral that both classic and modern had, it's probably going to be a straightforward change if you just need to swap out the classic peripheral for the modern one - Yes, every bitfield will be named differently, but only rarely did a modern AVR's peripheral lack a feature the classic version had. The USART on classic AVR has whack stuff like MPCM, and the 9 bit mode - sorry, modes. Even the layout of some of the registers is similar - the parts aren't as different as they appear at first. Another type is the "bitbanger", where they're using direct port writes; the solution to this is cookbook - switch to using the relevant PORT or VPORT registers. Input capture is a little more complicated because you have to set up the event channel, and figure out how to offer that in a library (that is the hard part). But the consistent factor is that generally, none of these things are long slow painful slogs. And as noted above, many libraries will work out of the box, or have already been adapted.
The fact that many libraries can be ported no or little underlines the need for reports from users about incompatible libraries as well as compatible ones not listed on the table linked below. Usually reports of non-working libraries to add to the table result in the library getting fixed , and the fixed library being added to the table; Almost all of the fruit here low hanging. So when you come upon incompatible libraries report it to me! Many libraries that were initially incompatible were fixed up in under 10 minutes. Porting typical libraries from classic AVRs requires a fraction of the effort that the "tar pit" libraries included with this core take to port to new modern AVR families (these are Comparator, Logic, Event: Logic and Event are both, on their own, large, complicated, "system-like" peripherals. The CCL is just complex in general, and has seen relatively modest changest between families, except for the t0/1. Event is simple in theory and much more complicated in practice, in no small part because the implementation on the 0-series, 1-series, mega0, 2-series/DA/DB/DD, EA and the EB are each different. And a single library has to support all of them with a consistent interface and paper over all the differences.
I know lots of people use libraries that aren't on that list, and I fully expect that there is a great number of libraries that work and are not listed, and I'd love to hear about them. Use the "discussions" or email me, or even submit a PR to add a line to the table. I want to hear about working libraries so others will know they work and not hesitate, and I'm even more interested in ones that don't work so they can be fixed - or determined to be unfixable)
For more information on resetting from software, using the Watchdog Timer, the causes of unexpected resets and how to prevent them, and generally all things reset-related, see the Reset Guide.
It is often useful to identify what options are selected on the menus from within the sketch; this is particularly useful for verifying that you have selected the options you wrote the sketch for when opened later by yourself or someone who you shared it with. Or, you can use such in-sketch identification, combined with preprocessor #if
macros, to select the appropriate code depending on the part or options at hand.
There are a great number of #define
s provided to get information about the hardware in-use, in order to write portable and flexible code in your sketch or, especially, library code.
Note : You cannot distinguish an extended temperature range part from a normal one from software. For 0/1-series, most packages mark the temperature grade. this is no longer true on the 2-series, nor on any part released after the 1-series - So better make sure you mark those parts if you unpack them, because the only alternative is to give the lot number to Microchip support, and they'll tell you if it's an F, a U, or an N (FUN letters - but notice that you can't turn any letter into any other letter without both erasing and adding lines. The same is true of the different set of letters they used on automotive parts - BMZ or something - less FUN, but they had the same "modification resistance" (hey, on at least one occasion, a quantity of t13'd had the markings polished off and were remarked as tiny85's and sold as such on aliexpress and ebay - that was worth doing to some criminal in China! Unethical behavior is of course the norm for companies everywhere, but in the US, criminality of the company (as opposed to rogue employees) is not pervasive. When it rises above that, low end of chinese industry - ex, virtually all PVC wire is 2-8 AWG smaller than what is printed on the wire; same with silicone wire (but FEP insulated wire is always spot on, cause it's not at the low end ya see), one has to assume that (well, if they still marked the parts) someone has taken a bunch of parts marked I (vertical line), added 3 horizontal lines to each one (One imagines, with the same sort of automated chip marking method that would be used for putting any other pattern, except here it would just be the missing parts of an E. The consistency of the location of markings on packages is remarkably consistent specimen to specimen, such that you might be able to target by position and get it close enough to be convincing, and with just 3 small marks and no grinding, and significant price difference between I and E spec parts for certain parts (oddly, not for most tinies). Of course when they adopted the I and E when they stopped marking parts at all, so this is academic. But can you seriously imagine anyone inspecting 200 boards and writing down every lot number he saw, and emailing the list to Microchip and asking for confirmation that they're all E's as he ordered?).
A new version of Optiboot (Optiboot_x) now runs on the tinyAVR 0-Series, 1-Series and 2-Series chips. It's under 512 bytes, and works on all parts supported by this core, allowing for a convenient workflow with the same serial connections used for both uploading code and debugging (like a normal Arduino Pro Mini). Note the exception about not having autoreset unless you disable UPDI (except for the 20 and 24-pin 2-Series parts which can put reset on PB4 instead), which is a bit of a bummer.
To use the serial bootloader, select a board definition with (optiboot) after it. Note - the optiboot suffix might be visually cut off due to the width of the menu; the second / lower set of board definitions in the board menu are the optiboot ones). The 2-Series Optiboot definitions and the 0/1-Series Optiboot definitions are separate entries in the board menu.
See the Optiboot referencefor more information.
These guides cover subsystems of the core in much greater detail (some of it extraneous or excessive).
Covering top-level functions and macros that are non-standard, or are standard but poorly documented, and which aren't covered anywhere else.
The API reference for the analog-related functionality that is included in this core beyond the standard Arduino API.
The API reference for the digital I/O-related functionality that is included in this core, beyond the standard Arduino API, as well as a few digital I/O-related features that exist in the hardware which we provide no wrapper around.
Documents the (largely intended for internal use) dirty inline assembly macros that are used by the core to improve performance or reduce code size.
Includes a list of all interrupt vectors that can be used, how the flags are cleared (not a substitute for the datasheet - just a very quick reminder), which parts each vector exists on, and and what parts of the core, if any, make use of a vector. It also has general guidance and warnings relating to interrupts their handling, including estimates of real-world interrupt response times.
The USARTs (Serial) have some greatly enhanced functionality compared to the stock core.
Serial UPDI is our recommended tool for UPDI programming.
Supported clock sources and considerations for the use thereof.
Manufacturer specs for speed at various voltages, and some discussion of BOD thresholds - this is written largely from a very conservative perspective, in contrast to most of the documentation.
These are provided by the core and can be overridden with code to run in the event of certain conditions, or at certain times in the startup process.
The core feature #define
s are used by megaTinyCore and other cores I maintain as well. This also documents what constant values are defined by the core for version identification, testing for features, and dealing with compatibility problems.
Export compiled binary generates both assembly listings and memory maps, in addition to the hex file. The options selected are encoded in the name of the file to help prevent confusion and make it easy to compare two configurations when you are surprised by the differences between them. Also provides links to a script I wrote to reformate memory maps so you can read the damned things.
The sources of reset, and how to handle reset cause flags to ensure clean resets and proper functioning in adverse events. Must read for production systems
The installation and operation of the Optiboot bootloader (for uploading over straight serial (not SerialUPDI)) is described here. Not recommended except on the 20/24-pin 2-Series (since they have the alt reset pin) or for special use cases that demand it.
This contains detailed information on how the timers are used in megaTinyCore, and some background on their capabilities.
These guides are older; some are still relevant.
This has been recently updated and will likely be turned into a Ref_TCA0.
This document describes how (on the 0 and 1 Series only) the ADC can be taken over and reconfigured, with particular attention to free running mode. The 2-Series ADC is different, and it would require changes to reflect those differences.
A delightful, though unfortunately short, document on bare metal programming in C.
The bible of the AVR instruction set. Like any such tome, it is a lengthy document which contains timeless wisdom from the creator(s), written in obtuse and challenging language and a confusing syntax (though you won't go to hell if you don't read it, if you're writing assembly without it, you might not be able to tell the difference).
As promised, a bunch of additional information was released; Unfortunately it leaves some of the key questions unanswered.
printf()
implementation - The default option can be swapped for a lighter weight version that omits most functionality to save a tiny amount of flash, or for a full implementation (which allows printing floats with it) at the cost of about 1k extra flash. Note that if non-default options are selected, the implementation is always included in the binary, and will take space even if not called. This applies everywhere that format strings are used, including Serial.printf()
.attachPortAEnable()
and replace A
with the letter of the port) before attaching the interrupt. This allows attachInterrupt()
to be used without precluding any use of a manually defined interrupt (which is always much faster to respond). Basically any time you "attach" an interrupt, the performance is much worse.millis()
, micros()
and pulseInLong()
will be available. If set to disable, these will not be available, Serial methods which take a timeout as an argument will not have an accurate timeout (though the actual time will be proportional to the timeout supplied); delay()
will still work. Disabling millis()
and micros()
saves flash, and eliminates the millis()
interrupt every 1-2 ms; this is especially useful on the 8-pin parts which are extremely limited in flash. Depending on the part, options to force millis()
/ micros()
onto specific timers are available. A #error
will be shown upon compile if a specific timer is chosen but that timer does not exist on the part in question (as the 0-Series parts have fewer timers, but run from the same variant). If RTC is selected, micros()
and pulseInLong()
will not be available - only millis()
will be.There are however a few cautions warranted regarding megaTinyCore - either areas where the core is different from official cores, or where the behavior is the same, but not as well known.
If you are manually manipulating registers controlling a peripheral, except as specifically noted in relevant reference pages, the stated behavior of API functions can no longer be assured. It may work like you hope, it may not, and it is not a bug if it does not, and you should not assume that calling said API functions will not adversely impact the rest of your application. For example, if you "take over" TCA0, you should not expect that using analogWrite()
- except on the two pins on the 20/24-pin parts controlled by TCD0 - will work for generating PWM. If you reconfigure TCA0 except as noted in Ref_Timers, without calling takeOverTCA0
, both analogWrite()
and digitalWrite()
on a PWM pin may disrupt your changed configuration.
While we generally make an effort to emulate the official Arduino core, there are a few cases where the decision was made to have different behavior to avoid compromising the overall functionality; the official core is disappointing on many levels. The following is a (hopefully nearly complete) list of these cases.
Earlier versions of megaTinyCore, and possibly very early versions of DxCore enabled the internal pullup resistors on the I2C pins. This is no longer done automatically - they are not strong enough to meet the I2C specifications, and it is preferable for it to fail consistently without external ones than to work under simple conditions with the internal ones, yet fail under more demanding ones (more devices, longer wires, etc). However, as a testing aid, we supply Wire. usePullups()
to turn on the weak internal pullups. If usePullups()
ever fixes anything, you should install external pullups straight away. Our position is that whenever external pullups are not present, I2C is not expected to work. Remember that many modules include their own on-board pullups. For more information, including on the appropriate values for pullups, see the Wire library documentation
The official core for the (similar) megaAVR 0-Series parts, which megaTinyCore was based on, fiddles with the interrupt priority (bet you didn't know that!) in methods that are of dubious wisdoom. megaTinyCore does not do this, saving several hundred bytes of flash in the process, and fixing at least one serious bug which could result in the microcontroller hanging if Serial was used in ways that everyone tells you not to use it, but which frequently work anyway . Writing to Serial when its buffer is full, or calling Serial.flush()
with interrupts disabled, or during another ISR (which you really shouldn't do ) will behave as it does on classic AVRs and simply block, manually calling the transmit handlers, until there is space in the buffer for all of the data waiting to be written or the buffer is empty (for flush()
). On th stock megaAVR core, this could hang forever.
This is deprecated on the official core and is, and always has been, a dreadful misfeature. Dropped as of 2.3.0.
digitalRead()
Does Not Turn Off PWM On official cores, and most third party ones, the digitalRead()
function turns off PWM when called on a pin. This behavior is not documented by the Arduino reference. This interferes with certain optimizations, makes digitalRead()
take at least twice as long (likely much longer) as it needs to and generally makes little sense. Why should a "read" operation change the thing it's called on? We have a function that alters the pin it's called on: digitalWrite()
. There does not seem to be a logically coherent reason for this and, insofar as Arduino is supposed to be an educational platform it makes simple demonstrations of what PWM is non-trivial (imagine setting a pin to output PWM, and then looking at the output by repeatedly reading the pin).
digitalWrite()
and INPUT
Pins Like the official "megaavr" core, calling digitalWrite()
on a pin currently set INPUT
will enable or disable the pullups as appropriate. digitalWrite()
also supports "CHANGE" as an option; on the official core, this will turn the pullup on, regardless of which state the pin was previously in, instead of toggling the state of it. The state of the pullup is now set to match the value that the port output register was just set to.
This was done because of the huge volume of code that makes use of this behavior. We experimented with making pinMode() do the inverse for INPUT and INPUT_PULLUP, but this was removed by unanimous agreement by everyone in the discussion thread.
analogWrite()
and TCD0 Pins Please see the above PWM feature description if using PWM on those pins and also using digitalRead()
or direct port writes on the same pins (PIN_PC0, and PIN_PC1).
On the official "megaavr" board package, TCA0 is configured for "single mode" as a three-channel 16-bit timer (used to output 8-bit PWM). megaTinyCore always configures it for "Split mode" to get additional PWM outputs. See the datasheets for more information on the capabilities of TCA0. See Taking over TCA0 for information on reconfiguring it. One downside to this is that the compare channels do not support buffering, so changing the duty cycle can cause a glitch lasting up to one PWM cycle (generally under 1 ms).
0 is a count, so at 255, there are 256 steps, and 255 of those will generate PWM output - but since Arduino defines 0 as always off and 255 as always on, there are only 254 possible values that it will use. The result of this is that (I don't remember which) either analogWrite(pin,254)
results in it being LOW
2/256's of the time, or analogWrite(pin,1)
results in it being HIGH
2/256's of the Zeit. On megaTinyCore, with 255 steps, 254 of which generate PWM, the hardware is configured to match the API, and this does not occur. As it happens, 255 also (mathematically) works out such that integer math gets exact results for millis()
timing with both 16-MHz-derived and 20-MHz-derived clock speeds, which is relevant when TCA0 is used for millis()
Timing. The same thing is done for TCD0, though to 509, giving 510 steps. analogWrite()
accounts for this, so that we can get the same output frequency while keeping the fastest synchronization prescaler for fastest synchronization between TCD0 and system clock domains.
On the official "megaavr" board package, as well as DxCore, the Type B timers are used to generate 8-bit PWM (one pin per timer). There are very few circumstances where this could increase the number of usable PWM pins. These timers are just too scarce and valuable on these parts. Being minimally useful for PWM, in short supply, and highly desirable for other purposes, support for using Type B timers for PWM was removed in order to save space that would otherwise be used initializing these timers for PWM and handling them in analogWrite()
et . al. If a Type B timer is used for millis()
, it is configured in a radically different way than the official core does it.
They return and expect uint8_t
(byte) values, not enum
s like the official megaavr board package does. Like classic AVR cores, constants like LOW
, HIGH
, etc are simply #define
d to appropriate values. The use of enum
s unfortunately broke many common Arduino programming idioms and existing code (granted, these idioms were poor programming practice - they're also incredibly widespread and convenient), increased flash usage, lowered performance and made optimization more challenging. The enum
implementation made language design purists comfortable and provided error checking for newbies, because you couldn't pass anything that wasn't a PinState to a digital I/O function and would see that error if you accidentally got careless. Nevertheless, due to all the complaints, a compatibility layer was added to the official core, so all the old tricks would work again, it was just less performant. However, that got rid of what was probably the most compelling benefit by allowing the workarounds: the fact that it did generate an error for new users to train them away from common Arduino practices like passing 1 or 0 to digitalWrite()
, if(digitalRead(pin))
and the like. The choice of names of the enum
s also had the perverse effect of making PinMode(pin,OUTPUT)
(an obvious typo of pinMode(pin,OUTPUT)
) into valid syntax (comma operator turns pin,OUTPUT
into OUTPUT
, and it returns a new PinMode
of value OUTPUT
...) and does nothing with it, instead of a syntax error (It took me over an hour to find the erroneous capitalization. That evening, I converted the digital I/O functions to the old signatures and removed the enum
s). Anyway - the enum
s are not present here, and they never will be; this is the case with MegaCoreX and DxCore as well.
There are two classes of significant low level architectural differences (aside from the vastly improved peripherals): the improved instruction set and the unified memory address space.
The classic AVR devices all use the venerable AVRe
(ATtiny) or AVRe+
(ATmega) instruction set ( AVRe+
differs from AVRe
in that it has hardware multiplication and supports devices with more than 64k of flash). Modern AVR devices (with the exception of ones with minuscule flash and memory, such as the ATtiny10, which use the reduced core AVRrc
) all use the latest iteration of the AVR instruction set, AVRxt
. AVRxt
has much in common with AVRxm
(used in XMega parts) in terms of instruction timing - and in the few places where they differ, AVRxt
is faster (SBIC, as well as LDD, and LD with pre-decrement, are all 1 clock slower on AVRxm
vs AVRxt
or AVRe
), however AVRxt
doesn't have the single-instruction-two-clock read-and-write instructions for memory access LAT
, LAC
, LAS
, and XCH
. The difference between subspecies of the AVR instruction set is unimportant for 99.9% of users - but if you happen to be working with hand-tuned assembly (or are using a library that does so, and are wondering why the timing is messed up), the changes are:
As you can see, everything that involves writing to the SRAM is faster now; it would appear that any time it is writing to a location based on one of the pointer registers or the stack pointer, it's a single cycle. All the other improvements except CBI
and SBI
can be viewed as a consequence of that. Of course, the variants of CALL
are faster; they have to put the return address into the stack. I can't say I've ever felt like LAT
, LAC
, or LAS
would be terribly useful as they are described in the instruction set manual - those take a register and the address pointed to by the Z register, load the contents of the specified address and toggle, set or clear in that memory address the bits that were set to begin with in the register. If that worked on special function registers, it would be a very useful instruction, taking PERIPHERAL.REGISTER |= SOME_BIT_bm;
from a 5 clock, non-atomic operation to a 2 clock atomic one! But it says they only work on SRAM... so not as much of a loss. XCH
is more obviously useful than the others, but all 4 of them come with the need to set up the Z register... which in many cases would take long enough that it wouldn't be a notable improvement.
Note that the improvement to PUSH
can make interrupts respond significantly faster (since they have to push the contents of registers onto the stack at the beginning of the ISR), though the corresponding POP
s at the end aren't any faster. The change with ST
impacted tinyNeoPixel. Prior to my realizing this, the library worked on SK6812 LEDs (which happened to be what I tested with) at 16/20 MHz, but not real WS2812's. However, once I discovered this, I was able to leverage it to use a single tinyNeoPixel library instead of a different one for each port like was needed with ATTinyCore (for 8 MHz, they need to use the single cycle OUT
on classic AVRs to meet timing requirements, the two cycle ST
was just too slow; hence the port had to be known at compile time, or there must be one copy of the routine for each port, an extravagance that the ATtiny parts cannot afford. But with single cycle ST
, that issue vanished).
Oh, and one other instruction it doesn't have that (some) AVRxm parts have: The hardware DES
encryption instruction - an instruction which is most effective at marking AVRxm as, ah, back from the time when DES
was a big deal.
On all modern AVRs with up to 48k of flash, both the flash and ram reside in the same address space - On tinyAVRs, the program memory starts at 0x8000, while on megaAVR 0-Series, it starts at 0x4000 to leave room for the 48k of flash that they can have, and on the Dx-Series parts with up to 32k of flash, they have the same layout as the tinyAVRs, while Dx-Series parts with 64k or 128k of flash have a 32k section of flash mapped at any given time (how to make sure variables go into this memory mapped flash has been described elsewhere in this document). There is another big and fundamental change to the layout of the address space as well: the registers are organized by peripheral. PORTA is assigned 0x400 to 0x41F. PORTB is the next 32 bytes, and so on - and the address space is far sparser - all the peripherals have multiple "reserved" registers that may or may not get functions added in the future. And each instance of a peripheral on a part that has multiple of them has the same layout. You can, say, pass a pointer to a TCB around without the functions that get it knowing which TCB they'll get, and then access the TCB registers through it. On classic AVRs the names of the registers were consistent, but their locations were all over the place, packed much more tightly, so that sort of trick isn't possible. This also means that the EEPROM (and USERROW) are part of this unified address space (on classic AVRs, reading was accomplished through special function registers, and was far more awkward).
The lowest 64 registers are special - you can read or write them with the IN
or OUT
instructions (hence, "I/O space") in a single clock cycle, without setting up a pointer to them as you would need to with ST
or LD
. The 32 "Low I/O registers" additionally have bit-level access instructions CBI
and SBI
to clear and set bits, and SBIC
/ SBIS
to skip the next instruction if a certain bit is set or cleared. On all AVRxt parts released so far, the low I/O registers are used only for the VPORTs, up to VPORTG or the last port on the part, whichever comes first. This means VPORTG.OUT |= 1 << n
, where n is known at compile-time and constant , is a 1 clock cycle atomic operation , while VPORTG.OUT = 1 << n
(note the =
in lieu of |=
) takes two clock cycles. For the latter, the first cycle is to put the value to be stored into a register, and the second is to write it with an OUT
instruction. The GPIOR0-3 registers occupying the last 4 bytes in the low I/O space (those are user-defined registers to use as you choose. We use GPIOR0 internally during startup to record reset cause, and store two types of warnings applicable to tuning ). The reset flag register is always cleared very early in startup to prevent dirty resets, and when using a bootloader, so that it can honor bootloader entry conditions on next reset). No other part of this core touches those registers, and we only set GPIOR0; we never read it. So all can be used freely, as long as you remember that GPIOR0 is not empty when you enter setup, and contains the reset cause flags. Other Low I/O registers are not used by the hardware.
The 32 "high I/O registers" are used even less - they only contain the the stack pointer, RAMPZ
on the 128k DA/DB parts, SREG
, and CCP
(Configuration Change Protection - where _PROTECTED_WRITE()
does it's magic to let you write to protected registers. That's all - 5 out of 32 registers are used, the rest are "reserved". On classic AVRs, registers for assorted peripherals that the designers thought would be accessed often were put into the I/O space, so it was a disappointment that they didn't put an alias of any other registers there. I'd vote for the intflags registers to be aliased there
megaTinyCore itself is released under the LGPL 2.1. It may be used, modified, and distributed freely, and it may be used as part of an application which, itself, is not open source (though any modifications to these libraries must be released under the LGPL as well). Unlike LGPLv3, if this is used in a commercial product, you are not required to provide means for users to update it.
The DxCore hardware package (and by extension this repository) contains DxCore as well as libraries, bootloaders, and tools. These are released under the same license, unless specified otherwise . For example, tinyNeoPixel and tinyNeoPixel_Static, being based on Adafruit's library, are released under GPLv3, as described in the LICENSE.md in those subfolders and within the body of the library files themselves.
The pyupdi-style serial uploader in megaavr/tools is a substantially renovated version of pymcuprog from Microchip, which is not open source has now been released under the open source MIT license! .
Any third party tools or libraries installed on behalf of megaTinyCoreCore when installed via board manager (including but not limited to, for example, avr-gcc and avrdude) are covered by different licenses as described in their respective license files.