Forum: Compiler & IDEs Wenn Ihr neue Projekte angeht, wie mach Ihr das ?


von Anfaenger (Gast)


Lesenswert?

Hallo Forum,

wie der Betreff schon sagt, habe ich erhebliche Probleme, Projekte
durchzuziehen.

Ich betreibe den µC Kram mit Atmel Controllern aller Art und Coleur
(Mega 8, 8515, 16, 32, 90S2313, 90s8515, ..) nur so als Hobby
nebenbei.

So viel zu meiner Vorgeschichte.

Programmieren wollte / werde ich in C mit dem Programmers Notepad und
auch den Atmel Studio Geschichten. Alles da, alles läuft, programmiert
habe ich auch schon erfolgreich. Aber nur Kleinkram, LED blinken, UART
Ausgabe, LCD Spielkram, ...

Irgendwie gelingt es mir aber nie, ein größeres, komplexeres Problem in
Hardware und Software umzusetzen.

Beispiel: USART --> Centronics Umsetzer für Telefonanlage.
          Hardware mit geätzter Platine und Gehäuse ist fertig

          (ATmega16 + 2 x 74LS244 und MAX232)
          Aber dann beim Programmieren wurde aus der, eigentlich
          kleinen Aufagbe ein heilloses durcheinander und jede Menge
          "Spaghetticode".

Die Liste der Projekte, die mit eigentlich 1a Hardware hier liegen,
aber vom Programmtechnischen her Chaos sind ist noch lang und ich habe
noch nirgendwo einen Ansatz gefunden, wie man denn sinnvoll vor dem
Coden vorgeht um ein Programm dann strukturiert umzusetzen.

Wie macht Ihr das denn, wenn Ihr für komplexere Hardware oder überhaupt
Programme schreibt ?

Macht Ihr PAP oder Flussdiagramme ?

Gibt es irgend eine Seite, die mir beim googlen durchgegangen ist, wie
man am besten bei der Programmerstellung vorgeht ?

Das Coden selbst ist dann kein so großes Problem, nur das strukturieren
des Problems, macht mir Schwierigkeiten.

Danke schon einmal für jeden Anstoß.

Anfaenger

P.S.: Ich sehe, das ich mich mal anmelden sollte. Anfaenger ist ein
gern genommener Nickname.

von Wolfgang Horn (Gast)


Lesenswert?

Hi, "Anfaenger",

begonnen habe ich mit dem Nachbau von Hardware + Firmware.
Erst mal ein Erfolgserlebnis haben. Sehen, daß alles läuft, auch
wenn's ein Könner programmiert hat.

Für das nächste Vorhaben habe ich diese Hardware und Firmware dann
einfach abgeändert. Und erweitert.

Warum das Rad neu erfinden?
Ich bekenne mich zu meiner Faulheit - bis auf dort, wo ich den Genß
suche.

Ciao
Wolfgang Horn

von Holger G. (holli1195)


Lesenswert?

Ich suche mir meistens die geeignete Hardware raus, gucke wie das alles
zu verbinden geht, und baue meistens erst mal ein loses Muster auf.
Zumindest mit den Grundkomponenten. Dann fange ich an kleine Bausteine
zu programmieren und zu testen. z.B. die Kommunikation meiner beiden
Atmels über UART. Dabei nutze ich so viel wie möglich Komponenten aus
dem Netz, diesem Forum hier oder aus meinen älteren Projekten und gucke
auch viel wie es andere gemacht haben. Dabei mache ich mir schon
Gedanken, wie die Schnittstellen zwischen diesen Bausteinen aussehen
sollen. (Beispiel: ich weiss, ich benötige in mehreren Modulen
Zeitabläufe -> gemeinsamen Nenner für den Timerwert suchen und EIN
Timermodul schreiben)Für komplexe Abläufe, wie Menüstrukturen mache ich
mir auch schon mal auf Papier ein Flussdiagramm. Jedes Modul wir
ausprobiert und so lange optimiert, bis ich zufrieden bin. So wird mein
Projekt dann immer komplexer, bis es einmal(hoffentlich) so
funktioniert, wie ich es mir vorgestellt habe.

Gruss Holger

von Anfaenger (Gast)


Lesenswert?

Sieht ja so aus, als ob Ihr alle da ein besseres Konzept habt, wie ich.

Naja, dann werde ich mal weiter machen, wie bisher aber in dem Wissen,
das es besser gehen müsste.

Es tröstet mich auch, das ich nicht der Einzige bin, der sich
"rundherum mit Codebeispielen" eindeckt um ein Problem zu lösen.

Gruß

Anfaenger

von MasterFX (Gast)


Lesenswert?

