Softwareentwicklung für die Motorsteuerung DSP TMS320F28

In meinem ersten Artikel habe ich über diese Controller-Familie gesprochen, mehr als ein Dutzend Leute haben mir in PM mit Fragen dazu geschrieben, obwohl dies nicht das Thema des Artikels war. Die Leute wollten kategorisch nicht zu Google gehen und sprachen über den Mangel an Informationen. Ich war ein wenig überrascht und entschied mich zu überprüfen - tatsächlich gibt es auf Russisch praktisch nichts in der C2000-Familie (vor dem Hintergrund von AVR, STM), und vor allem gibt es keine klaren Startanleitungen. Informationen können auf Englisch gefunden werden, aber es reicht nicht aus. Für mich ist das etwas überraschend, da diese Familie nicht wenige Jahre alt ist. Daher wurde beschlossen, die Situation nach besten Kräften zu beeinflussen.

Wer braucht diese Steuerungen grundsätzlich ... Möchten Sie einen Schweißwechselrichter montieren? Unterbrechungsfreie Stromversorgung? Galvanisierbadglätter? Frequenz? Ein Wechselrichter für alternative Energie? CNC-Maschine? Wenn es in mindestens einem Punkt um Sie geht, ist der Artikel Ihnen gewidmet!

Andere Leser werden ebenfalls daran interessiert sein, mehr über den "neu-alten" Controller zu erfahren, warum er benötigt wird und wie man damit arbeitet. Diese Familie ist sehr einfach (viel einfacher als STM, LPC und andere Cortex), die Steine ​​sind leicht zu kaufen (es gibt auch Ali), sie ermöglichen es Ihnen, hochzuverlässige industrielle Lösungen zu implementieren, auf deren Grundlage Sie fast jedes industrielle Steuerungssystem bauen können.

Haben Sie bereits entschieden, dass dieser Controller Ihr Traum ist und bereit ist, in die Schlacht zu eilen? Dann kaufen wir für 17 US-Dollar das folgende Debugging von F28027-LaunchPad:


Hast du gekauft Jetzt kannst du in die Schlacht ziehen. Wenn sich die Frage stellte, wo man "besser" und "billiger" kaufen kann, gehen wir zum offiziellen Laden. Wir gehen hierher und sehen den Preis von 17 $. Für diesen Betrag erhalten Sie eine Original-Debugging-Gebühr und eine Kurierzustellung an die Tür. Ich habe einmal in China für die Lieferung bestellt, es stellte sich heraus, 16 $ und es ist mit einem Rabatt und einem Gutschein sowie einer "Bonus" -Reise zur Post. Daher empfehle ich es ist der Beamte. Lass uns gehen!

Übersicht über die C2000-Serie


Sie können auf der offiziellen Website natürlich alles auf Englisch am ausführlichsten lesen. Ich werde kurz darüber sprechen und meine Gedanken über die Anwendung zum Ausdruck bringen. Bitte beachten Sie, dass dies nur meine Spekulation ist und sie nicht die Wahrheit behaupten.

Zunächst ein paar Worte zum C2000 im Allgemeinen. Besondere Merkmale der Familie, die mit ihrem Hauptzweck der Motorsteuerung verbunden sind, sind das Vorhandensein von HRPWM (hochpräzises PWM) und CLA (Coprozessor). Letzteres fehlt beim jüngsten Piccolo TMS320F2802x wirklich, wird dort aber nicht benötigt, Hauptsache HRPWM. Was ist das? HRPWM selbst ist ein reguläres PWM, es ist nur sehr genau und die Aufzeichnungs- und Einstellzeit für einen neuen Arbeitszyklus ist erheblich schneller. Dies ermöglicht es beispielsweise, einen perfekt geformten Sinus in einem DC / AC-Wechselrichter zu erhalten oder Schrittmotoren in einer CNC-Maschine mit sehr hoher Genauigkeit zu steuern.

CLA ist im Wesentlichen ein vollwertiger Kern, hat jedoch keinen Zugriff auf Peripheriegeräte, sondern nur auf den Hauptkern und den Speicher. Es dient dazu, den Hauptkern vom Computing zu entlasten. Dieser Coprozessor verarbeitet Float-Daten sehr einfach und auf natürliche Weise. Dies ist wichtig, wenn verschiedene Algorithmen, Filter und mehr implementiert werden.



Ich werde über zwei Hauptfamilien sprechen, denen Sie wahrscheinlich begegnen werden:

  • Piccolo. Die jüngsten Controller, aber auch die billigsten. Mein TMS320F28027 stammt aus dieser Familie. Wenn Sie sich für die Entwicklung von Leistungselektronik für kommerzielle Zwecke entscheiden, sind dies Ihre Hauptsteine ​​- sie sind recht billig, kostenpflichtig (LQFP, QFN, TSSOP) und ermöglichen es Ihnen, fast alles zu implementieren. Zum Beispiel reicht ihre Leistung für einen zweiphasigen PFC, einen Wechselrichter für Solarmodule, einen Frequenzumrichter bis 10 kW mit Vektorsteuerung usw. aus. Wie Sie sehen, handelt es sich um ein Produktsegment, das von normalen Menschen und Unternehmen gekauft wird, was bedeutet, dass es sehr gefragt ist. Die Hauptbeschränkungen sind die Frequenz von 60 MHz, eine begrenzte Anzahl von PWM-Kanälen.
  • Delfino. Ideologisch sind dies alle die gleichen Piccolo, nur mit Meldonium aufgeblasen. In dem, was es ausdrückt - einer Frequenz von bis zu 200 MHz, gibt es in älteren Steinen bereits 2 vollwertige Kerne + 2 Coprozessoren, große Gehäuse und dementsprechend viele Beine, viele PWM-Kanäle, viele ADCs und im Allgemeinen viel. Das heißt, in älteren Steinen haben wir 4 Kerne mit einer Frequenz von 200 MHz, eine Leistung von 800 MIPS, was ziemlich beeindruckend ist. Diese Leistung kann auf verschiedene Arten verwendet werden, aber die Hauptanwendung sind algorithmisch komplexe Systeme, zum Beispiel der Vienne-Gleichrichter oder etwas anderes. Auf einer solchen Steuerung können Sie auch das gesamte Steuerungssystem für eine CNC-Maschine implementieren, z. B. Fräsen oder Flammenschneiden von Metall.

