Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
microcontrollertechnik:tipps_fuers_programmieren [2019/08/19 13:09]
tfischer [Programmier-Fehler]
microcontrollertechnik:tipps_fuers_programmieren [2022/04/05 01:35] (aktuell)
tfischer ↷ Links angepasst weil Seiten im Wiki verschoben wurden
Zeile 1: Zeile 1:
-====== Allgemeines ====== +====== Tipps fürs Programmieren ====== 
-  * Eine schöne Einführung in die Embedded Softwareentwicklung ist im Buch [[https://link.springer.com/content/pdf/10.1007%2F978-3-658-18386-8.pdf|Sensornetzwerke in Theorie und Praxis Embedded Systems-Projekte erfolgreich realisieren]] von Kollegen Meroth und Sora zu finden. Dort wird der Einstieg in das Feld die (in Hardwareeingebettete Softwareentwicklung erklärtAus dem Hochschulnetz bzwmit VPN können Sie dieses direkt bei Springer Link betrachten. Eine andere schöne Einführung findet sich auf [[https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial|Mikrocontroller.net]]. + 
-  Zum Programmieren muss die Hardware noch nicht vollständig seinWenn Sie einen Mikrocontroller der ATmega Familie nutzen wollenso können Sie z.Bmit dem MiniMEXLE bereits Software entwickeln und testen.+  * Sofern es sich um eine Aufgabe mit Hardware-Software-Co-Design hantdelt, kann mit der Erstellung der Software bzw. der Softwaresystem-Entwicklung bereits parallel zur Schaltplan-Erstellung bzwdirekt danach begonnen werden. 
 +  * Machen Sie sich dazu zunächst Gedanken, 
 +      * **was**  die Software tun muss (übergeordnete Tätigkeiten), 
 +      * und in **welcher Abfolge**  sie das tun soll 
 +  * Dann können Sie sich überlegen, 
 +      * wie diese einzelnen Tätigkeiten **C-Funktionen**  zugeordnet werden können, 
 +      * wie die C-Funktionen von einander abhängen, 
 +      * welche Schnittstellen die C-Funktionen untereinander benötigen, (Datentyp, Wertebereich, Name) 
 +  * **Erst dann sollten Sie überlegen wie der Code aussieht**. Hier hilft ein Blick in die Datenblätter und Application Notes der µController und Chips. Dort sind nicht selten Algorithmen oder Codeschnipsel vorgegeben. 
 + 
 +===== Software System Design ===== 
 +Falls Sie noch nicht wissen, wie die Software oder die zu verwende Hardware genau genutzt wird, sollten folgende Tipps helfen:  
 +    * Suchen Sie die Komponente nicht (nurauf deutschDie Ergebnisse vermehren sich um ein Vielfaches, wenn in Englisch gesucht wirdZur Übersetzung empfiehlt sich [[https://www.linguee.de/|Linguee]]. 
 +    Nutzen Sie auch die Bildersuche, wenn Sie den genauen Begriff nicht kennen. 
 +    * Bei unklaren Begriffenbieten sich auch folgende Suchworte an: // ''Arduino'' + <englische Übersetzung von dem "Ding" was gesucht wird> + ggf''Project''//Alternativ bietet sich statt Arduino auch ''AVR'' oder ''Atmel'' an. Für C-Code kann ein ''"c code"'' zusätzlich gesucht werden. Code liegt häufig auf Github, entsprechend kann sich in Google ein Hinzufügen von ''site:github.com'' empfehlen. 
 + 
 +===== Vorgaben für Bewertung ===== 
 + 
 +Die [[vorgaben_fuer_die_softwareentwicklung|Vorgaben für die Programmierung]] enthalten Hinweise, wie der abgegebene Code aussehen soll. 
 + 
 +===== Häufige Fehler und Debugging ===== 
 + 
 +  * Tipps zum Debugging und zu häufigen Fehlern finden sich bei den [[elektronik_labor:tipps_fuer_die_fehlersuche|Tipps für die Fehlersuche (Elektronik-Labor)]].
   * Versuchen Sie möglichst nach jeder kleinen Änderung Ihr Programm zu testen. Wenn Sie drei Punkte ändern und dann erst testen, dann wissen Sie nicht, an welcher Änderung es liegt!      * Versuchen Sie möglichst nach jeder kleinen Änderung Ihr Programm zu testen. Wenn Sie drei Punkte ändern und dann erst testen, dann wissen Sie nicht, an welcher Änderung es liegt!   
-  *{{ ::presentation-twenty-five_most-common_mistakes.pdf |Die 25 häufigsten Fehler beim Programmieren }} oder als {{ ::10.1.1.113.6245.pdf |Paper}} und weitere {{ ::koopman11_escsv_handouts.pdf |41 häufige Fehler}}+  *{{ microcontrollertechnik:presentation-twenty-five_most-common_mistakes.pdf |Die 25 häufigsten Fehler beim Programmieren }} oder als {{ microcontrollertechnik:10.1.1.113.6245.pdf |Paper}} und weitere {{ microcontrollertechnik:koopman11_escsv_handouts.pdf |41 häufige Fehler}} 
 + 
 +===== Allgemeines ===== 
 +  * Eine schöne Einführung in die Embedded Softwareentwicklung ist im Buch [[https://link.springer.com/content/pdf/10.1007%2F978-3-658-18386-8.pdf|Sensornetzwerke in Theorie und Praxis - Embedded Systems-Projekte erfolgreich realisieren]] von Kollegen Meroth und Sora zu finden. Dort wird der Einstieg in das Feld die (in Hardware) eingebettete Softwareentwicklung erklärt. Aus dem Hochschulnetz bzw. mit VPN können Sie dieses direkt bei Springer Link betrachten. Eine andere schöne Einführung findet sich auf [[https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial|Mikrocontroller.net]]. 
 +  * Zum Programmieren muss die Hardware noch nicht vollständig sein. Wenn Sie einen Mikrocontroller der ATmega Familie nutzen wollen, so können Sie z.B. mit dem MiniMEXLE, MEXLE2020 oder Simulide bereits Software entwickeln und testen.
   * Tipps für die {{ :doc8453.pdf |Programmierung von ATMEL Chips}}   * Tipps für die {{ :doc8453.pdf |Programmierung von ATMEL Chips}}
   * Falls Sie lange Tabellen benötigen, sollten Sie die Daten im Programmspeicher (EEPROM) und nicht im Datenspeicher (SRAM) ablegen. In der Regel ist der Programmspeicher um den Faktor 5..10 größer   * Falls Sie lange Tabellen benötigen, sollten Sie die Daten im Programmspeicher (EEPROM) und nicht im Datenspeicher (SRAM) ablegen. In der Regel ist der Programmspeicher um den Faktor 5..10 größer
Zeile 11: Zeile 37:
   * Die Variablentypen sind bei Rechnungen zu beachten, sonst wird aus c=a/b mit int a=5 und int b=2 eine 2. Hier hilft ein expliziter Typecast: c=(float)a/b   * Die Variablentypen sind bei Rechnungen zu beachten, sonst wird aus c=a/b mit int a=5 und int b=2 eine 2. Hier hilft ein expliziter Typecast: c=(float)a/b
  
- +===== serielle Schnittstellen =====
-====== serielle Schnittstellen ======+
   * Die Programmierung eines AVR-Chips über USB (sofern dies der Chip ermöglicht), geschieht über das Tool [[https://www.microchip.com/developmenttools/ProductDetails/FLIP|FLIP]]   * Die Programmierung eines AVR-Chips über USB (sofern dies der Chip ermöglicht), geschieht über das Tool [[https://www.microchip.com/developmenttools/ProductDetails/FLIP|FLIP]]
   * Falls Sie einen externen Baustein über einen Mikrocontroller ansteuern wollen, ist folgendes zu beachten: Überprüfen Sie, ob der externe Baustein auf die positive Flanke triggert oder auf die negative. In der Regel lässt sich dies beim externen Baustein nicht ändern. Dies kann auf der Seite des Mikrocontrollers per Software geändert werden.    * Falls Sie einen externen Baustein über einen Mikrocontroller ansteuern wollen, ist folgendes zu beachten: Überprüfen Sie, ob der externe Baustein auf die positive Flanke triggert oder auf die negative. In der Regel lässt sich dies beim externen Baustein nicht ändern. Dies kann auf der Seite des Mikrocontrollers per Software geändert werden. 
   * Falls eine weitere I2C Schnittstelle benötigt wird, so finden sich [[https://en.wikipedia.org/wiki/I%C2%B2C|Vorlagen dazu im Netz]].   * Falls eine weitere I2C Schnittstelle benötigt wird, so finden sich [[https://en.wikipedia.org/wiki/I%C2%B2C|Vorlagen dazu im Netz]].
  
-====== Programmierung des ST7565 im Display ERC 128 64 - 1 ====== +===== Programmierung des ST7565 im Display ERC 128 64 - 1 ===== 
-  * Das Display {{ ::erc12864-1.pdf |ERC 128 64 - 1}} mit 128 Pixel in x-Richtung und 64 in y-Richtung ist in 8x8 Teile unterteilt. Die 8x8 Pixel werden auch Page genannt. In Sotware sind 132x65 Pixel ansprechbar - die Ausgabe ist aber nur auf 128x64 Pixel. +  * Das Display {{ laborausstattung:erc12864-1.pdf |ERC 128 64 - 1}} mit 128 Pixel in x-Richtung und 64 in y-Richtung ist in 8x8 Teile unterteilt. Die 8x8 Pixel werden auch Page genannt. In Sotware sind 132x65 Pixel ansprechbar - die Ausgabe ist aber nur auf 128x64 Pixel. 
-  * Je 8bit vertikal sind im {{ ::st7565.pdf |ST7565}} in einem Byte gespeichert.+  * Je 8bit vertikal sind im {{ grundlagen_der_digitaltechnik:st7565.pdf |ST7565}} in einem Byte gespeichert.
   * Die Kommandos, welche über SPI genutzt werden können, sind im Datasheet beschrieben.    * Die Kommandos, welche über SPI genutzt werden können, sind im Datasheet beschrieben. 
   * Über SPI kann nur auf das Display geschrieben werden. Ein Lesen ist nicht möglich.    * Über SPI kann nur auf das Display geschrieben werden. Ein Lesen ist nicht möglich. 
Zeile 25: Zeile 50:
   * Beachten Sie die Einbaurichtung bei der Ansteuerung des Displays.   * Beachten Sie die Einbaurichtung bei der Ansteuerung des Displays.
  
-====== Verwenden von Ports ======+===== Verwenden von Ports =====
   * Folgendes ist zu beachten, falls Sie JTAG-Ports - z.B. PF4..7 bei ATMEGA16U4 - anderweitig verwenden wollen/müssen (JTAG Ports = Ports an denen die ProgrammierHW angeschlossen wird): Die JTAG-Ports können nicht ohne weiteres direkt genutzt werden. Die JTAG Schnittstelle muss zunächst über folgenden Code deaktiviert werden. \\ <code>   * Folgendes ist zu beachten, falls Sie JTAG-Ports - z.B. PF4..7 bei ATMEGA16U4 - anderweitig verwenden wollen/müssen (JTAG Ports = Ports an denen die ProgrammierHW angeschlossen wird): Die JTAG-Ports können nicht ohne weiteres direkt genutzt werden. Die JTAG Schnittstelle muss zunächst über folgenden Code deaktiviert werden. \\ <code>
 MCUCR |=(1<<JTD); MCUCR |=(1<<JTD);
 MCUCR |=(1<<JTD); MCUCR |=(1<<JTD);
 </code>  Wichtig: Es das Control Register muss __zweimal__ geschrieben werden. </code>  Wichtig: Es das Control Register muss __zweimal__ geschrieben werden.
-  * Für eine zeitkritische Ausgabe von aufeinanderfolgenden Bits (z.B. für die Ansteuerung von [[Hardware_fuer_schaltungserstellung|intelligenten LEDs]]) müssen unbedingt Interrupts genutzt werden. Es lohnt sich zusätzlich auf __USART__ zurückzugreifen. Bei USART werden die zu versendenden Daten zunächst ins UDRn Register gegeben und dann in das Shiftregister übertragen. +  * Für eine zeitkritische Ausgabe von aufeinanderfolgenden Bits (z.B. für die Ansteuerung von [[elektronik_labor:hardware_fuer_schaltungserstellung|intelligenten LEDs]]) müssen unbedingt Interrupts genutzt werden. Es lohnt sich zusätzlich auf __USART__ zurückzugreifen. Bei USART werden die zu versendenden Daten zunächst ins UDRn Register gegeben und dann in das Shiftregister übertragen. 
   * Falls Sie einen externen Oszillator oder Quarz benutzen, werden zwei Ports dafür verwendet (Ports XTAL = "Crystal"). Wenn Sie diese Ports per DDR versehentlich zu einem Ausgang definieren, hat der Chip keinen Takt mehr. Das heißt diese Portzuweisung ist das letzte was der Chip macht... Es ist danach nur noch per Debuggerschnittstelle möglich diesen wieder zu beleben.   * Falls Sie einen externen Oszillator oder Quarz benutzen, werden zwei Ports dafür verwendet (Ports XTAL = "Crystal"). Wenn Sie diese Ports per DDR versehentlich zu einem Ausgang definieren, hat der Chip keinen Takt mehr. Das heißt diese Portzuweisung ist das letzte was der Chip macht... Es ist danach nur noch per Debuggerschnittstelle möglich diesen wieder zu beleben.
  
-====== Umgang mit Fehlern ====== +====== Simulide ====== 
-===== Programmier-Fehler ===== +===== Schrittmotortreiber =====
- +
-  * "Erasing device failed", "Error status received: Got 0xc9, expected 0x00 (An unknown command was sent)".  +
-    * Steht bei Device Programming das Interface auf ISP? Falls nicht kann dies die Ursache sein. Das Programming geschieht immer mittels ISP. +
-    * Hat das USB-Kabel/Progi/Adapterplatine/Kabel ein Problem? Probieren Sie eine andere Variante der Komponenten durch +
-  * ** Mein Chip hat keinen Speicherplatz mehr** bzw ** Ich erhalte ein 'Memory Overflow' Fehler** Falls Sie Daten statt im SRAM im EEPROM speichern wollen, so können Sie das Befehlswort "PROGMEM" nutzen. Details dazu finden Sie z.B. auf der Seite von [[https://www.microchip.com/webdoc/AVRLibcReferenceManual/pgmspace_1pgmspace_strings.html|Microchip]] +
-  * **F_CPU not defined for** (z.B. <util/delay.h>) Das beste ist die Frequenz F_CPU im AVR Studio direkt anzugeben: +
-    * Gehe zu Menu: Projekt > (ProjektName) Eigenschaften > Toolchain > AVR/GNU C Compiler > Symbols +
-    * Füge F_CPU=8000000 (bzw. Passende Frequenz) ein  +
- +
- +
- +
  
-====== Debugging ====== +Verschiedene Schrittmotortreiber bzwSteppermotor Driver (wie z.B. [[https://www.ti.com/lit/ds/symlink/drv8825.pdf|DRV8825]]) ermöglichen durch die Angabe der Richtung und ein Takten des STEP Pins das Antreiben eines SchrittmotorsSolche Treiber sind in Simulide nicht verfügbar
-  * Zum Auffinden von Fehlern gibt es verschiedene VorgehenFolgendes sehe ich als sinnvoll und zielführend an:  +Folgende Simulation ermöglicht aber zumindest die Nachbildung  
-    - Definieren des "Gut-Falls": Wie wäre zu erkennen, dass das Programm korrekt läuft?  +{{microcontrollertechnik:stepper.rar}}
-    - Definieren des Ausgangszustands: Gab es schon ein Teil des Programms, welcher korrekt lief? +
-    - Falls es schon einen Teil des Programms gab, so sollte dieser wieder hergestellt werden. Die Änderungen sollten dann Zeile für Zeile (bzw. Funktionsblock für Funktionsblock) eingefügt und auf der Hardware auf getestet werden. +
-    - Zur Ausgabe bietet es sich an z.B. ein unbenutzten PIN oder - falls schon vorhanden und in Software ansprechbar - ein Display zu nutzen +
-    - Die Ausgabemöglichkeit kann als genutzt werden, um den Programmablauf zu überprüfenz.B. kann die Ausgabe eines Buchstabens auf dem Display als Zeile eingefügt und so das Erreichen dieser Zeile überprüft werden++Beispiel|<code c>...   +
-void main() +
-{ +
-  initLCD(); +
-  initADC(); +
-   +
-  while(1) +
-  { +
-     doThis(); +
-     if (something) +
-     { +
-        LCDprint('s',1,1); +
-        doThat(); +
-     } +
-  }; +
-}</code>++ +
-    - Ähnliches geht auch beim Sprung in ein Unterprogramm. Wird dieses aber mehrmals in der Hauptschleife aufgerufen, kann es sich anbieten eine Hilfsvariable einzufügen. Damit ist es möglich nur den Sprung beim vermuteten Fehlverhalten zu betrachten++Beispiel|<code c>...   +
-void main() +
-+
-  int dummy=0; +
-  ... +
-  while(1) +
-  { +
-     doThis(); +
-     if (something) +
-     { +
-        dummy=1; +
-        doThis(); +
-        dummy=0; +
-     } +
-  }; +
-}+
  
-void doThis() 
-{ 
-   ... 
-   SomeCode; 
-   if(dummy==1) LCDprint('s',1,1); 
-   ... 
-} 
-</code>++ 
-    - Falls sich das Unterprogramm in einer weiteren Datei (z.B. eingebundene Library) befindet, so muss die Hilfsvariable übergeben werden. Temporär ist dafür die Definition/Deklaration einer externen Variable sinnvoll. Beispiel: Es wurde die Datei ADC.h inkludiert. Aus main() wird setADCgain() aufgerufen. In dieser Funktion wird ein Fehler erwartet. Sinnvoll ist es nun die Variable dummy in ADC.h zu deklarieren (extern int dummy;) und in main.c zu definieren (int dummy=0;). Dann kann die Variable in ADC.C auch ohne weiter Definition/Deklaration verwendet werden. Näheres dazu auch auf [[https://en.wikipedia.org/wiki/External_variable#Example_(C_programming_language)|Wikipedia]]. ++Beispiel|\\ **main.c** <code c>...   
-#include ADC.h 
  
-int dummy=0; 
-void main() 
-{ 
-  ... 
-  while(1) 
-  { 
-     setADCgain(); 
-     ... 
-     if (something) 
-     { 
-        dummy=1; 
-        setADCgain(); 
-        dummy=0; 
-     } 
-  }; 
-} 
  
-</code>**ADC.h**\\ <code c>...  
-extern int dummy; 
-</code>**ADC.c**\\ <code c>...  
-void setADCgain() 
-{ 
-   ... 
-   SomeCode; 
-   if(dummy==1) LCDprint('s',1,1); 
-   ... 
-} 
-</code>++