Was immer etwas hilfreich ist, ist es den Quellcode sinnvoll in mehrere
Dateien aufzuteilen. Dadurch ersparst du die bei etwas größeren Code
das ständige suchen. Auch Kommentare sollte man stehts machen (nicht
bei jeder Zuweisung oder so, aber da wo man später erstmal nachdenken
müsste was oder warum man das gemacht hat). Flussdiagramme sind auf
jeden Fall sinnvoll. Auch ich habe damals immer den Fehler gemacht
einfach blind drauf los zu programmieren. Bei kleinen Problemen kommt
man dann zwar schnell zum Ziel, aber bei größeren schießt man sich
damit früher oder später selbst ins Bein.
Man sollte bevor man richtig anfängt wissen was man alles braucht und
danach in einer sinnvollen reihenfolge programmieren. Sinnvoll heist,
dass du erst die grundlegenden Sachen machst, die man auch immer
zwischendurch testen kann. Auf diesen "Treibern" (nenn ich sie
einfach mal) kannst du dann den Rest nach und nach aufbauen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Man sollte sich auch nicht scheuen, mal was wegzuwerfen, egal
wie viel Arbeit man da reingesteckt hat.  Gerade wenn man im
Design eines Softwareprojekts noch nicht so viel Erfahrung hat,
kommt man halt schnell mal zu so 'nem Spaghetti-Punkt, an dem
alles ein endloses Knäuel wird.  Im Prinzip weiß man aber an
dieser Stelle, wie man es hätte richtig angehen müssen, da man
mittlerweile im Bilde ist, wie die Struktur aussehen muss.

Das ist m. E. der Punkt, an dem man die bisherige Arbeit einfach
in den Papierkorb legt (eine Versionsverwaltungs-Software kann
sie ja für spätere Referenz nochmal aufbewahren) und wirklich von
vorn anfängt.  Das ist auf Dauer weniger Arbeit, als am alten
Knoten immer weiter herumzuflickschustern.

Ich halte diese Vorgehensweise (mittels trial&error sich ein
Bild vom Problem verschaffen und danach dann die endgültige
Implementierung angehen) durchaus für eine sinnvolle Alternative
zu irgendwelchen PAPs oder sowas.

von Wolfram (Gast)


Lesenswert?

Du solltest probieren eine saubere Schichtung der Software zu
erreichen,
ganz unten Abstraktion der Hardware, als nächstes Zwischenlogik und
Verarbeitung, oben Schnittstelle nach aussen und Darstellung.
evt. noch mehr Zwischenschichten.
Auch wenn es kurzfristig unbequem erscheint solltest du keine
Abkürzungen über mehrere Schichten nehmen. Wesentlicher Vorteil, man
ist gezwungen Timingunabhängig in den oberen Schichten zu
programmieren.
Nichts ist schlimmer als, man macht eine Änderung im Programmcode und
durch ein verschobenes Timing funktioniert es nicht mehr.
Die andere Sache ist, dass man probiert eine zusammengehörige Sache
abzukapseln und nur durch ein Interface von aussen zu bedienen.
Dies geht auch auf einem Mikrocontroller ohne Objektorientierung.
Stell dir folgendes Bild vor:
Du stehst als Kapitän eines Schiffes am Ruder, da rennt man nicht
einfach von der Brücke in den Maschinenraum um dort den Dampfdruck zu
erhöhen, sondern man signalisiert zum Maschinenraum "ich will
schneller fahren", wie das der Maschinenraum löst muss er wissen.
Genauso wäre es wenn plötzlich in der hohen Ebene steht, setze auf
PortX folgendes Bit.
Wer sowas macht, produziert Code den er mit Sicherheit auf dem nächsten
Prozessor nicht mehr einsetzen kann. Oder bei Änderungen
bleibt dann plötzlich ein Bit gesetzt weil man vergessen hat das man in
Routine xy ja noch direkt zugreift.
Während im anderen Fall nur die Lowlevelroutinen zu ersetzen sind.
Versuche nicht Algorithmen während des Entwurfes zu Optimieren
Wer probiert auf Lowlevel Ebene jeden Takt zu Optimieren, kann sich auf
Highlevelebene einiges verstellen, was wesentlich mehr bringt, wie das
Weglassen eines unnötige Aufruf eines ganzen Programmzweiges statt der
Optimierung von 3 Befehlen.
Wenn man Probleme hat das ganze einzuschätzen, zu komplex, keine genaue
Erfahrung welche Probleme bei dem ganzen Auftreten sollte man es genauso
machen wie Jörg es schreibt, eine Vorentwurf implementieren, sehen wo es
nicht so richtig klappt und dann die richtige Lösung.

von Stefan (Gast)


Lesenswert?

@ Anfaenger

Wenn du die Gelegenheit hast in das Buch "Der Pragmatische
Programmierer" von Andrew Hunt und David Thomas reinzusehen, tue es.
Ich habe es in meiner Stadtbücherei gefunden.

