Als Mikrocontroller/Embeddes System wurde uns von Herrn Walter
das Entwicklungsboard STM32F746G-DISCOVERY zu Verfügung gestellt.
Vorteil an diesem Board ist die Mensch-Maschine-Schnittstelle,
welche als direkt montiertes Touchdisplay ausgeführt ist.
|
Abb.: STM32F746G-DISCOVERY
|
Das Board besitzt einen ARM Cortex M7 Kern und bietet sich für
verschiedenste Anwendungsszenarien an. Die Hauptmerkmale lassen sich
auf der
Herstellerwebsite einsehen. Für unser Projekt war der
Quadratur-Eingang des Boards ein wichtiges Merkmal. Das
Weglängenmesssystem von Balluff überträgt die Messgröße als
differentielles Spannungssignal (Signal A und Signal B). Die beiden
Signale sind elektrisch um 90° Grad phasenversetzt. Das Vorzeichen
der Phasenverschiebung hängt von der Bewegungsrichtung des Sensors
ab. Der Flankenabstand A/B entspricht der mechanischen Auflösung des
Sensorkopfes (z. B. 1 µm).
|
Abb.: Signalverlauf Balluff Messsystem
|
Im sogenannten Encoder-Mode des Boards wird ein Hardware Timer
benutzt, um die Flankenwechsel zu zählen. Je nach Richtung
(Phasenverschiebung) zählt der Timer hoch oder runter. Die Richtung
wird über das Setzen eines DIR-Bits gekennzeichnet. Das Board kennt
somit zu jedem Zeitpunkt die genaue Position des Sensors ohne diesen
periodisch abfragen zu müssen (Echtzeitfähigkeit).
|
Abb.: Bespiel aus dem STM32F7 Datenblatt
|
Weitere Informationen zum Weglängenmesssystem und Encoder-Mode
sind in der
Anleitung von Balluff und im
STM32 cross-series timer overview zu finden.
Für die vorhandene Hardware STM32F7gibt es eine
open Source IDE namens System Workbench for STM32. Diese basiert auf
dem Programm Eclipse und ist auf der Website
openstm32 nach einer kostenlosen Registrierung erhältlich. Auf
dieser Website sind auch Erklärungen zur Installation und ersten
Einrichtung zu finden.
Um die Hardware des Entwicklungsboards zu konfigurieren, stellt
STMicroelectronics das Programm CubeMX zur Verfügung, welches auf
der
Herstellerwebsite nach einer kostenlosen Registrierung
heruntergeladen werden kann.
Auf einer anderen
Website des Herstellers finden sich auch allgemeine
Informationen, Anleitungen, Handbücher und Treiber. Das Firmware
Package STM32CubeF7 ist unter dieser
Website erhältlich. In diesem Paket befinden sich unter anderem
HAL, Low-Layer APIs, Beispielprogramme und Software, um eine GUI zu
erstellen (STemWin).
Eine weitere hilfreiche Website nennt sich
microElk. Hier gibt es Anleitungen zur Hardware-Einrichtung und
weitere Hinweise zur Erstellung von Projekten mit dem STM32F7.
Wir beschäftigten uns zunächst mit der grundlegenden
Einrichtung des STM32F7. Hierbei verwendeten wir eine, aus einem
anderem
Projekt vorhandene, graphische Oberfläche und programmierten
diese um. Damit war es uns möglich nach Toucheingabe eine Status-LED
auf dem Board leuchten zu lassen. Nach weiterer Recherche fanden wir
ein anderes
Projekt,
indem eine Schrittmotorsteuerung mit dem
STM32F7 realisiert wurde. Anhand dieses Projektes konnten wir eine
graphische Oberfläche, samt Ansteuerung der Endstufe, realisieren. Die
Erklärung zur Bedienung ist auf der Seite
Bedienungsanleitung zu finden.
|
Abb.: Graphische Benutzeroberfläche
|
Nachfolgend sollen die entscheidenen Stellen des Sourcecodes
gezeigt werden.
Im folgenden Ausschnitt
wird das Abfragen der Endschalter in der Datei main.c
gezeigt. Die Abfrage findet in der Main Loop statt, welche
eine while-Schleife ist. Die Endschalter sind als Öffner
ausgelegt, um Drahtbruchsicherheit zu gewährleisten. Daraus
folgt: Wenn der Schalter betätigt ist, liegt ein LOW-Pegel am
Eingang der Mikrocontrollers an, wenn er nicht betätigt wird,
liegt ein HIGH-Pegel am Eingang des Mikrocontrollers an. Das
ist der Grund, warum die Variablen EndStopLeft und
EndStopRight negiert abgefragt werden. Sobald einer der
beiden Endschalter erreicht ist, wird ein Flag gesetzt damit
dies im ganzen Programm bekannt ist. |
|
main.c . . .
//
Main Loop while(1) { . . .
// Abfragen der Endschalter //
Endschalter links EndStopLeft =
HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_2);
// Endschalter rechts
EndStopRight = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15);
// Wenn Endschalter links
erreicht, Endschalter sind Oeffner -> Drahtbruchsicherheit
if (!EndStopLeft) { //
Flag Endschalter links erreicht setzen
StopLeftReached = 1; // Flag
Endschalter rechts zurücksetzen StopRightReached =
0; } else { // Wenn
Endschalter rechts erreicht, Endschalter sind Oeffner ->
Drahtbruchsicherheit if (!EndStopRight) {
// Flag Endschalter links
zurücksetzen StopLeftReached = 0;
// Flag Endschalter rechts
erreicht setzen StopRightReached = 1; }
. . . } |
|
In diesem Ausschnitt
wird die Auswahl des manuellen Verfahrmodus in der Datei
main.c gezeigt. Die Abfrage findet in der Main Loop
statt, welche eine while-Schleife ist. Sobald einer der
Taster Move Left oder Move Right gedrückt wird, der
Automatik-Modus nicht aktiv ist und die jeweiligen
Endschalter nicht betätigt sind, wird ein Flag für den
manuellen Modus gesetzt, das jeweilige Richtungsflag gesetzt
und der andere Endschalter deaktiviert. |
|
main.c . . .
//
Main Loop while(1) { . . .
// manueller Modus
//linke Richtung
// Wenn Taste Move Left gedrückt,
Automatik-Modus aus und Endschalter links nicht erreicht
if (BuMoveLeft && !AutoModeActive && !StopLeftReached) {
// Flag manueller Modus setzen
ManModeActive = 1; //
Motorrichtung links setzen StepperDirection = 0;
// Flag Endschalter rechts
erreicht zuruecksetzen StopRightReached = 0; }
else { //rechte Richtung
// Wenn Taste Move Left gedrückt, Automatik-Modus aus und
Endschalter rechts nicht erreicht if (BuMoveRight
&& !AutoModeActive && !StopRightReached) {
// Flag manueller Modus setzen
ManModeActive = 1; //
Motorrichtung rechts setzen StepperDirection = 1;
// Flag Endschalter links
erreicht zuruecksetzen StopLeftReached = 0;
} else {
// Flag manueller Modus
zuruecksetzen ManModeActive = 0; } }
. . . } |
|
In diesem Ausschnitt
sehen wir die Interrupt Routine, in welcher die Funktion für
die Ansteuerung der Schrittmotor-Endstufe aufgerufen wird.
Der Interrupt wird jede Millisekunde ausgeführt. Wenn das
Flag für den manuellen Modus gesetzt ist (ManModeActive), wird
die Funktion MoveStepperContinous aufgerufen. In diesem
Aufruf werden die Richtung und die Position des Sliders
(Geschwindigkeit) übergeben. Wenn das Flag für den
Automatik-Modus gesetzt ist (AutoModeActive), wird die
Funktion AutoMode aufgerufen. |
|
main.c . . .
void HAL_SYSTICK_Callback(void)
{ // Interrupt jede
Millisekunde
. . .
// Wenn manueller Modus aktiv
if (ManModeActive) { //
Aufrufen der Funktion für die Ansteuerung
MoveStepperContinuous(StepperDirection, SliderPosition);
} // Wenn Automatik-Modus
aktiv if (AutoModeActive) {
// Aufrufen der Funktion für
Automatik-Modus AutoMode(); }
. .
.
} |
|
In der Datei
stepper.c befindet sich die Funktion
MoveStepperContinous. Diese setzt je nach Richtung den Pegel
von D2 auf HIGH oder LOW. D2 ist mit dem Richtungseingang
der Endstufe verbunden. Über den Pin D1 wird ein
Rechtecksignal durch das Wechseln von HIGH und LOW Pegeln an
die Endstufe gegeben. |
|
stepper.c . . .
void
MoveStepperContinuous(int Direction, int Speed) {
. . .
// wenn
Direction-Flag mit Bewegung nach links gesetzt ist
if (Direction == 0) { //
Setzen von D2 auf LOW-Pegel, Richtungseingang an der
Endstufe, LOW -> links HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6,
GPIO_PIN_RESET);
switch (StepNo) { case 1:
// Setzen von D1 auf HIGH-Pegel,
Pulseingang an der Endstufe
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
if (NextStep == 1) {
StepNo = 2; NextStep = 0; StepCounter--; } break; case 2:
// Setzen von D1 auf LOW-Pegel,
Pulseingang an der Endstufe
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6,GPIO_PIN_RESET);
if (NextStep == 1) {
StepNo = 1; NextStep = 0; StepCounter--; } break;
default:
// Zurücksetzen der Pins
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET);
StepNo = 1; break; } } else {
// wenn
Direction-Flag mit Bewegung nach rechts gesetzt ist
if (Direction == 1 && Period > 0) { //
Setzen von D2 auf HIGH-Pegel, Richtungseingang an der
Endstufe, HIGH -> rechts HAL_GPIO_WritePin(GPIOG,
GPIO_PIN_6,GPIO_PIN_SET);
switch (StepNo) { case 1:
// Setzen von D1 auf HIGH-Pegel,
Pulseingang an der Endstufe HAL_GPIO_WritePin(GPIOC,
GPIO_PIN_6,GPIO_PIN_SET);
if (NextStep == 1) {
StepNo = 2; NextStep = 0;
StepCounter++; }
break; case 2:
// Setzen von D1 auf LOW-Pegel,
Pulseingang an der Endstufe
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6,GPIO_PIN_RESET);
if (NextStep == 1) { StepNo = 1; NextStep = 0;
StepCounter--; } break; break;
default:
// Zurücksetzen der Pins HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET);
StepNo = 1;
break; } } } } |
|
Struktogramm
|
|
Abb.:
Struktogramm |
|
|
Download Struktogramm (.xlsx) |
Download Struktogramm (.pdf) |
|