Finalisierung des Debugboards


Wenn Sie eine Box mit einer Debug-Karte erhalten, finden Sie den fehlenden Quarz und die Kondensatoren. Sie sind nicht notwendig, aber es ist ratsam zu dope. Ich habe keinen Quarz mehr im HC-49, also musste ich ihn mir von einem Freund ausleihen. Er wählt AVR und STM, also hat er nur 8 MHz gefunden. Gelötet. Ich habe 22 pF Kondensatoren aus dem alten Speicher hinzugefügt, wie ich es bei Mega in der Schule getan habe.

Diese Lösung ist nicht die beste und hängt mit der PLL-Konfiguration zusammen. Der maximale Multiplikator für PLL ist x12 (mehr kann sein, wird aber nicht empfohlen und funktioniert schief). Die maximale Frequenz beträgt 60 MHz. Der Maximalwert des Teilers am PLL-Ausgang beträgt 3. Die Frequenz des Quarzes beträgt 8 MHz. Ich kann nicht mit 8 mit einer ganzen Zahl multiplizieren und 60 erhalten. Wir suchen nach dem nächsten Gesamtwert, in diesem Fall 240. Das heißt, ich werde 8 mit 30 multiplizieren und dann durch 4 dividieren, um die begehrten 60 MHz zu erhalten, aber das Problem ist, dass der x30-PLL-Multiplikator nicht akzeptabel ist , divider / 4 ist ebenfalls nicht verfügbar. Es gibt zwei Auswege:

  • Schlecht: Multiplizieren Sie die Frequenz von 8 MHz mit 7 und dividieren Sie durch 1 und erhalten Sie 56 MHz. Sie können mit 8 multiplizieren und 64 MHz erhalten, es wird stabil funktionieren, aber in beiden Fällen beträgt die Frequenz nicht maximal 60 MHz. Leider nicht genug Perfektionismus. Ich habe gerade eine solche Option, 8 MHz gelötet und eine Frequenz von 56 MHz gemacht.
  • Gut: Kaufen Sie Quarz bei 10 oder 20 MHz (besser als 10) und multiplizieren Sie mit 6, dividieren Sie durch 1, wir erhalten die geschätzten 60 MHz. Ich lebe außerhalb der Stadt und ehrlich gesagt war es zu faul, in ein lokales Geschäft zu gehen, in dem es keine Tatsache ist, dass es 10-MHz-Quarz gibt. Natürlich werden sowohl die interne RC-Schaltung als auch der 8-MHz-Quarz für das Training verwendet, aber in Ihren zukünftigen Projekten sollten Sie den 10-MHz-Quarz und nicht die Mammutmutanten in das HC-49-Paket aufnehmen.

Architektur und periphere Merkmale


Alles, was als nächstes passieren wird, gilt für den TMS320F28027-Controller. Schauen wir uns zunächst die Struktur aus dem Datenblatt an :



Das erste, worauf Sie achten sollten, ist, dass RAM in drei Sektoren unterteilt ist: M0, M1 und SARAM. Das Volumen dieser Speichersektoren beträgt in unserem Fall 1k, 1k und 4k. Es ist erwähnenswert, dass in diesem Fall das Wort nicht 8 Bit, sondern 16 Bit ist, dh in einer bekannteren Form 2 kB + 2 kB + 8 kB. Die Besonderheit dieses Moduls besteht darin, dass die Sektoren M0 und M1 schneller sind als die verbleibenden 8 kB RAM. Formal können Sie dies als Cache verwenden. Die Sektoren M0 und M1 speichern normalerweise die am häufigsten verwendeten Daten sowie die Daten, die für die Speicherleistung am kritischsten sind. Standardmäßig können wir den Linker verwenden, um anzugeben, was und wo gespeichert wird. Ich werde dieses Thema in diesem Artikel jedoch nicht ansprechen. Hier wird mindestens ein separater Artikel benötigt.

Das zweite wichtige Merkmal ist, dass alle Peripheriegeräte vom Systembus getaktet werden, d. H. Von 60 MHz (in meinem Fall 56 MHz). Als Beispiel gebe ich die STM32-Mikrocontroller an, bei denen die Kernfrequenz beispielsweise 180 MHz für F4 beträgt, die Peripheriegeräte jedoch über eine Reihe von Teilern getaktet sind. Ich nenne diesen Ansatz für mich „Fake Megahertz“, obwohl dies sehr übertrieben ist. Daher sind 60 MHz für TMS320F28 und 180 MHz für stm32 nicht so unterschiedlich, und wenn Sie sich an das Vorhandensein von CLA erinnern, sind 60 + 60 MHz zumindest vergleichbar. Es ist klar, dass ein solcher Vergleich nicht korrekt ist, aber es macht deutlich, dass nicht nur Megahertz voll ist.