http://www.pragmatischprogrammieren.de/pragprog/index.html
http://www.hanser.de/buch.asp?isbn=3-446-22309-6&area=Computer (mit
Leseproben)

von Peter D. (peda)


Lesenswert?

"Versuche nicht Algorithmen während des Entwurfes zu Optimieren"

Wenn der Algorithmus dadurch einfacher und besser lesbar wird, würde
ich es machen.

Z.B.:
- sind wiederholt gleiche Sachen zu machen -> in eine Schleife packen
- sind an mehreren Stellen gleiche Sachen zu machen -> in Unterfunktion
packen
- sind konstante Berechnungen in Schleifen -> aus Schleife
herausziehen

Insbesondere sind gleiche Programmteile gute Fehlerkandidaten, wenn
daran Änderungen zu machen sind, eine Stelle vergißt man immer zu
ändern. Aber gibt es kein Copy&Paste Konstrukte, kann man auch nichts
vergessen.

Programmplanung klinkt so hochtrabend, bei mir sind es nur
Bleistiftkritzeleien, aber sie helfen ne Menge.
Es sind auch keine kompletten Programabläufe, sondern nur die Teile,
die ich gerade progge.

Und man muß auch nicht immer nur von oben nach unten programmieren.
Wenn man mal nicht weiterkommt, kann es helfen, welche nützliche
Unterfunktion könnte diesem Problem zuarbeiten, also auch mal von unten
nach oben programmieren, sozusagen von beiden Seiten dem Problem
annähern.

Programmieren erinnert mich auch immer an Bill Murray (Babyschritte),
man kann Aufgaben nie zu weit unterteilen. Je kleiner die Schritte,
umso leichter kann man sie in Code umsetzen.


Peter

von Wolfram (Gast)


Lesenswert?

@Peter:
Alles was du an Optimierungsmassnahmen beschreibst erfordert, das dein
Algorithmus steht, denn erst dann erkennst du wirklich, was gleiche
Teile sind, die zusammenfassbar sind etc.
Wenn man dagegen schon während des Entwurfes des Algorithmus versucht
Optimierungen einzuführen, verstellt man sich den Blick für so etwas.
Wenn ich programmiere dann mache ich gewöhnlich erstmal die
Hardwareabstraktion und dann die oberste Schicht, dann kommt die
Zwischenschicht. Vorteil die obere Schicht kann ich, wenn es sein muss
auch schonmal auf dem PC testen. Sie ist ja hardwareunabhängig und auch
die darunterliegende Programmlogik kann man auf dem PC entwickeln. Das
geht teilweise schneller und man ist genötigt hardwareunabhängig zu
programmieren was automatisch eine saubere Struktur fördert.
letzten endes ist es doch egal, ob ich unter windows mit createfile
einen
stream öffne oder mit fdevopen, das gehört in die hardwareabhängige
Schicht. Tastenentprellen und weiterleiten eines gültigen Tastendruckes
oder ein gedrückter Button sind effektiv auch das gleiche. Die
wesentliche Entscheidung ist, einzuschätzen wo man Zeit sparen kann,
wenn man auf dem PC entwickelt und wo nicht, da man ja die
Hardwareabstraktion für den PC zusätzlich macht.
Zu "Babyschritte": Man sollte den grossen Programmablauf immer im
Auge haben, auch wenn er erstmal nur aus leeren Routinen besteht, die
man dann einzeln mit "Babyschritte" füllt.

von gucksdu (Gast)


Lesenswert?

Scheint hier wohl das alte Dillemma zu sein: "Top-down" oder
"boottom-up" an eine Sache dran zu gehen.

Ich selber komme sehr gut zurecht mit dem Top-Down Ansatz. Erst mal die
Rahmenhandlung abstecken, und versuchen einzelne Dinge zu strukturieren.
Wenn mir unterwegs dabei bestimmte Teilkomponenten einfallen (Botton-up)
dann ist das prima, es hilft das Gesamtbild runder zu machen.

Dineg bei denen ich noch nicht weiter verfeinern möchte kläre ich
zumindest soweit ab wie erforderlich, damit der gesamte Rahmen nicht
möglicherweise komplett umgestellt werden muss.

Ums mal plakativ zu beschreiben: Erst den Rahmen vom Puzzle
fertigmachen. Die restlichen Puzzlesteine werden sich schon an
passender Stelle hinfinden

von Anfaenger (Gast)


Lesenswert?

Also die Vorgehensweise, die Wolfram beschreibt, hört sich gut an.

Das Problem, das sich daraus für mich ergibt, ist das ich mich
zusätzlich noch mit dem Erstellen von Bibliotheken und Headerfiles
auseinandersetzen muss.

Wenn ich die Antworten so sehe, dann beschäftigt Ihr euch alle zuerst
mit dem Thema Software und geht dann zur Hardware über.

