Fortsetzung des nächsten Artikels: STM32 für Anfänger. Schnittstellen

Vorheriger Beitrag: " Ein weiterer Artikel - STM32 für Anfänger "



Und wie benutzt du es?



Im vorherigen Artikel haben wir eine aktivierte Klasse für die Arbeit mit E / A-Ports erstellt. Und was dann? Warum das alles in den Unterricht stecken?



Nehmen wir zum Beispiel eine einfache Button-Umfrage:





Für dieses Schema sieht die Umfrage im einfachsten Fall folgendermaßen aus:



int GetKey()
{
  volatile uint32_t* addr = reinterpret_cast<uint32_t*>(GPIOA_IDR);
  uint32_t ret_val = *addr;
  return ret_val & 0x0F;
}


Wenn Sie jedoch die an die Tasten in der Schaltung angeschlossenen Ports ändern, müssen Sie die Abfragefunktion ändern. Und so in jedem Projekt. Dies ist nicht immer bequem. Ich möchte einmal schreiben, testen und verwenden.



Schreiben wir diese Funktion unter der zuvor erstellten Klasse neu:



int GetKey(Pin* p0, Pin* p1, Pin* p2, Pin* p3)
{
  int ret_val = p0->Get() + (p1->Get() << 1) + (p2->Get() << 2) + (p3->Get() << 3);
  return ret_val;
}


Es bleibt im Hauptprogramm, die Ports zu initialisieren und an die Funktion zu übergeben:



...
using namespace STM32F1xx;
Pin key0('a', 0);
Pin key1('a', 1);
Pin key2('a', 2);
Pin key3('a', 3);
...
int main()
{
  key0.ModeInput();
  key1.ModeInput();
  key2.ModeInput();
  key3.ModeInput();
  int key_code = GetKey(&key0, &key1, &key2, &key3);
...
  return 0;
}


Wo sind die Schnittstellen?



Und jetzt stellen wir uns vor, dass die Controller der f10x-Serie aufgebraucht sind, aber es gibt eine Reihe von f030s. In Bezug auf die Leistung und die Anzahl der Pins reicht es aus, Sie müssen nur den Header für die GetKey-Funktion ändern oder ... #ifdef verwenden. Erstellen Sie eine globale Header-Datei, in der der verwendete Controllertyp (z. B. #define STM32F030) angegeben ist, und häufen Sie eine Reihe von Definitionen an. Nein, dies ist nicht der Grund, warum Hochsprachen erstellt wurden, um in Makros verwirrt zu werden!



Lass uns den anderen Weg gehen. Erstellen wir eine Klasse, in der wir die virtuellen Methoden auflisten, die wir im Leben benötigen, um mit Ports zu arbeiten:



iPin.h
#pragma once

class iPin
{
public:
  virtual void ModeInput()              = 0;
  virtual void ModeAnalogInput()        = 0;
  virtual void ModeInputPulled()        = 0;
  virtual void ModeOutput()             = 0;
  virtual void ModeOutputOpenDrain()    = 0;

  virtual void Set(bool st) = 0;
  virtual bool Get() = 0;

  virtual void Reverse() { Set(!Get());}

  void On()              { Set(true);  }
  void Off()             { Set(false); }
};




(Die Methoden, die gleich 0 sind, müssen in der abgeleiteten Klasse definiert werden!)

und wir werden sie als Basismethode in der Pin-Klasse verwenden:



...
#include "iPin.h"
...
class Pin : public iPin
...


dann ändert sich die GetKey-Funktion geringfügig:



int GetKey(iPin* p0, iPin* p1, iPin* p2, iPin* p3)
{
  int ret_val = p0->Get() + (p1->Get() << 1) + (p2->Get() << 2) + (p3->Get() << 3);
  return ret_val;
}


Jetzt kümmern wir uns nicht mehr um einen Controller! Auch wenn es sich um einen Bus-Expander handelt, der über SPI oder I2C arbeitet. Wir werden serielle Schnittstellen in den nächsten Artikeln betrachten.



Und was dann?



Als Nächstes müssen Sie eine Klasse für die Arbeit mit einem Systemzeitgeber entwerfen. Dies ist aber bereits in der nächsten Veröffentlichung.



All Articles