Ebenfalls ein interessanter Punkt - achten Sie auf die allgemeine Struktur: HRPWM, ADCs, Komparatoren mit internem DAC, Encoder Processing Module (eCAP) ... Ein fertiger Frequenzumrichter mit Vektorsteuerung in seiner reinen Form! Das ist die ganze Essenz dieser Familie - der Minimalismus. Einerseits ist die Peripherie im Vergleich zu Cortex eher schlecht, andererseits reicht es aus, einen Frequenzumrichter, Gleichstrom / Gleichstrom, Gleichstrom / Wechselstrom und einen Schrittmotortreiber zu implementieren. Aus diesem Grund ist die Arbeit mit den TMS320F28-Controllern sehr einfach, verständlich und nicht mit unnötigen Aktionen überlastet. Aber wenn Sie plötzlich 3 UARTs benötigen und für sie ein Paar i2c und 3 weitere SPIs, dann sind diese Controller definitiv nichts für Sie - sie haben unterschiedliche Aufgaben.

Entwicklungsumgebung



Haben Sie sich das Splash-Logo angesehen? Erinnere dich an sie. Wenn Sie sich entscheiden, Artikel für die Entwicklung der Helden des Artikels zu verwenden, gehört diese Software Ihnen, und wie Sie sehen, heißt die Software controlSUITE .

Diese Anwendung ist eine Sammlung und Bibliothek von allem, was Sie zur Entwicklung von Software für die Controller-Familie C2000 benötigen. Die Installation dieser Anwendung ist das erste, was Sie tun müssen, um ihre Zusammensetzung zu sehen. Sie enthält:

  • Beschreibung aller vorhandenen Controller und darauf basierenden Debug-Boards. Schaltungsquellen, Leiterplatten, Stücklisten hauptsächlich in Altium Designer
  • Beispiele für Schaltungen und Design von Leiterplatten
  • Kernbibliotheken für die Firmware-Entwicklung
  • Mathematik- und DSP-Bibliotheken, auch zur Verwendung mit CLA
  • Ein Beispiel für Softwareprojekte für jeden Peripherietyp
  • Eine große Anzahl von Apnouts für die Implementierung der meisten Algorithmen zur Steuerung von Motoren, DC / DC-Wandlern, MPPT-Controllern und anderen Systemen
  • Eine Reihe von Programmen, mit denen Sie ein Motormanagementsystem ohne Programmierung erstellen können, indem Sie einfach eine grafische Umgebung verwenden
  • Die IDE selbst, die entwickelt wird

Alles, was ich oben beschrieben habe, ist sehr kurz und bescheiden. Es dauert einige Wochen, bis Sie mindestens diagonal sehen und scrollen. Natürlich werden Sie zu Beginn nicht die meisten dieser Datenmengen benötigen, aber Sie müssen sich merken, wohin Sie gehen müssen, wenn etwas für Sie unverständlich und ausgefallen ist.

Was wir heute arbeiten werden, ist die IDE, deren grafischer Teil auf der Basis der bekannten Eclipse basiert. Der Compiler ist kein GCC, sondern ein eigener aus Texas, der meiner subjektiven Meinung nach definitiv besser ist als der erste. Obwohl es den Verdacht gibt, dass dies trotzdem gründlich dotiert ist. Die Entwicklungsumgebung heißt Code Composer Studio , die aktuelle Version 7.4.

Projekterstellung


Zuerst wollte ich eine Aufgabe implementieren, die mit dem ersten Artikel identisch ist, dh einen Sinus zeichnen. Im Rahmen eines Artikels hätte dies im Prinzip getan werden können, wobei ein Rahmen eine sehr große Menge kleiner Dinge zurückgelassen hätte, aber wie Sie wissen, liegt die Essenz genau in kleinen Dingen. Es gibt mehrere Artikel über das TMS im Internet, aber sie sind alle sehr oberflächlich und führen zu der Art „kopiere dies und alles funktioniert“, dh der Prozess selbst und die Ideologie werden überhaupt nicht berücksichtigt. Daher werden wir im Rahmen dieses Artikels ein Projekt erstellen, unnötige Komponenten entfernen, die Firmware im Flash-Speicher des Controllers konfigurieren und lernen, wie man mit GPIO arbeitet. Diese sind hier sehr interessant.

Laden Sie CCS7 von der Website des Herstellers herunter, installieren Sie das Projekt und erstellen Sie es wie gewohnt: Datei → Neu → CCS-Projekt ...


Wir sehen dieses Fenster und müssen darin den Controller auswählen, der uns interessiert. In meinem Fall ist es TMS320F28027, den Namen des Projekts angeben und den Pfad vorgeben, in dem es gespeichert wird. Zuerst müssen Sie einen Ordner erstellen, in dem das Projekt gespeichert wird. Der Projektname und der Ordnername stimmen möglicherweise nicht überein. Klicken Sie auf die Schaltfläche Fertig stellen und unser Projekt wird erstellt.