Ich mache es zur Zeit noch umgekehrt. Erst die Hardware mit allen
Einzelheiten (Layout, Platine, Spannungsversorgung, Pegelanpassung und
so) und dann, wenn die Platine steht, mache ich mir die Gedanken über
die Software.

Vorher habe ich natürlich meterweise Datenblätter "inhaliert" um auch
die richtigen PIN´s an den Bauteilen miteinander zu verbinden.

Nach den vielen eindringlichen Hinweisen zur Softwareentwicklung, werde
ich mich nun doch wohl erst einmal auf die Software stürzen.

Anfaenger

von Peter D. (peda)


Lesenswert?

Die Hardware sollte natürlich stehen, bevor man die Software in Angriff
nimmt.

Es kann aber auch sein, daß man erstmal einen Teil in Software
schreibt, um festzustellen, ob die Software das zeitmäßig schafft, oder
ob man lieber zusätzliche Hardware anbindet.


Ich versuche immer, soviel wie möglich in Software zu machen und die
Hardware minimal zu halten.


Peter

von Anfaenger (Gast)


Lesenswert?

Wie ich ja schon ganz am Anfang geschrieben habe, ist mein Hauptproblem
ja die Software.

Wenn ich die Hardware habe und weiß was ich mit dieser Hardware
erreichen will, dann enden meine Programme meistens mit:

#include <avr/io.h>
#include <avr/signal.h>
#include <LCD  UART  ...>

#ifndef F_CPU
#define F_CPU 3686400L //Oder einer anderen Quarzfrequenz, je nach dem,
was da für ein Mega tickt
#endif

void main (void)
{
   20 - 40 Zeilen Code bis zur Konfusion
}

und dann gehen mir die Ideen aus, oder ich suche mich halb tot nach
irgendwelchen Anstössen, wie ich denn weiterkommen könnte.

Dann male ich meistens ein Paar Flussdiagramme, vernichte den ersten
Anfang, fange neu an und bleibe wieder stecken.

Dann lese ich Bücher, stöbere im Forum, ... komme ein wenig weiter,
fange wieder von vorne an, ... letztendlich landet das Projekt dann in
der Kiste mit den unfertigen Sachen.

Vielleicht bin ich ja auch nur zu blöd zum Entwickeln von
Mikrocontrolleranwendungen und ich sollte mir ein anderes Hobby
suchen.

(So langsam kommt wieder der Frsut duch)

Anfaenger

von Besserwisser (Gast)


Lesenswert?

40 Zeilen bis zum Gedankencrash? Das ist schlecht, um nicht zu sagen..
Sehr schlecht.

Worin besteht die Konfusion?
Überleg dir, was das Progi machen soll, benenne Funktionen.
Beachte dieses Konzept:

----------------------------------------
| Obere Schicht: E/A zum User etc.     |
|--------------------------------------|
| Mittlere Schicht: Logik              |
|--------------------------------------|
| eventuell: Abstraktionsschicht       |
|--------------------------------------|
| Untere Schicht: Hardware             |
----------------------------------------

Eine hohe Schicht darf nur auf die tiefere zugreifen, nicht aber eine
tiefe auf eine höhere.

von Marc M. (bytewood) Benutzerseite


Lesenswert?

Nicht den Frust durckommen lassen!

Wenn ich ein Projekt beginne mache ich folgendes:
Erstmal ein Blatt Papier zücken!
Meine Überlegungen, was das Teil können soll stichpunktartig
aufschreiben - und wieder nachdenken und schreiben  => while (1){...}
Wenn mir nichts mehr einfällt, dann 'ne Nacht drüber schlafen - dann
ggf. ergänzen. Wenn nichts mehr unerwartetes passieren kann
(hoffentlich!), dann layouten, ätzen und bestücken.

Zum Proggen:
Wieder mit einem Blatt Papier zur Hand:
Das große Problem in viele kleine zerlegen und in Unterprogrammen
lösen. Ich schreibe mir auf, was die Unterprogramme machen sollen
(stichpunktartig). Dann die Unterprogs proggen.
Wenn das dann alles gelungen ist, dann das Hauptprogramm schreiben,
quasi alle "Module" in das Hauptprog einfliessen lassen.
Du kannst es Dir so vorstellen:
Zuerst alle Puzzelteile erzeugen, dann zu einem Gesamtbild
zusammenbauen, das dann schön ist, wenn's hängt (läuft).

Grüße

von Anfaenger (Gast)


Lesenswert?

Das, in meinem Ersten Post genannte Problem ist da wohl das Beste
Beispiel ...

