07. Arduino für die Produktion!! Wie man einen Pin ausgibt, um eine LED auf dem ARM-Mikrocontroller blinken zu lassen Teil 2
Teilen
Bevor wir mit der Programmierung fortfahren, möchte ich Ihnen ein weiteres Register vorstellen, das wir berücksichtigen müssen, um den GPIO zu aktivieren. Dieses Register heißt RCC, was für Reset, Clock und Control steht. Dieses Register steuert einige Busse, die sich auf dem Mikrocontroller befinden. Der Bus, der uns interessiert, ist der AHB-Bus (Advanced High Performance). Dieser Bus kann auf bestimmte Peripheriegeräte des Mikrocontrollers zugreifen, von denen eines der GPIO ist. Damit dies funktioniert, müssen wir den AHB-Bus über das AHB-Enable-Register (AHBENR) aktivieren, das sich unter dem RCC befindet. Unter diesem Register können wir den Takt für den Port, den wir benötigen, aktivieren, und das wird der GPIOC sein, wobei C der Port ist, den wir verwenden werden.
Zurück im Programm fügen wir etwas Pseudocode für den RCC ein. Aktivieren Sie den GPIO-Takt für Port C mit dem AHB und RCC.
int main(void)
{
// Alle Steuerregister für PortC Pin 6 einstellen
// Moder
// OTyper
// OSpeedr
// PUPDr
while(1)
{
// Warten
// LED ausschalten (BRR)
// Warten
Um auf all diese Register zugreifen zu können, müssen wir eine Header-Datei für den Mikrocontroller einfügen. Das tun wir jetzt. Wir verwenden die Include-Anweisung.
Diese Header-Datei enthält alle Definitionen, Spezifikationen und Typen und so weiter.
Nun beginnen wir mit den Registern, die wir angeben müssen. Wir beginnen mit dem RCC-Typ. Dies ist tatsächlich nur ein Typ in C++, der eine Struktur oder ein Struct ist. Ein Struct ist einfach ein Typ, den Sie selbst definieren. Sie erstellen Ihren eigenen Typ, der Eigenschaften und Mitglieder innerhalb dieses Typs hat, die ihren eigenen Typ haben können. Wir werden auf diese Mitglieder mit dem Symbol "->" zugreifen, dem sogenannten Member-Zugriff. Der Member-Zugriff zeigt Ihnen alle Mitglieder in dieser Struktur an.
Wir suchen das AHBENR-Register, wir wählen es aus und verwenden dann unseren "oder"-Operator, da wir keine anderen Bits in diesem Register überschreiben wollen.
Wenn wir darüberfahren, sehen wir, dass es ein 32-Bit-Register ist und weitere Informationen enthält.
Wenn Sie mit der rechten Maustaste klicken und „open declaration“ wählen, können Sie tatsächlich das Element innerhalb der RCC-Typdefinition sehen. Sie können auch sehen, dass wir uns in der f030-Headerdatei befinden, auf die diese Headerdatei wahrscheinlich verweist.
Suchen wir nun das spezifische Bit, das wir in diesem spezifischen Element anpassen müssen. Wir verwenden RCC und finden den Port, den wir im GPIO benötigen, nämlich GPIOC. Wir werden nun die 1 in der 32-Bit-Binärzahl angeben, die 8 in Hexadezimal ist.
An diesem Punkt sieht das Programm so aus:
RCC ->AHBENR |= RCC_AHBENR_GPIOCEN;
Wir können auch die Bitweise-Operation des Shifts verwenden, wie wir es in der AVR-Serie getan haben, um die Portnummer anzugeben. Um beispielsweise eine 1 an die 19. Bitposition zu setzen, wäre die Lösung (1 << 19) unter Verwendung des Bitweise-Shift-Operators (<<). Die vorherige Anweisung ohne Verwendung von Membern wäre also:
Es gibt verschiedene Wege, Dinge zu tun, aber haben Sie keine Angst vor dem Code, wenn die Sprache Ihnen fremd erscheint. Hier geschieht wirklich keine Magie. Sie beeinflussen lediglich ein Bit, das sich im AHBENR-Register befindet.
Werfen wir einen Blick auf das GPIOCEN-Register im Referenzhandbuch. Das Referenzhandbuch finden Sie hier: STM32F030 Referenzhandbuch. Wir können direkt dorthin gelangen, indem wir im Inhaltsverzeichnis zur RCC-Steuerung gehen. Wir gehen direkt zum eigentlichen Register, wo Sie die 32 Bits und das, was unter jedem Bit gesteuert wird, finden. Sie werden sehen, dass der IOPCEN auf 19 liegt, was wir verwenden. Sie können sehen, dass das C hier auf 19, das B auf 18, das A auf 17 und das F auf 22 liegt.
Je nach Prozessor, den Sie haben, können Sie viel mehr Funktionen aktivieren. Sie werden auch feststellen, dass Sie unter dem AHB andere Funktionen aktivieren können. Erinnern Sie sich an das 19. Bit? Da ist es im Handbuch, das ist also eine gute Bestätigung, dass die entsprechende Nummer im Code mit dem im Referenzhandbuch angegebenen Bit übereinstimmt.
Gehen wir zum Modusregister und werfen einen Blick ins Referenzhandbuch für den Moder. Suchen Sie unter den GPIO-Registern, und das Modusregister ist das erste.
Sie werden hier feststellen, dass Ihnen angegeben wird, was in den Zweibit-Teil der 32-Bit-Zahl eingefügt werden muss, um den benötigten Modus zu aktivieren. Sie werden den Eingabemodus, den Allzweckausgabemodus, den Alternativmodus und den Analogmodus sehen. Wir haben über den Allzweckausgabemodus gesprochen, und das ist 01. Wir werden diese 01 für den Pin einfügen, den wir verwenden müssen. Dies sind die Pinnummern, und Sie werden feststellen, dass, da es für jeden Pin 2 Bits gibt, es nur 16 Pins gibt, so dass es bei Pin 0 beginnt und bei Pin 15 endet. Wir suchen nach Pin 6 und müssen die 0 und 1 in diesen Pin einfügen.
Um auf den GPIO Port C zuzugreifen, geben wir GPIOC und dann das Symbol "->" für den Member-Zugriff ein, um die Member anzuzeigen. Wir wählen Moder und verwenden den "oder"-Operator (|=), damit wir keine anderen Bits in diesem Register stören, da wir uns nur um Pin 6 kümmern. Als Nächstes geben wir GPIO_Mode ein und wählen 6_0.
GPIOC ->MODER |= GPIO_MODER_MODER6_0;
Wir können die Hexadezimalzahl überprüfen, um sicherzustellen, dass die 1 an der 12. Position steht. Dies überprüfen wir im Datenblatt.
Nun betrachten wir das Typ-Register im Referenzhandbuch. Wir sehen, dass es 16 Pins gibt und nur ein Bit für jeden Pin. Da wir keinen Open-Drain, sondern Push-Pull verwenden, können wir einfach sicherstellen, dass es auf Null gesetzt ist.
Geben Sie GPIOC ein und greifen Sie auf OTYPER zu. Wir verwenden den bitweisen Operator „&= ~“ mit Klammern. Da wir den Not-Operator verwenden, werden wir keine anderen Bits im Register beeinflussen. Wir verwenden den „Not“-Operator, um sicherzustellen, dass die Null in Pin 6 bleibt.
GPIOC ->OTYPER &= ~(GPIO_OTYPER_OT_6);
Als Nächstes werden wir die Geschwindigkeit betrachten. Wir werden das Datenblatt noch einmal untersuchen. In diesem Fall haben wir niedrig, mittel und hoch. Wir werden Hochgeschwindigkeit verwenden, was 11 ist.
Wir stellen sicher, dass die 3 in der Zahl enthalten ist, da dies 11 im Binärsystem ist.
GPIO ->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR6;
Als Nächstes verwenden wir das Pull-up-Pull-down-Register.
Wir wollen hier die 00 für keinen Pull-up, Pull-down. Um beide auf 0 zu setzen, müssen wir ein "and not" ("& = ~") durchführen, wieder wählen wir den richtigen Pin am GPIO. Wir sehen hier 3, und wir wissen, dass es jetzt Nullen einfügt, weil wir den "and not"-Operator in Kraft haben. Wir stoppen hier für den Moment. Im nächsten Video werden wir uns die Erstellung der Verzögerungsfunktion und das Senden des Signals an und aus ansehen.
GPIOC ->PUPDR &= ~(GPIO_PUPDR_PUPDR6);
Wir haben nun Folgendes aus den vorgenommenen Änderungen:
// Funktion erstellen, um eine bestimmte Zeit zu warten
int main(void)
{
RCC ->AHBENR |= RCC_AHBENR_GPIOCEN;
// Alle Steuerregister für PortC Pin 6 einstellen
// Moder
GPIOC ->MODER |= GPIO_MODER_MODER6_0;
// OTyper
GPIOC ->OTYPER &= ~(GPIO_OTYPER_OT_6);
//OSpeedr
GPIO ->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR6;
// PUPDr
GPIOC ->PUPDR &= ~(GPIO_PUPDR_PUPDR6);
while(1)
{
// Warten
// LED ausschalten (BRR)
// Warten
[[TUTORIALMENU(tutorial-arm" frameborder="0" allowfullscreen>