Jetzt müssen Sie unser Projekt mit Inhalten füllen und verbinden. Erstellen Sie zuvor folgende Ordner, um die Struktur des Projekts zu verbessern:


  • inc - Ein Ordner, der alle Header-Dateien enthält
  • system_inc - In diesem Abschnitt werden die Header-Dateien der Standardbibliotheken gespeichert. Die Dateien, die wir selbst erstellen, z. B. main.c, befinden sich im Ordner inc. Dies wird nicht etwas gedankenlos brechen oder unnötig entfernen
  • src - Ordner mit allen Quellen
  • system_src - Ordner mit Quelldateien für Standardbibliotheken

Bitte beachten Sie, dass diese Struktur kein Dogma ist, sondern nur meine Idee der Bestellung. Obwohl ich es Leuten mit minimaler Erfahrung empfehlen werde, werden Sie es im Laufe der Zeit ändern, um es Ihrem Weltbild anzupassen, aber im Moment wird dies die Anzahl der Pfosten minimieren.

Erstellen Sie nun die Datei main.h im Ordner inc und verbinden Sie sie mit main.c. Durch sie werden die Basisbibliotheken verbunden. Bevor Sie mit dem Übertragen von Bibliotheken und anderen Dateien beginnen, schreiben Sie den Pfad zu den Ordnern auf, in denen unsere zukünftigen Header-Dateien in den Projekteinstellungen gespeichert werden. Klicken Sie dazu mit der rechten Maustaste auf das Projekt (Test) in der Projektstruktur und klicken Sie unten auf Eigenschaften oder drücken Sie einfach Alt + Eingabetaste . Gehen Sie im folgenden Fenster zu Build → C2000 Compiler → Include Options und schließen Sie hier zwei vorhandene Pfade ein - registrieren Sie den Pfad zu den Ordnern inc und system_inc. Klicken Sie auf Hinzufügen , dann auf Arbeitsbereich und dann auf den gewünschten inc-Ordner. Machen Sie dasselbe und klammern Sie sich an den zweiten Ordner. Daher haben wir relative Pfade vorgeschrieben. Wenn Sie ein Projekt übertragen, müssen Sie nichts neu konfigurieren. Als Ergebnis erhalten wir ein solches Bild und klicken auf OK :



Jetzt haben wir ein leeres Projekt mit den vorgeschriebenen Pfaden und anderen Einstellungen, es bleibt nur, um es mit Bibliotheken zu füllen. Sie müssen nur prüfen, ob alles angeschlossen ist. Theoretisch sollten Sie einen solchen Code und ein Bild erhalten, das Projekt kompilieren. Drücken Sie dazu STRG + B oder gehen Sie oben zu Projekt → Alle erstellen. Das Projekt sollte fehlerfrei kompiliert werden und so aussehen (das Bild ist anklickbar):



Lassen Sie uns nun ein wenig über den Linker sprechen. Beim Erstellen eines Projekts generiert die IDE zunächst die Datei 28027_RAM_lnk.cmd und legt unser Programm während des Debuggens und der Firmware im RAM ab. Dies ist praktisch, wenn wir debuggen, weil Flash-Speicherressourcen werden nicht verschwendet und das Debuggen im RAM ist erheblich schneller. Aber was ist, wenn wir Blitz einnähen wollen? Zu diesem Zweck gibt es eine weitere Linkdatei, die unser Programm in Flash platziert. Ich werde diese Option zeigen.

Löschen Sie zunächst die Datei 28027_RAM_lnk.cmd . Wie gesagt - controlSUITE ist unser Alles. Wir öffnen es. Gehen Sie nun zu Englisch → Gerät → Piccolo F2802x → Unterstützende Bibliotheken → Header-Dateien für F28027x . Rechts sehen wir Ordner - dies sind die Standardbibliotheken und alles, was benötigt wird, einschließlich Linker. Jetzt gehen wir zum Ordner f2802x_common → cmd und hier sehen wir eine Reihe von Linkern für alle Steine ​​in der Linie. Es ist nicht schwer, die _RAM-Dateien zum Hochladen von Code in den Arbeitsspeicher und ohne dieses Tag zum Hochladen über Flash zu erraten. Wir nehmen die Datei F28027.cmd und kopieren sie in unser Projekt anstelle des alten Remote-Linkers.

Jetzt ist es Zeit, die Bibliotheken selbst zu migrieren. Wir gehen zum Ordner f2802x_common → source und sehen eine Reihe von Dateien. Es gibt zwei Arten von Bibliotheken: Standardregister (ähnlich wie CMSIS) und eine Art SPL. In diesem Fall interessiert uns nur die erste Ansicht, dh Dateien mit dem Präfix f2802x_ . Natürlich können Sie alle in unser Projekt ziehen, aber warum sollten Sie es verstopfen, wenn wir nicht alles verwenden? Wenn Sie etwas brauchen, fügen wir es in Zukunft einfach hinzu. Im Moment beschränken wir uns auf folgende Dateigruppen:

  • f2802x_codestartbranch.asm
  • f2802x_defaultisr.c
  • f2802x_piectrl.c
  • f2802x_pievect.c
  • f2802x_sysctrl.c

Wir kopieren die Datendatei und fügen sie in unseren Ordner system_src ein . Nun gehen wir zum Ordner f2802x_headers → source und nehmen von dort die Datei F2802x_GlobalVariableDefs.c und kopieren sie erneut in unseren Ordner system_src . Wechseln Sie als Nächstes zum Ordner f2802x_headers → cmd und kopieren Sie die Datei F2802x_Headers_nonBIOS.cmd von dort in denselben Ordner. Damit ist das Ausfüllen des Ordners system_src abgeschlossen und Sie können mit den Headern fortfahren.