Ich habe das Interface fertig hergestellt. Die 74LS244 sind mit den
Ports des ATmega16 verbunden. Die USART Schnittstelle des Mega16 ist an
den MAX 232 angeschlossen und auch die Pins für den RTS / DTR sind so
verlegt, das ich die im Notfall auf die INT0 / INT1 Pins legen kann
(Jumper sind vorgesehen).

Dann fing ich an, die Baudrate für den Mega16 festzulegen. Bei dem Teil
des Programms, das dann nach dem Eintreffen der USART Daten, diese auf
den 8-Bit Port (PortA, um das Problem mit den JTAG-Fuses zu vermeiden)
kopieren soll (RXC = 1 kopiere Inhalt des RecieveBuffer auf Port A)
fing das Problem schon an.

Ich muss ja den Handshake mit dem Centronics machen. Also
TimerInterrupt usw. wegen Strobe / ACK.

Da dann rumgekaspert und immer mehr in die Richtung SpaghettiCode
geraten.

1 Tag pausiert und Bücher  Posts  PDF zum Thema Timer /
Timerinterrupt gelesen.

Den Code wieder vorgeholt und trotz Kommentaren keinen Durchblick mehr
bekommen. Also neu angefangen und dann wieder stecken geblieben usw.

Ihr seht also, das da irgendwo bei mir die Step by Step Anleitung
fehlt. Ich weiß genau, was ich machen will und wie ich dahin kommen
könnte, nur bei der Durchführung geht dann alles grausam schief.

Wenn ich wie Wolfram oder Besserwisser programmieren könnte, also
strukturiert und nach Ebenen sortiert, ich würde platzen vor Stolz.

Aber so verbringe ich Stunden damit, Wissen durch Lesen zu erwerben und
bei der praktischen Umsetzung zu scheitern.

Anfaenger

von Wegstabenverbuchsler (Gast)


Lesenswert?

@Besserwisser

... wobei ich persönlich in der "Logik" Ebene anfange.

um beim vom Ursprungsposter genannten Beispiel zurück zu kommen:

"Beispiel: USART --> Centronics Umsetzer für Telefonanlage. "


Ob ein Status-Wert pqr auf bit 3 oder 5 reinkommt ist für die Logik
ziemlich egal.

Was aber schonmal durchdacht werden sollte ist so Zeugs wie:
Fluss-Steuerung, Ringpuffer, Schnittstellenbefehlsumfang,
Timing (INT oder Polling)
Speicherplatz für Daten
Wiederanlaufverhalten

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich glaube, du solltest dir schon mal ein Buch zur Methodik des
Programmierens reinziehen, oder vielleicht findest du auch was im
Internet dazu.  Inbesondere musst du (m. E.) lernen zu abstrahieren,
um dein Problem in Teilprobleme zu zerlegen.

Letzendlich läuft es auf die bereits genannten Strategien eines
Top-Down- oder Bottom-Up-Entwurfs hinaus.  Nur so als Beispiel, ein
möglicher Top-Down-Entwurf deines Problems:

. Analyse der groben Funktion:

+ Initialisierung
+ Schleife: alle von der USART kommenden Zeichen auf Centronics
ausgeben

. Verfeinern: Initialisierung:

+ Initialisierung USART: Baudrate, Framing
+ Initialisierung Centronics: Setzen der Bits, damit der Drucker den
Computer als bereit zum Senden anerkennt

. Verfeinern: USART Zeichen lesen:

+ Hat USART ein Zeichen?
+ Einlesen Zeichen, zurückgeben des Zeichens

. Verfeinern: Centronics schreiben:

+ Anlegen des Zeichens an Datenpins
+ Generieren des Signalspiels

Mit diesem Entwurf solltest du eine erste Implementierung wagen
können, die zumindest in der Lage ist, eine Zeile auf den Drucker
auszugeben.  Bei mehr als einer Zeile könntest du in Probleme rennen,
dass der Drucker noch nicht wieder in der Lage ist, Zeichen
entgegenzunehmen.  Das ist dann die Stelle, an der du den Entwurf
sukkzessive verfeinern kannst.  Du musst also eine "device ready"-
Überprüfung bei der Centronics-Ausgabe vornehmen.  Vorerst wirst du
wohl einfach mal so lange die Ausgabe blocken (das Zeichen also noch
zurückhalten), solange der Drucker "not ready" ist.  An dieser
Stelle
könntest du feststellen, dass es noch eine Statusleitung mehr gibt
(paper out), irgendwo eine Anmerkung machen (ein TODO oder XXX-
Kommentar oder auf Extra-Zettel bzw. -Datei).

Danach wirst du (u. U.) das nächste Problem bemerken: während die
Ausgabe blockiert, könnten von der USART Zeichen einlaufen, gegen die
du dich nicht wehren kannst.  Das heißt, die ursprünglich primitive
Eingabe von der USART müsstest du nun auf Interrupt-Betrieb mit Puffer
umbauen.  In den oberen Schichten ändert sich dabei nichts, da du für
das Lesen eines Zeichens von der USART eine Funktion (usart_get() oder
sowas) benutzt, die das aktuelle Zeichen zurückgibt.  In der ersten
Prototyp-Implementierung liest diese Funktion einfach aus dem
UDR-Register (nachdem sie die Statusbits der USART gepollt hat, bis
ein Zeichen verfügbar ist), in der nun folgenden Implementierung gibt
sie das aktuelle Zeichen aus dem USART-Puffer zurück (muss natürlich
auch warten, wenn keins da ist).

Vermutlich wird dies bereits die gewünschte Gesamt-Applikation sein.
Wenn du noch nachfeilen willst, kannst du dir Gedanken um RTS-CTS-
Handshake machen, falls der USART-Puffer mal volläuft (was wohl nur im
Falle von paper out oder abgeschalteten Drucker passieren dürfte),
allerdings hat das möglicherweise nur begrenzten Wert: erstens muss
die Tk-Anlage das Handshake verstehen, zweitens muss sie mehr als die
aktuelle Meldung puffern können, und drittens wird bei länger
anhaltender Fehlerbedingung auch deren Puffer irgendwann voll laufen,
irgendwann tritt also schon Datenverlust ein.  Weitere Gimmicks:
Anzeige des Betriebszustandes (OK, Druckerfehler, USART-Puffer voll)
über LEDs.  Vielleicht auch noch Umstellen der Centronics-Ausgabe auf
Interrupt-Betrieb, damit wird die Hauptschleifen dann ziemlich
entlastet und könnte nebenbei noch andere Aufgaben wahrnehmen oder
aber auch den Prozessor schlafen legen.

von AndreasB (Gast)


Lesenswert?

Ich würde zu Anfang mal nur mit Papier und Bleistift arbeiten.

- Definiere was das Projekt können muss.