Wir gehen in den Ordner f2802x_headers → include und kopieren alle Dateien von dort in unseren Ordner system_inc . Nun gehen wir zum Ordner f2802x_common → source und kopieren die Dateien von dort:

  • f2802x_examples.h
  • f2802x_globalprototypes.h
  • f2802x_i2c_defines.h
  • f2802x_epwm_defines
  • f2802x_swprioritizedisrlevels.h
  • f2802x_defaultisr.h

Wir sollten dieses Bild im Projektbaum bekommen:


Jetzt müssen Sie die Basisbibliotheken verbinden. Die Datei main.h hat die folgende Form:

#pragma once #include "F2802x_Device.h" #include "F2802x_examples.h" 

Wir versuchen zu kompilieren. Wenn das Projekt ohne Fehler und Warnungen kompiliert wurde, ist alles korrekt verbunden. Wenn dies nicht geschehen ist, überprüfen Sie alle 10 Male, und wenn es überhaupt nicht funktioniert, schreiben Sie an die PM - ich werde helfen, wie Owl sagte: "Baz-woz-mEz-bottom, das heißt umsonst . "

Initialisierung der Steuerung und des Taktsystems


In diesem Abschnitt schreiben wir eine Funktion, die den Watchdog-Timer und die Interrupt-Vektoren initialisiert und die Interrupt-Flags auf Null setzt. Wir haben auch das Taktsystem eingerichtet, wodurch der externe Quarz anstelle der internen RC-Kette zur Taktquelle wird, die PLL konfiguriert und die Taktung für alle Peripheriegeräte aktiviert.

Für die Genauigkeit des Codes schlage ich vor, alle grundlegenden Initialisierungen in einer separaten Datei abzulegen , deren Frontend die Funktion void InitStartSystem (void) sein wird . Erstellen Sie dazu die Dateien systemInitStart.h und systemInitStart.c . Ich werde sofort eine Funktion schreiben und dann analysieren wir einfach ihren Inhalt:

 void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLCR, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); } 

Alle Funktionen, die in InitStartSystem () aufgerufen werden, sind Standard. Ich rate Ihnen, im Detail zu sehen, wie sie implementiert werden. Dazu können Sie die STRG-Taste gedrückt halten und auf die gewünschte Funktion klicken. Hast du geschaut? Jetzt kurz durchgehen ...

  • DisableDog () - Die Funktion schaltet den "Hund" aus. Dies ist ein obligatorischer Schritt beim Einrichten des Hauptteils kritischer Peripheriegeräte, z. B. eines Taktsystems. Im Bibliothekscode, den Sie häufig sehen, wird er dupliziert und dupliziert
  • XtalOscSel () - Diese Funktion implementiert das Umschalten von einer internen Taktquelle auf einen externen Quarz. Ein wichtiger Punkt! Bei dieser Funktion liegt ein Fehler in der Standardbibliothek vor - sie wird nicht deklariert. Wir gehen zur Datei f2802x_globalprototypes.h und fügen unter allen anderen die Zeile extern void XtalOscSel (void) hinzu.



    Der zweite wichtige Punkt! Gehen Sie zur XtalOscSel-Funktion und löschen Sie die Verzögerungsfunktion.



    Der dritte wichtige Punkt! Wir gehen zur Datei f28027x_exmaples.h und kommentieren die Verzögerungsimplementierungsfunktion aus.


  • InitPll (TMS320_PLLMUL, TMS320_DIVSEL) - Die Funktion konfiguriert die PLL. Es werden 2 Werte übertragen: Multiplikator und Divisor. Ihr Wert wird in der Header-Datei angegeben. Ein wichtiger Punkt! Wir öffnen diese Funktion in der Bibliothek und Sie müssen die Verzögerung ganz unten auskommentieren

  • InitPll (TMS320_PLLMUL, TMS320_DIVSEL) - Die Funktion konfiguriert die PLL. Es werden 2 Werte übertragen: Multiplikator und Divisor. Ihr Wert wird in der Header-Datei angegeben. Ein wichtiger Punkt! Wir öffnen diese Funktion in der Bibliothek und Sie müssen die Verzögerung ganz unten auskommentieren
  • InitPeripheralClocks () - Diese Funktion aktiviert einfach die Taktung für die gesamte Peripherie. Ja für alle. C2000 ist keine Lösung für batteriebetriebene Verschraubungen.
    Diese Lösung von Einheiten-Zehntausenden von Kilowatt und erbärmlichen 2-3 mA wird hier keine Rolle spielen. Nun, Sie müssen sich nicht jedes Mal daran erinnern, wenn Sie die Uhr für eine Art SPI eingeschaltet haben oder nicht
  • InitPieCtrl () - Die Funktion deaktiviert alle Interrupts und setzt Interrupt-Flags zurück
  • InitPieVectTable () - Die Funktion füllt die Tabelle mit Interruptvektoren

Eigentlich ist hier alles Initialisierung. Ich denke, viele haben die „wichtigen Punkte“ bemerkt, die mit der Verzögerungsfunktion verbunden sind. Warum haben wir es am Rebstock geschnitten? Ja, alles ist einfach - es ist eine Krücke.