- Teile es in funktionale Module auf (ein Modul das genau eine Funktion
(noch nicht Software) macht

- Finde raus welche Module du unterteilen musst, aber unterteile ein
modul nichtunötigerweise.

- Finde raus, welche Dinge noch zu klären sind, ob das überaupt geht
oder nicht.

- Mach dich dran die Module zu designen (hardware, schaltung, software
definieren, testen) und zu entwickeln.

Vor allem: Nimm dir nicht zuviel vor am Anfang.

Und: Kompromissloses Refacturing vom Code hilft ihn auch später noch zu
verstehen. Auch wenn es sinnlos scheint 2 Zeilen in ne eigene Funktion
zu packen - es hilft manchmal enorm. Scheu dich nciht vor großen
Änderungen (Sicherung ist latürnich Pflicht)

Gruß Andreas

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nachtrag: diese Abstraktionsschritte bilden sich normalerweise
einigermaßen auf separate Teilfunktionen ab.  Z. B. könnte der
Entwurf nach Phase 1 ungefähr so niedergeschrieben werden:
1
void
2
ioinit(void)
3
{
4
}
5
6
char
7
usart_getchar(void)
8
{
9
}
10
11
void
12
centronics_putchar(char c)
13
{
14
}
15
16
int
17
main(void)
18
{
19
  char c;
20
21
  ioinit();
22
23
  for (;;) {
24
    c = usart_getchar();
25
    centronics_putchar(c);
26
  }
27
28
  /* NOTREACHED */
29
  return 0;
30
}

In Phase 2 würde es dann weitergehen:
1
void
2
usart_init(void)
3
{
4
  /* UCSRXXX ... */
5
}
6
7
void
8
centronics_init(void)
9
{
10
  /* DDRXXX ... */
11
}
12
13
void
14
ioinit(void)
15
{
16
  usart_init();
17
  centronics_init();
18
}

Ich hoffe, du kannst dir ein Bild machen, wie ich das meine.

von Markus Volz (Gast)


Lesenswert?

@Anfaenger
Sei mir bitte nicht böse, aber ich habe den Eindruck, Deine Projekte
sind software-technisch gesehen, 2 bis 3 Nummern zu groß für Dich. Das
was Du da als Projekt vor hast, überfordert auch so manchen
Fortgeschrittenen.

Das Problem bei der Geschichte liegt nicht so sehr bei Dir sondern da
dran, daß der Unterschied zwischen einem Anfänger und einem Profi in
vielen Jahren Erfahrung liegt. Und die bekommt man leider nicht durch
das Lesen eines Buches oder im Internet sondern durch Ausprobieren,
Fehler, Ausprobieren, Fehler, Ausprobieren...

Außerdem gibt es nicht DAS Kochrezept, um Software zu entwickeln. Hier
bildet sich bei jedem im Lauf der Zeit eine eigene, höchst Individuelle
Vorgehensweise aus, die andere nicht notwendigerweise nachvollziehen
können.

Der wichtigste Aspekt bei der SW-Entwicklung ist das Ausbilden einer
abstrakten Sichtweise auf die zu lösenden Probleme. Anfänger, die dies
noch nicht leisten können, sehen i.d.R. vor lauter Bäumen den Wald
nicht mehr. Diesen Eindruck habe ich bei den von Dir geschilderten
Problemen.

Vielleicht legst Du Dein Projekt erst mal auf Eis und beschäftigst Dich
mit Software-Entwicklung am und für PCs, unabhängig von µCs? Dort kannst
Du mit erst mal kleinen, dann immer komplexeren Projekten Erfahrung
sammeln, was das Strukturieren von Software-Projekten anbelangt. Wenn
Du dann mehr Überblick hast, hole die Projekte wieder aus der Kiste und
mache weiter. Außerdem hat Software den Vorteil, daß die Projekte keine
"teuren" Elektronik-Komponenten benötigen, die dann in der Kiste
verstauben.

Ich wünsche Dir auf jeden Fall viel Erfolg
Markus

von Wolfram (Gast)


Lesenswert?

>Wenn ich wie Wolfram oder Besserwisser programmieren könnte, also
>strukturiert und nach Ebenen sortiert...
Das ist das Fazit aus den Jahren des Spagetti Codes...

>Aber so verbringe ich Stunden damit, Wissen durch Lesen zu erwerben
>und bei der praktischen Umsetzung zu scheitern
Programmieren ist in erster Linie der Entwurf eines Algorithmus, das
Ausformulieren in einer Programmiersprache ist dann eher nur noch
tippen. Ok da wird es jetzt wahrscheinlich ein bischen Protest geben.
Möglicherweise hängst du ganz einfach, weil du dich auf das
Ausformulieren versteifst, anstatt dir erstmal das was du eigentlich
sagen willst (den Algorithmus) klar zu machen. Ob du das durch
Flußdiagramme oder durch Bauklötzchen stapeln oder durch etwas anderes
klar machst ist völlig egal, nur wenn du nicht weisst, was du sagen
willst, brauchst du dir im das wie du es sagen willst, keine Gedanken
machen. Letzten Endes hast du jetzt eine ganze Menge Vorschläge
bekommen wie du es besser machen könntest. Aber bei der Umsetzung
hapert es.
Probiere doch einfach mal zu erklären, wo genau du bei der letzten
Umsetzung gescheitert bist und warum. Also nicht, ich hatte jede Menge
Spagetticode in dem ich mich nicht mehr zurechtgefunden habe, sondern
ich hatte folgenden Algorithmus ... Beschreibung, bei den und den
Sachen hat es nicht funktioniert(Gründe). Das ist nämlich die Analyse
die du als erstes machen musst egal bei welchem Problem. Dann kann man
die Programmiersprache auswählen in der man das möglichst einfach
formulieren kann.

von Anfaenger (Gast)


Lesenswert?

@Markus Volz

Nein, ich nehme es Dir nicht überl, das Du mir genau die Position
aufzeigst, auf der ich mich im Moment befinde.
Das die Projekte eine oder mehr Nummern zu groß sind, habe ich
gemerkt.
Mein Denkfehler war wohl: AVR Tutorial an einem Abend durchspielen, ein
paar ATmega kaufen, dazu dann noch ein paar Quarze (Den Rest der
Elektronik hate ich hier rumliegen) und dann mal los, größere Sachen
anfangen. War wohl ein Fehlschluß.

@Wolfram
Also werde ich mich nun mal weniger mit der Hardware, sondern mehr mit
dem Ausformulieren einer Lösungsstrategie beschäftigen.
Ich habe heute Nachtschicht und wenn sich da mal eine Stunde oder so an
Zeit ergibt, werde ich versuchen, mal das Umsetzerproblem in einen
Algorithmus zu formulieren.

An alle:

Vielen Dank für eure Hilfe und die vielen Tipps.
Ich habe nun verstanden, das nicht alles, was so einfach aussieht (wenn
man hier im Forum die Codesammlung so durchstöbert sieht das ja für
einen wie mich so aus, als ob µC Programmieren die Lösung für alle
Probleme der Elektronik wäre) in Wirklichkeit das Ergebnis von vielen,
vielen Stunden harter Arbeit ist.

Ich für meine Person werde also wieder zurück zu den blinkenden LED´s
und dem 2 Zeilen Display gehen und damit dann so lange
weiterexperimentieren, bis das Umsetzen von Problemen in Code bei mir
geläufiger ist.

Anfaenger

von Wegstabenverbuchsler (Gast)


Lesenswert?

> Also werde ich mich nun mal weniger mit der Hardware, sondern mehr
> mit dem Ausformulieren einer Lösungsstrategie beschäftigen.
> Ich habe heute Nachtschicht und wenn sich da mal
> eine Stunde oder  so an Zeit ergibt, ...

--> erfahrungsgemäß wird dieser softwaretechnische konzeptionelle Teil
(die Formulierung des Algorithmus) als auch die praktische Umsetzung
eher länger dauern als der hardwaretechnische Teil

Vergleichbar:
Konzept: Ach ja, für die Statusmeldung nehm ich ne grüne LED, mach da
470 Ohm vor, und papp den an Port 4.3 dran weil .. (irgendein Grund) (1
Minute)
Umsetzung: kram-in-Schublade (1 Min) ... Britzel-Bratzel (1 Minute)


> werde ich versuchen, mal das Umsetzerproblem in einen
> Algorithmus zu formulieren.

Mach es dir leicht und beschreib es in deiner Muttersprache in einer
dir genehmen "Einfachformulierung"

einfach: "wiederhole 20 mal im Abstand von 1 Sekunde: ..."

evtl. verständlich: " for (i=0; i=19; i++) interval 1 sec do{ ...}

unverständlich:
ld a, 5761
ld b, 20
djnz blabla
jp xyz

von Peter D. (peda)


Lesenswert?

"erfahrungsgemäß wird dieser softwaretechnische konzeptionelle Teil
(die Formulierung des Algorithmus) als auch die praktische Umsetzung
eher länger dauern als der hardwaretechnische Teil"



Oftmals werden folgende Zahlen genannt:

Harwareentwicklung: 10..20%

Softwareentwicklung: 80..90%


Aus meiner Erfahrung kann ich sagen, das stimmt.
Manchmal ist sogar 5% HW zu 95% SW drin.

Die höhere Flexibilität einer Softwarelösung hat ihren Preis.

Alerdings eben auch Vorteile, wenn man Fehler nachträglich beim Kunden
durch eine Update-CD beheben kann und nicht neue Platinenlayouts machen
muß und die ganzen alten Platinen zurückrufen und in die Mülltonne
kloppen muß.


Wenn also jemand behauptet, er hätte die Hardware fertig und damit 80%
des Projektes und müsse nur noch nen bischen Software machen, dann kann
ich nur lachen ob der Ignoranz.


Peter

von Peter D. (peda)


Lesenswert?

Mal ein Beispiel:

Strommessung bei nem 5000V-Modul, dabei vergessen, daß durch den 50Meg
Meßwiderstand ja auch schon Strom fließt.


Also flux die Formel Iist = Imeß - Umeß / 50Meg ins Programm eingefügt
und die Sache ist gegessen.

In Hardware hätte ich noch nen extra differenz-Opamp einfügen müssen
und vielleicht sogar noch nen Trimmpoti zum Abgleich.


Peter

von Wegstabenverbuchsler (Gast)


Lesenswert?

@Anfaenger

und wei weit bist du jetzt mit der Software-Spezi nach 1 Stunde
Nachtschicht?

von Sebastian (Gast)


Lesenswert?

Mein Tipp: Hirn einschalten und alle Aufgaben in sinvolle
Unterfunktionen (und Sourcefiles) verpacken. Das strukturiert zum einen
den Code, erleichtert aber auch die nächsten Projekte.

Irgendwann musst Du bei neuen Projekten nur noch die (virtuelle)
Schublade öffen, Deine Sourcecodes neu mischen, den Sourcecode um
bisher neues erweitern und fertig.

Ich habe z.B. öfter Projekte mit DMX (ein serielles
Datenübertragungsprotokoll der Lichttechnik). Dazu habe ich eine Datei,
z.B. "DmxInAtMega8.c", die wird includiert, die darin enthaltenen
Funktionen aufgerufen und gut ist.

Oder eine Datei "RSServoOut.c", die Modellbauservos ansteuern kann.

Beide kombiniert ergibt dann eine Software, die Daten von einer
Lichtsteuerung einließt und mit diesen Daten ein (oder mehrere)
Modellbauservo ansteuert.

Gruß,
Sebastian

von Anfaenger (Gast)


Lesenswert?

@Wegstabenverbuchsler

Es war mehr als 1 Stunde Nachtschicht. Schliesslich bezahlt man mich ja
für die Störungsbeseitung an Industriemaschinen und nicht für das
Herumsitzen in der Werkstatt zum Grübeln über Softwareprobleme.

Die Strategie, einzelnen Module zu entwerfen habe ich dabei mal auf dem
Papier versucht.

Sollte klappen. Nun brauch ich nur mal einen Anfall von Bastel und
Programmierwut, dann sollte die Platine mit dem RS232 --> Centronics
Wandler wenigstens schon einmal die eingehenden Daten auf 8 LED
darstellen.


Danke nochmal für eure Anteilnahme.

Anfaenger

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.