Die TI-Ingenieure haben diese völlig unnötigen Verzögerungen zu einigen Funktionen hinzugefügt, die in den letzten Updates hinzugefügt wurden. Warum - ein Rätsel nicht nur für mich. Register und andere kritische Einträge sind bereits geschützt, sodass unser Controller nicht dumm wird. Übrigens ist es bei der Initialisierung in der Leistungselektronik unmöglich, überhaupt zu "stumpfen", sonst sind es Weichlinge. Vergessen Sie daher für immer die Verzögerungsfunktionen und andere Teufelei, nur Timer! Verzögerungen sind nur für bestimmte Bildungszwecke zulässig, z. B. schnelles Blinken mit einer LED.

Um zu überprüfen, ob der Code funktioniert, rufen wir die Initialisierungsfunktion in main auf, kompilieren, flashen und schließen das GPIO18- Oszilloskop an. Dieser Pin ähnelt dem MCO des STM32, dh er gibt die Systemfrequenz aus. Ein Oszilloskop sollte ein Signal mit einer Frequenz von 56 MHz sehen. Wenn das Oszilloskop gut ist, sehen Sie den Mäander, wenn die Chinesen (sogar gut), dann ist es höchstwahrscheinlich etwas näher am Sinus. Das Einstellen von GPIO18 zur Ausgabe der Systemfrequenz wird in der Funktion InitPeripheralClocks () angezeigt . Zuerst müssen Sie gpio an den Frequenzausgang „anschließen“ und dann den Teiler auf 1 setzen:

  GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // GPIO18 = XCLKOUT SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2; // Set XCLKOUT = SYSCLKOUT/1 

GPIO-Setup


Um mit dieser Familie arbeiten zu können, benötigen wir nur ein Referenzhandbuch, das die TI-Entwickler in mehrere Dateien unterteilt haben, von denen jede eine bestimmte Peripherie beschreibt, was sehr praktisch ist. Laden Sie das Datenblatt hier herunter und gehen Sie zum Abschnitt Dokumentationsunterstützung auf Seite 126. Hier sehen Sie eine Reihe von Links zur Dokumentation mit ihrer kurzen Beschreibung: Errata, eine Anleitung zum Starten der Motorverwaltung und Anleitungen für jede Peripherie. Wir sind an einem Dokument mit dem Namen TMS320F2802x / TMS320F2802xx Piccolo-Referenzhandbuch für Systemsteuerung und Interrupts interessiert. Es enthält die Beschreibung des GPIO und andere grundlegende Systemeinstellungen, die uns interessieren. Wir betrachten das GPIO-Blockdiagramm:



Wir sehen ein ziemlich bekanntes Bild der Eingangs- / Ausgangsanschlüsse des Geräts. Hier und die Möglichkeit, den internen Hosenträger einzuschalten, und die Verwendung eines Signals mit GPIO für Interrupts und andere Annehmlichkeiten. Das Hauptmerkmal dieses Peripheriegeräts im C2000 ist die Möglichkeit der Unterdrückung von Hardware-Interferenzen, beispielsweise das Klappern mechanischer Kontakte einer Taste. Schauen wir uns ein interessantes Diagramm an:



Es zeigt das Prinzip des Lesens des Status von Eingaben. In den meisten Controllern wird der Eingangszustand mit der Taktfrequenz dieser Peripherie gelesen, dh in unserem Fall standardmäßig mit einer Frequenz von 56 MHz, und bei gleichem stm in den älteren Familien sind diese Frequenzen sogar noch höher. Ich denke, jeder versteht, dass der Controller bei einer solchen Frequenz Zeit hat, Störungen und Geräusche zu „sehen“. Manchmal wird eine solche Frequenz benötigt, und manchmal nicht, zum Beispiel, wenn wir eine Schaltfläche abfragen müssen. Warum sollten wir sie alle 18 ns interviewen? Daher haben wir die Möglichkeit erkannt, die Taktfrequenz eines bestimmten Ports mithilfe des CTRL- Registers und der QUALPRDx- Bits zu reduzieren , wobei X einen Wert von 0 bis 3 annimmt: QUALPRD0 ist für GPIO0 ... 7 verantwortlich, QUALPRD1 ist für GPIO8 ... 15 usw. verantwortlich. Tatsächlich ist dies ein gewöhnlicher Frequenzteiler mit einem Koeffizienten von 1 bis 510.



Es macht oft keinen Sinn, eine Taste abzufragen, daher stellen wir den Teiler auf 510 ein, dh auf das Maximum. Wir sehen uns das Diagramm noch einmal an und sehen, dass das Signal nur dann als stabil angesehen wird, wenn sein Pegel für 6 Ticks unverändert war. Die Anzahl der zur Fixierung erforderlichen Maßnahmen kann 1, 3 oder 6 betragen . Je größer der Teiler und je mehr Zyklen wir fixieren, desto stabiler ist der Schutz vor Rattern. Wenn es zu einem Rattern von Kontakten kommt, handelt es sich zunächst um chaotische Übergänge von 0 nach 1 und umgekehrt. Wenn das Rattern vorbei ist und das Signal stoppt und sich für 6 Takte nicht ändert, bedeutet dies, dass die Taste gedrückt wird. Alles Geniale ist einfach.

Schauen wir uns nun die Hauptregister an, wir werden keine Interrupts berühren - nur die Einstellungen der Ports selbst. Zuerst müssen Sie sagen, dass die Register in zwei Typen unterteilt sind: Setup- Register und Datenregister . Erstere sind für die Konfiguration von Eigenschaften verantwortlich, beispielsweise dieser Eingabe oder Ausgabe. Die zweite Gruppe ist für das Schreiben und Lesen des Portstatus verantwortlich.

Setup-Register:

  • GPxCTRL - Register zum Schreiben des Taktteilers . Anstelle von "x" ersetzen wir den Buchstaben "A" - wenn wir GPIO0 ... 31 haben, "B" - wenn wir GPIO32 ... 63 verwenden und so weiter
  • GPAQSELx - Register zum Einstellen der Anzahl der Ticks zum Festlegen des Werts am Eingang
  • GPAMUX1 ist ein Register zur Auswahl angeschlossener Peripheriegeräte. Es zeigt beispielsweise an, dass GPIO oder UART oder möglicherweise PWM zum Fuß kommen.
  • GPADIR - GPIO-Richtungsauswahlregister: Ein- oder Ausgang. Standardmäßig sind alle Ports für die Eingabe konfiguriert.
  • GPAPUD ist das Register, das für den Anschluss des internen Hosenträgers an VCC verantwortlich ist.
    Es ist anzumerken, dass für einige Ports das Pull-up standardmäßig deaktiviert und für einen Teil aktiviert ist.
    Dies ist wichtig zu beachten!

Datenregister:

  • GPADAT - Ausgangsstatusregister. Wenn der Ausgang für die Eingabe konfiguriert ist, lesen wir daraus den Eingabestatus. Wenn es für eine Ausgabe konfiguriert ist, können wir den Wert aufschreiben, den diese Ausgabe annehmen soll, dh 0 oder 1
  • GPASET - Register, das den Ausgang auf "1" setzt. Um auf "1" zu setzen, müssen Sie "1" schreiben. Wenn Sie "0" schreiben, wird der Befehl ignoriert
  • GPACLEAR - Register, das den Ausgang auf "0" setzt. Um auf "0" zu setzen, müssen Sie "1" schreiben. Wenn Sie "0" schreiben, wird der Befehl ignoriert
  • GPATOGGLE ist ein Register, das den aktuellen Wert des Ausgangszustands invertiert. Um den Wert zu invertieren, schreiben Sie "1". Wenn Sie "0" schreiben, wird der Befehl ignoriert

Hier ist so ein einfacher Satz von Registern. Selbst anhand der obigen Beschreibung können Sie bereits verstehen, was zur Konfiguration des Ports getan werden muss, aber die umsichtigen Ingenieure oder technischen Redakteure von TI haben eine weitere schrittweise Anleitung gegeben:



Ich werde gleich sagen, dass die Schritte 6 und 7 für uns nicht notwendig sind, weil In diesem Artikel werden weder der Hund noch die Unterbrechung verwendet. Ich werde die verbleibenden Schritte für Leute, die in der Schule Deutsch gelernt haben, kurz beschreiben:

  • Schritt 1 - Bestimmen Sie die Ausgabefunktionalität: dass es sich um eine Eingabe oder Ausgabe handelt,
    GPIO oder Ausgabe an andere Peripheriegeräte und so
  • Schritt 2 - Aktivieren oder Deaktivieren des internen Pullups
  • Schritt 3 - Konfigurieren Sie den Takt- und Sprungschutz für einen bestimmten Port
  • Schritt 4 - Wählen Sie die gewünschte Funktion: GPIO oder Peripheriegeräte
  • Schritt 5 - Stellen Sie die Ausgaberichtung ein: Eingabe oder Ausgabe

Das ist das ganze Setup, wie Sie sehen, es ist elementar und logisch klar. Ich möchte sofort darauf hinweisen, dass es in dieser Reihenfolge nicht erforderlich ist, Einstellungen vorzunehmen. Sie können beispielsweise die Richtung (Eingabe oder Ausgabe) bereits im ersten Schritt festlegen. Es spielt keine Rolle.

Super wichtig!

Bei der Arbeit mit Registern der C2000-Familie muss der Zeitpunkt berücksichtigt werden, zu dem sie geschützt sind. Alles, was unten beschrieben wird, gilt hauptsächlich für die Register der Konfigurationsgruppe. Wenn Sie sich die Standardfunktionen genau angesehen haben, haben Sie dort wahrscheinlich seltsame Befehle gesehen: EALLOW; und EDIS; . Befehl EALLOW - Entfernt den Schutz und ermöglicht den Zugriff auf die Arbeit mit Systemregistern. EDIS- Befehl - Aktiviert den Rückenschutz und ermöglicht den Zugriff auf die Arbeit mit Systemregistern. Das heißt, jede Arbeit mit Systemregistern sollte IMMER so aussehen:

 EALLOW; //    ,   ,  EDIS; 

Eine solche Operation ist nicht erforderlich, wenn wir mit Datenregistern arbeiten. Wenn wir beispielsweise unseren Ausgang mithilfe des GPxSET- Registers auf „1“ setzen , müssen wir den Schutz nicht entfernen und ihn dementsprechend wieder einschalten. In der Dokumentation steht überall, was geschützt werden muss und was nicht, zum Beispiel so:



Basierend auf all dem oben Genannten konfigurieren wir GPIO0 ... 3 mit LEDs für die Ausgabe. Ich schlage vor, alle GPIO-Einstellungen in die InitLEDgpio- Funktion zu setzen und zu schreiben:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; } 

Standardmäßig sind unsere GPIOs bereits als GPIOs konfiguriert Alle Registerwerte werden gelöscht, was bedeutet, dass „0“ bereits in das GPAMUX1-Register geschrieben wurde. Für GPIO0 ... 11 ist das Pull-up standardmäßig deaktiviert, sodass wir die Arbeitsrichtung zum Ausgang nur mit GPADIR bestimmen können. Wenn Sie sich erinnern, sind die LEDs über Kathoden mit dem Controller verbunden, was bedeutet, dass sie unmittelbar nach der Initialisierung leuchten. Setzen wir diese Schlussfolgerungen direkt in der Initialisierungsfunktion auf „1“:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; } 

Wie Sie sehen können, verwende ich das GPADAT- Register nicht zum Schreiben, sondern SET, CLEAR, TOGGLE . Beachten Sie auch, dass ich diesen Eintrag außerhalb der Schutzzone vorgenommen habe, dh nach dem EDIS- Befehl. Konfigurieren Sie nun in derselben Funktion GPIO12 so, dass es mit der Schaltfläche funktioniert, und fügen Sie unsere Funktion hinzu:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF; GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; } 

Zunächst schalte ich die interne Verschraubung aus , indem ich "1" in das GPAPUD- Register schreibe , weil Es ist standardmäßig von GPIO12 aktiviert. Wie ich bereits geschrieben habe, sind alle Ports nach der Initialisierung für die Eingabe als konfiguriert Nullen werden in das GPADIR- Register geschrieben, wir konfigurieren es hier nicht.

Es bleibt die Konfiguration des Sprungschutzes zu konfigurieren, dazu teilen wir die Teiler 0xFF , die dem Wert / 510 entsprechen. In das Register GPAQSEL1 schreiben wir den Wert „10“ oder 2, wodurch der Wert auf eine Stichprobe von 6 Takten gesetzt wird. Fertig! Um den Wert einer bestimmten Eingabe zu lesen, müssen Sie nur den Wert aus dem GPADAT- Register lesen:

 if (GpioDataRegs.GPADAT.bit.GPIO12) { //      +3.3 (. 1)  ,     } 

So hinterfragen wir die notwendigen Schlussfolgerungen. Rufen wir nun die GPIO-Konfigurationsfunktion in unserer Hauptfunktion auf und erhalten ihre endgültige Form:

 void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLMUL, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); /*********************************/ InitLEDgpio(); } 

Jetzt rufen wir die InitStartSystem- Funktion im Hauptteil des Programms in main auf und damit ist die Konfiguration abgeschlossen. Wir erhalten folgenden Code:

 #include "main.h" int main (void) { InitStartSystem(); while(1) { } } 

Es ist Zeit, unser erstes Testprogramm zu schreiben und das Ganze zu testen. Der Algorithmus lautet wie folgt: Die LED auf GPIO3 blinkt, und wenn Sie die Taste auf GPIO12 drücken, leuchtet die GPIO0-LED einfach auf. Daher werden wir die Funktion der Ports sowohl für die Eingabe als auch für die Ausgabe überprüfen. Wir schreiben den folgenden Code:

 #include "main.h" int main (void) { InitStartSystem(); while(1) { if (GpioDataRegs.GPADAT.bit.GPIO12) { GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; } else { GpioDataRegs.GPASET.bit.GPIO0 = 1; } GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1; delay(100000); } } 

Wir kompilieren, gehen zum Debugger, starten ihn und sehen, wie eine LED ständig blinkt, und wenn Sie die Taste drücken, leuchtet eine andere auf. Am Ende des Abschnitts werde ich ein Projekt mit diesem Code anhängen. Wenn etwas nicht funktioniert, dann schau es dir an. Besonders für diejenigen, die sich mit Texten schwer tun oder nicht alle Punkte verstanden haben, empfehle ich, dieses Video über die Arbeit mit GPIO anzuschauen. Dort geschieht alles, wie im Abschnitt "GPIO". Ich warne Sie, dass das Video für eine Stunde trostlos, lang, aber so detailliert wie möglich und alles sichtbar ist:



Dateien aus dem Artikel


  • Archiv mit dem Projekt für CCS7 hier herunterladen
  • Sie können den Code auf Github sehen

Zusammenfassung


In dieser Phase beende ich den heutigen Artikel. Ich denke, Sie haben verstanden, dass der Artikel um ein Vielfaches größer gewesen wäre, wenn ich mich sofort entschlossen hätte, die DC / AC-Implementierung des Wechselrichters zu zeigen, oder dass viele wichtige Details einfach hinter den Kulissen geblieben wären, was meiner Meinung nach nicht akzeptabel ist.

Ich hoffe, mein Artikel wird allen helfen, mit der Entwicklung dieser Steuerungsfamilie und der Entwicklung auf dem Gebiet der Leistungselektronik und Werkzeugmaschinen zu beginnen. In Zukunft werde ich wahrscheinlich noch etwas zu diesem Thema schreiben, zum Beispiel möchte ich überlegen, mit PWM zu arbeiten oder eine Art Algorithmus zu implementieren. Die Hauptsache ist, Zeit zu haben.

Wenn Sie Fragen haben oder etwas für Sie nicht funktioniert, können Sie mir private Nachrichten schreiben. Ich werde versuchen, Ihre Fragen zu beantworten und alle möglichen Hilfen für die Studie bereitzustellen. Ich wünsche Ihnen viel Erfolg beim Training!

UPD Vielen Dank für den Tipp von BelerafonL zum Buch „Embedded High-Performance Digital Control Systems“.

Source: https://habr.com/ru/post/de410161/


All Articles