Forum: Mikrocontroller und Digitale Elektronik Flag in BLOCK setzen und löschen?


von Maxim B. (max182)


Lesenswert?

Guten Tag!
Ich habe wieder eine Frage:
Yalu X hat für mich sehr interessante Lösung mit Attribut "cleanup" 
erklärt.
Beitrag "Re: Lokale Variable statt static, aber optimiert. Wie?"

Vielleicht gibt es eine ähnliche Möglichkeit, um für die Ausführungszeit 
einer Funktion bestimmte Flags setzen und danach löschen (oder 
umgekehrt) ?

Z.B. möchte ich Zugang zu SPI aus ISR. Z.B. aus Timer-ISR, wo Systempuls 
gemacht wird. Aber SPI kann in dieser Zeit andere Operationen aus 
mehreren byte-Sendungen ausführen, die nicht zu unterbrechen sind (in 
diesem Fall sollte Zugriff aus ISR nicht stattfinden, und wenn ISR 
wieder kommt, dann wieder versuchen). Natürlich kann ich "per Hand" am 
Anfang einer solchen Operation Flag "SPI besetzt" setzen, und am Ende 
dieser Operation wieder löschen.
Aber es wäre doch schön, einfach wie bei cleanup "SPI_SAVE;" schreiben 
und nicht mehr denken, daß später Flag gelöscht sein sollte.

Nach dieser Art könnten auch viele andere ähnliche Fälle gelöst 
werden...

Ist das in GCC auch möglich?

Vielen Dank für die Antwort im voraus!

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Maxim B. schrieb:

> Vielleicht gibt es eine ähnliche Möglichkeit, um für die Ausführungszeit
> einer Funktion bestimmte Flags setzen und danach löschen (oder
> umgekehrt) ?

Ich nehme weiterhin an, es geht um C? In C++ einfach machbar (Stichwort: 
RAII).

von Maxim B. (max182)


Lesenswert?

Ja, ich möchte bei C bleiben.
Ich denke, dort wo ich mich jetzt befinde, sollte ich besser alle 
Möglichkeiten von C und GCC bestens kennenlernen.
Wenn ATMega nicht mehr produziert werden, mein JTAGICEII kaputt geht und 
ich nach mehr Möglichkeiten suchen werde, als ATMega geben kann - dann 
kommt Zeit für C++.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Maxim B. schrieb:
> Ja, ich möchte bei C bleiben.

Ok, aber schade.

Mal als Anregung: https://www.youtube.com/watch?v=YnWhqhNdYyk

> Ich denke, dort wo ich mich jetzt befinde, sollte ich besser alle
> Möglichkeiten von C und GCC bestens kennenlernen.

Warum?

> Wenn ATMega nicht mehr produziert werden, mein JTAGICEII kaputt geht und
> ich nach mehr Möglichkeiten suchen werde, als ATMega geben kann - dann
> kommt Zeit für C++.

???

von Einer K. (Gast)


Lesenswert?

Maxim B. schrieb:
> Aber es wäre doch schön, einfach wie bei cleanup "SPI_SAVE;" schreiben
> und nicht mehr denken, daß später Flag gelöscht sein sollte.

Sowas?
1
void tuWas()
2
{
3
   SPI_SAVE(SPI1)
4
   {
5
     // hier tuwas mit SPI1
6
   }
7
}

Dann schaue dir das ATOMIC_BLOCK makro an, das tut es so!

von Maxim B. (max182)


Lesenswert?

Arduino Fanboy D. schrieb:
> Dann schaue dir das ATOMIC_BLOCK makro an, das tut es so!

Danke!

von Maxim B. (max182)


Lesenswert?

Wilhelm M. schrieb:
> Warum?
>
> ???

Weil die Profis sagen:
mit C++ kann man viel leichter als mit C etwas schlechtes und 
unverständliches machen.

Und auch weil ich nicht genau weiß, wie man mit AVR Studio 4.19 etwas 
auf C++ macht. Umstellen auf eine andere Version von Studio möchte ich 
jetzt nicht, da JTAG mit ihr gut arbeitet. Wenn ich auf spätere 
Versionen von Studio gehe, dann sind Kosten für Upgrade zu hoch: ich 
brauche neuen Laptop, fast alle Programme neu und noch neuen 
JTAG-Emulator.

Ich möchte schon vorhandene Technik bis zu Ende benutzen, und erst wenn 
es nicht weiter geht, nur dann ersetzen. Manche Programme kosten alleine 
vergleichbar mit einem Laptop.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Maxim B. schrieb:
> Wilhelm M. schrieb:
>> Warum?
>>
>> ???
>
> Weil die Profis sagen:
> mit C++ kann man viel leichter als mit C etwas schlechtes und
> unverständliches machen.

Das sind ja tolle Profis ;-)

M.E. ist die Reihenfolge C -> C++ sehr ungünstig, vor allem, wenn man 
damit auf dem µC anfängt. Man lernt dabei sehr schlecht bis gar nicht, 
in Abstraktionen zu denken.
Besser ist in meinen Augen ein Start auf dem PC mit C++, dann C++ auf 
dem µC, wobei automatisch die prozeduralen (und generischen) Anteile in 
den Vordergrund rücken.

von Peter D. (peda)


Lesenswert?

Maxim B. schrieb:
> Aber SPI kann in dieser Zeit andere Operationen aus
> mehreren byte-Sendungen ausführen, die nicht zu unterbrechen sind

Für den Fall bietet sich der SPI-Interrupt geradezu an.
Man legt ein Array von Callbacks (Funktionspointer) an, die der 
SPI-Interrupt aufruft. Ein Indexzähler zeigt dann jeweils auf das 
auszuführende Callback. Ist es fertig, löscht es sich aus der Liste 
(Nullpointer) und setzt den Index eine Stelle weiter. Ist die Liste 
leer, disabled sich der SPI-Interrupt. Wird ein SPI-Job in die Liste 
eingetragen, enabled er den SPI-Interrupt wieder. Jedes Callback 
behandelt immer nur ein Byte, d.h. muß sich den Bytezähler selber 
merken. Oder der Bytezähler wird mit in der Liste gespeichert und dem 
Callback übergeben.
Der Timerinterrupt trägt seinen Callback dann in die nächste freie 
Stelle ein.
Ich würde dafür folgende Funktionen implementieren:
void spi_job_init(void);
bool spi_job_add(fp *fptr);
void spi_job_advance(void);

P.S.:
Für den Bytezähler reicht eine Variable, da ja die Jobs nicht 
gleichzeitig ausgeführt werden können. Er muß also nicht mit ins Array.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Warum?
>
> ???

Ach, lass ihn...
Ein gutes C Programm ist immer noch schöner, als ein schlechtes in C++.

C++ lernen ist mit ein paar Hürden verbunden.
Mittlerweile habe ich etwas C++ Übung, und ich kann sagen:
> Wenn man das Licht am Ende des Tunnels, meint zu sehen,
> dann ist es meist ein Zug, der auf einen zu kommt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Arduino Fanboy D. schrieb:
> Wilhelm M. schrieb:
>> Warum?
>>
>> ???
>
> Ach, lass ihn...

Mich interessieren die Antworten auf solche Fragen.

> Ein gutes C Programm ist immer noch schöner, als ein schlechtes in C++.

Man kann es aber in C++ wesentlich schöner machen ...

> C++ lernen ist mit ein paar Hürden verbunden.

Eigentlich nur, wenn man schlechte Bücher und/oder schlechte Lehrer hat.

von Dr. Sommer (Gast)


Lesenswert?

Maxim B. schrieb:
> Ich denke, dort wo ich mich jetzt befinde, sollte ich besser alle
> Möglichkeiten von C und GCC bestens kennenlernen.

In C geht so etwas nicht vernünftig. Alle obskuren Möglichkeiten von GCC 
ausloten um es nachzubauen macht dich vom GCC abhängig, ist wenig 
übertragbar und erweiterbar, man findet nicht viel dazu im Netz oder 
Büchern, funktioniert mit anderen Compilern & Plattformen nicht. Da ist 
es doch sinnvoller die gut bekannten, verbreiteten und flexiblen 
Möglichkeiten von C++ zu lernen. Viel mehr Leute dürften zumindest die 
hier benötigten Grundzüge von C++ kennen, als alle Details und 
Erweiterungen des GCC.

Maxim B. schrieb:
> Und auch weil ich nicht genau weiß, wie man mit AVR Studio 4.19 etwas
> auf C++ macht.

Die Quellcode-Datei nach .cpp umbenennen.

Maxim B. schrieb:
> Umstellen auf eine andere Version von Studio möchte ich
> jetzt nicht, da JTAG mit ihr gut arbeitet.

C++ Programme werden exakt genauso per JTAG übertragen.

Maxim B. schrieb:
> Wenn ATMega nicht mehr produziert werden, mein JTAGICEII kaputt geht und
> ich nach mehr Möglichkeiten suchen werde, als ATMega geben kann - dann
> kommt Zeit für C++.

Du würdest also auch erst Auto Fahren lernen wenn es keine Pferde und 
Kutschen mehr gibt?

Maxim B. schrieb:
> Wenn ich auf spätere
> Versionen von Studio gehe, dann sind Kosten für Upgrade zu hoch: ich
> brauche neuen Laptop, fast alle Programme neu und noch neuen
> JTAG-Emulator.

Wie alt ist dieses Laptop, und wie sehr möchtest du dich durch Sparen 
einschränken... Halbwegs aktuelle PC-Hardware bekommt man (gebraucht) 
für 300€ oder so.

Ansonsten ist die Antwort auf deine Frage:
Genau so wie in Beitrag "Re: Lokale Variable statt static, aber optimiert. Wie?"

von Stefan F. (Gast)


Lesenswert?

Es gibt bei Mikrocontrollern nur einen harten Grund gegen C++:

Mikrocontroller ohne RAM können C++ Programme nicht ausführen.

Nur: Wann hat hier jemand zuletzt mit so einem µC zu tun gehabt?

von Maxim B. (max182)


Lesenswert?

Peter D. schrieb:
> Für den Fall bietet sich der SPI-Interrupt geradezu an.
> Man legt ein Array von Callbacks (Funktionspointer) an, die der
> SPI-Interrupt aufruft. Ein Indexzähler zeigt dann jeweils auf das
> auszuführende Callback.

Vielen Dank!
Sehr interessante Idee!

Im Moment kam das Problem bei mir, weil ich alle auf meiner Platine 
eingebauten Geräte noch teste und Grundfunktionen schreibe. 
Hauptschleife.
Drehgeber sollte aber besser jede ms abgefragt werden, mit steigender 
Zahl von Aufgaben in der Hauptschleife hat Drehgeber seine Grenze 
erreicht, deshalb sollte ich aus ISR abfragen.

In der Zukunft möchte ich aber von mir früher (aus einer Idee von einem 
Anderen) entworfenen Planer benutzen, dort gibt es Prioritäten und mit 
jeder Aufgabe wird noch eine 32bit-Variable gespeichert (nichts steht im 
Wege (außer Leistung), auch 64bit-Variable zu speichern). Dort wird das 
einfacher: wird eine Aufgabe, die SPI braucht, merken, daß SPI besetzt 
wird, dann stellt sich selber die Aufgabe wieder auf die Reihe, ein paar 
ms später.

Aber für mich ist interessant, alle Varianten auszuprobieren. Ich denke, 
die Arbeit mit ISR ist besonders für I2C und USART von Wert. Bei SPI 
kommen lange mehrbytes-Übertragungen. Z.B. wenn ich meine graphische 
Anzeige bediene, die über MCP23S17 geschalet wurde, wird für jeden Bytes 
in Display 12 bytes per SPI übertragen (d.h. ein ASCII-Zeichen kostet 72 
bytes). Beim Lesen noch mehr (alles in 3-bytes-Einheiten). LCD braucht 
in SPI-Mode (mit 4bit-parallel habe ich wenig Glück gehabt) auch je 3 
bytes ununterbrochen in Serie (aber mit langsamer Geschwindigkeit als 
andere Geräte). SPI-RAM kann blockweise lange Übertragungen machen, auch 
für 1 bytes sind 5 bytes notwendig. Kleinstmögliche Einheit kann man 
wohl nach CS bestimmen.

Ja, es gibt was zu überlegen noch...

von Maxim B. (max182)


Lesenswert?

Dr. Sommer schrieb:
> Wie alt ist dieses Laptop, und wie sehr möchtest du dich durch Sparen
> einschränken... Halbwegs aktuelle PC-Hardware bekommt man (gebraucht)
> für 300€ oder so.

Na, etwa schon 9 Jahre. Problem ist nicht und nicht nur Laptop selbst 
sondern alles, was auf dem steht. Ursprünglich stand auf dem Laptop 
Windows 7, aber ich habe auf gut mir bekanne Windows XP umgestellt (ich 
konnte noch Treiber finden), was Geschwindigkeit spürbar verbesserte. 
Ich habe eine Menge von Programmen, die mit Windows 10 nicht laufen, 
manche auch mit Windows 7, die ich aber täglich brauche. Extra nur für 
Mikrocontrollern Laptop zu halten ist auch nicht so bequem, da ich zu 
dem Laptop gewöhne und ständige Wechsel nicht komfortabel ist (das habe 
ich erlebt, wie ich versuchte, zweiten Laptop mit Kubuntu parallel zu 
nutzen).

Ich habe Festplatte 2 TB und 4 GB RAM (davon kann XP 3,5 benutzen, was 
auch nicht so schlecht ist) installiert, und zuerst reicht mir das für 
alles.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Maxim B. schrieb:
> wird für jeden Bytes
> in Display 12 bytes per SPI übertragen

Vielleicht ist für dich ein kleiner ARM-Controller (z.B. STM32F103) mit 
DMA sinnvoll. Der kann (nahezu) beliebig viele Bytes auf einmal ohne 
Software-Arbeit übertragen.

Maxim B. schrieb:
> SPI-RAM kann blockweise lange Übertragungen machen

SPI-RAM braucht man dann wahrscheinlich auch nicht mehr, weil die viel 
RAM integriert haben.

Weitere Vorteile: C++ läuft besser da Standard-Bibliothek vorhanden, 
kein __flash oder PROGMEM benötigt, JTAG-Adapter sehr billig, komplett 
Open Source Toolchains verfügbar (geht auch super mit Linux, was auf 
alten PCs gut geht)...

Maxim B. schrieb:
> Ursprünglich stand auf dem Laptop
> Windows 7, aber ich habe auf gut mir bekanne Windows XP umgestellt (ich
> konnte noch Treiber finden), was Geschwindigkeit spürbar verbesserte.

Damit sollten aber auch aktuellere Toolchains laufen, auch für ARM. 
Wobei ich mir schon Gedanken machen würde ob man die uralte Software 
wirklich braucht und die nicht per VM geht und ob man davon wirklich so 
viel abhängig machen möchte.

von Maxim B. (max182)


Lesenswert?

Windows 10 möchte ich prinzipiell nicht benutzen: vor 2 Jahren habe ich 
Laptop mit Windows 10 gekauft, alles war sehr sehr langsam. Dann habe 
ich Kubuntu installiert, dort eine virtuelle Maschine und dort noch 
Windows XP und Windows 7. Komisch: Windows XP über Kubuntu und virtuelle 
Maschine läuft deutlich besser und schneller, als Windows 10 direkt!!! 
Was haben dort die Programmierer aus Microsoft gemacht, keine Ahnung. 
Aber man braucht bestimmt viel Talent, um aus einem nicht besonders 
schlechten Laptop eine Bremse zu machen!

: Bearbeitet durch User
von Maxim B. (max182)


Lesenswert?

Dr. Sommer schrieb:
> Vielleicht ist für dich ein kleiner ARM-Controller (z.B. STM32F103) mit
> DMA sinnvoll. Der kann (nahezu) beliebig viele Bytes auf einmal ohne
> Software-Arbeit übertragen.

Ich finde es viel bequemer mit einem Mikrocontroller mit 5 Volt 
Speisung: so kann ich auch blauen und weißen LED direkt an Pins 
schalten, ohne Pegelwandler. Auch für MOSFET ist 5 Volt besser als 3. Es 
ist normalerweise leichter, Pegel von 5 auf 3 Volt zu reduzieren als 
umgekehrt. Ich möchte zuerst alle vorhandenen ATMega bis zu Verschleiß 
ausnutzen. Danach kenne ich C bestimmt viel besser und kann dann wohl 
mit STM etwas machen.

Ich mag es außerdem, die IC auf selbstgebaute Leiterplatte zu löten, 
ohne Zwischenstufe. STM mit 0,5 mm zwischen Pins ist für meinen Augen 
eine Herausforderung. Nach Möglichkeit gehe ich nicht unter 1,27 mm, 
notfalls 0,8 mm.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Maxim B. schrieb:
> Ich finde es viel bequemer mit einem Mikrocontroller mit 5 Volt
> Speisung: so kann ich auch blauen und weißen LED direkt an Pins
> schalten, ohne Pegelwandler.

Kompromisslösung:
1
       +-----------------------------------------------------+
2
       |                                                     |
3
5V o---+---[3,3V Regler]---[Mikrocontroller]---[===]---|<|---+
4
5
                                                       LED

von Maxim B. (max182)


Angehängte Dateien:

Lesenswert?

Auf meiner Platte gibt es auch 3V3: für SD-Card und für LCD...

Für diese Platte habe ich mit Absicht ATMega in DIP40 genommen: nach 
Verschleiß (10 000 Umprogrammierungen versprochen) kann ich die 
wechseln, ohne zu löten. So hoffe ich, damit lange spielen zu dürfen. 
Ich habe sozusagen hauseigene Standard für Module entwickelt, so möchte 
ich Erweiterungsplatten für alles mögliche machen (eine mit MIDI-Buchsen 
und Optokoppler ist schon gemacht).

von Dr. Sommer (Gast)


Lesenswert?

Maxim B. schrieb:
> Windows 10 möchte ich prinzipiell nicht benutzen: vor 2 Jahren
> habe ich
> Laptop mit Windows 10 gekauft, alles war sehr sehr langsam.

Auch nachdem alle Updates installiert, alle Bloatware gelöscht und alle 
Treiber aktualisiert waren (oder besser: komplett neu installiert 
wurde)? Naja, aktuelle Toolchains gehen wie gesagt sogar mit XP, wobei 
ich mir das nicht antun würde (allein schon weil man damit aus 
Sicherheitsgründen natürlich nicht mehr ins Netz gehen sollte). Auf 
meinem auch nicht mehr ganz neuen Laptop (einfaches Office-Gerät von 
2013) läuft Win10 super flüssig.

Maxim B. schrieb:
> Ich finde es viel bequemer mit einem Mikrocontroller mit 5 Volt
> Speisung:

Na dann, du musst wissen ob die 5V-Bequemlichkeit wichtiger ist als die 
Software-Bequemlichkeit (bessere Toolchains, besseres Debugging, viel 
mehr Leistung/Ressourcen, ...).

Maxim B. schrieb:
> Danach kenne ich C bestimmt viel besser

und muss alle schlechten C-Angewohnheiten wieder un-lernen wenn du dann 
doch mal auf C++ wechseln möchtest...

Maxim B. schrieb:
> STM mit 0,5 mm zwischen Pins ist für meinen Augen
> eine Herausforderung. Nach Möglichkeit gehe ich nicht unter 1,27 mm,
> notfalls 0,8 mm.

Der STM32G031J6 hat ein 1.27mm SO-8 Gehäuse. Ist allerdings eine 
ziemliche Ausnahme. Es gibt aber sehr billige handliche 
Breakout-Boards...

Maxim B. schrieb:
> Für diese Platte habe ich mit Absicht ATMega in DIP40 genommen: nach
> Verschleiß (10 000 Umprogrammierungen versprochen)

Die 10.000 hat noch nie jemand erreicht... Vorher grillt man die per ESD 
oder so.

von Maxim B. (max182)


Lesenswert?

Dr. Sommer schrieb:
> Naja, aktuelle Toolchains gehen wie gesagt sogar mit XP

Ich habe mir Toolchain aus einer aktuellen Atmel Studio herausgenommen. 
Dafür habe ich unter Kubuntu, virtueller Maschine und Windows 7 die 
installiert (sehr langsam!), Daten kopiert und danach alle 
gleichnahmigen Daten in dem vorhandenen Toolchain ersetzt.

> Der STM32G031J6 hat ein 1.27mm SO-8 Gehäuse.
2x Vcc und Gnd. Dann wohl auch Reset? Und was bleibt fürs Leben? Wozu so 
ein Leben überhaupt?

> Die 10.000 hat noch nie jemand erreicht... Vorher grillt man die per ESD
> > oder so.
Macht nichts. Ich habe welche parat :) Einfach neue stecken und los...

Auch stehen zwei 20xBuchsen parallel zu MC, so habe ich alle 
MC-Leitungen auch für externe Steckbrett. Es gibt auch Buchsenreihen für 
GND, 5 und 3,3 Volt.

Als Anregung diente mir diese Platte:
http://shop.easyelectronics.ru/index.php?productID=153
Die habe ich auch gekauft, wie ich in Moskau war (ich sollte lange 
warten, bis sie aus Sybirien kommt!). Aber sie ist für etwas anderes 
gedacht. Ich habe überlegt, ich mache mir lieber eine eigene, mit 
anderen Akzenten.

Alles, was ich für besonders häufigen Gebrauch schätze und was auch für 
Debug gut sein kann, habe ich auf dieser Platte integriert: 2x LCD 
(Symbol- und graphische), digitale Anzeige (aus China mit max7219) und 
eine Baranzeige (auch max7219), 5 Tasten und Drehgeber, DS3234 und 
SPI-RAM mit 1,5 F Kondensator, MicroSD-Steckdose mit Pegelwandler, 3 
chinesischen WunderLED WS2812B... Alles außer SD-Card schon getestet. 
Alles andere sollte extern kommen, per Buchsen.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Maxim B. schrieb:
> Ich habe mir Toolchain aus einer aktuellen Atmel Studio herausgenommen.

Dir ist klar dass man die auch separat herunterladen kann... Auch für 
Linux!

Maxim B. schrieb:
> Einfach neue stecken und los...

Ich dachte die sollen direkt auf die Platine. Ob Sockel oder 
Mini-Breakout-Board ist auch kein großer Unterschied... z.B.:

https://www.st.com/en/evaluation-tools/nucleo-l432kc.html

Das hat sogar den Debugger mit dabei.

Maxim B. schrieb:
> Als Anregung diente mir diese Platte:

Was für ein Monstrum! Für ARM gibt es natürlich auch eine riesige 
Vielfalt an Platinen/Eval-Boards. Und dank einheitlicher Plattform 
kannst du die alle (von allen Herstellern) mit der selben Software und 
dem selben JTAG-Adapter programmieren (sofern du einen 
herstellerübergreifenden hast, z.B. J-Link).

von Maxim B. (max182)


Lesenswert?

Dr. Sommer schrieb:
> Dir ist klar dass man die auch separat herunterladen kann...

Ich habe nichts passendes gefunden. Bei allen neueren Versionen, wenn 
ich die direkt zu installieren versuchte, war Problem mit Make. Deshalb 
habe ich letzte Version, wo Make drin ist und gut arbeitet 
(avr-toolchain-installer-3.4.2.1573-win32.win32.x86.exe), danach 
avr8-gnu-toolchain-installer-3.6.0.1734 dazu noch gebracht.

> Was für ein Monstrum!
Was Autor wirklich gut gemacht hat: es gibt eine Reihe von Artikel von 
ihm, wo er stufenweise für Anfänger mit dieser Platte erklärt, wie alles 
geht. Alles mit Beispiel. Z.B. wie man graphische Anzeige bedient oder 
wie man TWI als ISR-Automat macht.

Was aber dem Autor nicht gelungen wurde: gute Speisesystem.
Auch eingebaute JTAG ICE Generation 1 ist für mich nicht von Wert. 
Dagegen gibt es mit seiner Platte Problem, USART mit XCK zu nutzen.

Ich wollte schon mit ARM (mit STM) beginnen. Aber dann fand ich, daß ich 
lieber zuerst mit einfacheren AT Mega lerne.

Speisesystem: ich habe für nur 5 Volt die Platte gemacht (es gibt Geräte 
mit 3V3, aber MC hat 5 Volt). Grund war: manche IC wollen doch lieber 5 
Volt und arbeiten von 3V3 schlecht oder gar nicht (max7219 oder auch 
WS2812B ). Von anderer Seite, wenn ich später einiges vom Code voanders 
verwende, dann geht das genau so auch mit 3 Volt oder auch 4 oder auch 
1,8 Volt (nur F_CPU anpassen).
OKI-78SR benutze ich schon seit langem, immer stabile gute Arbeit. 1,5 A 
bei 5 Volt reicht meistens für alles. Vin kann 9, 12, 24 Volt sein, 
alles akzeptabel, da Impulswandler. Und es steht noch LD1117 für 3,3 
Volt - auch mit Absicht keine modernere genommen, da hier Sparsamkeit 
unwichtig ist, aber Fähigkeit von Wert, notfalls auch Strom zu nehmen.

: Bearbeitet durch User
von ein Profi (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Das sind ja tolle Profis ;-)
> M.E. ist die Reihenfolge C -> C++ sehr ungünstig, vor allem, wenn man
> damit auf dem µC anfängt. Man lernt dabei sehr schlecht bis gar nicht,
> in Abstraktionen zu denken. Besser ist in meinen Augen ein Start auf dem
> PC mit C++, dann C++ auf dem µC, wobei automatisch die prozeduralen (und
> generischen) Anteile in den Vordergrund rücken.

Es ist wurscht, welche Sprache du verwendest.
Man muss unabhängig von der Sprache und unabhängig von der 
SW-Entwicklung in Abstraktionen denken können.
Der Entwurf (= das funktionale Design) eines Programms oder einer 
Applikation sollte deine prozeduralen Anteile bereits beinhalten. Deine 
generischen Anteile kommen aus der Architektur, die nach und folgend aus 
dem Design erstellt wird.
kopfschüttel

Man lernt programmieren vielleicht mit Beispielen in einer Sprache. Die 
Sprache definiert aber keinesfalls was und wie du denken können sollst.

Glaub mir, es gibt C++-Software-Entwickler, die gerne in einer einzigen 
C++-Quelldatei 10 Klassen runterschreiben, die sich zu 95% gleichen. 
Diese Art von "Entwickler" hat kein abstraktes Denken gelernt. Die 
Sprache unterstützt diese armen Menschen daher garnicht beim Anwenden 
einer bestimmten Denkweise.

von ein Profi (Gast)


Lesenswert?

PS
Bis die Architektur steht, ist übrigens noch keine einzige Zeile Code 
da.

von Stefan F. (Gast)


Lesenswert?

ein Profi schrieb:
> Man lernt programmieren vielleicht mit Beispielen in einer Sprache. Die
> Sprache definiert aber keinesfalls was und wie du denken können sollst.

Erzähle das mal den Leuten, die Frameworks vermarkten, die der Nabel der 
Welt sein wollen.

von Einer K. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Mich interessieren die Antworten auf solche Fragen.

Mich eher nicht.
Denn die Antwort ist offensichtlich!

Wer vor der Entscheidung steht, C oder C++ zu lernen, hat noch nicht die 
nötige Kompetenz/Wissen/Erfahrung um diese Entscheidung objektiv zu 
treffen.

Also wird die Entscheidung aus dem Bauch heraus getroffen. Damit ist sie 
automatisch irrational(?).
Diese Art der Entscheidungsfindung wurde uns von der Evolution für 
Notlagen mitgegeben. Denn wenn einen ein Tiger in den Hintern beißen 
will, ist keine Zeit für Abwägungen, kundig machen usw.

Damit hat sich die Frage "Warum?" eigentlich erübrigt.
Es gibt kein ursprüngliches "Warum?", bestenfalls eine nachgeschobene 
Rechtfertigung.

Ich behaupte:
99% aller Entscheidungen beruhen nicht auf klare Fakten, sondern werden 
aus dem Bauch heraus getroffen.
Danach wird ein Großteil der Intelligenz darauf verplempert, sich und 
anderen, den Mist schön zu reden, den man gerade verzapft.

Beispiel:
Durch die Kurve bin ich schon hundert mal gefahren, die konnte ich schon 
immer schneiden, da ist mir noch nie einer entgegen gekommen.




Meine Erfahrung sagt: (habe das einige male beobachten dürfen)
Leute, welche aus der prozeduralen Ecke (z.B. C) kommen, tun sich mit 
der OOP (z.B. C++) recht schwer. Sind quasi verdorben für die OOP.

Andersrum ist es einfacher. Bei der OOP, bekommt man die prozedurale 
Sicht geschenkt dazu.

Es ist also schon so, dass die verwendete Sprache/Verfahren das Denken 
formt.

von Maxim B. (max182)


Lesenswert?

Arduino Fanboy D. schrieb:
> Wer vor der Entscheidung steht, C oder C++ zu lernen, hat noch nicht die
> nötige Kompetenz/Wissen/Erfahrung um diese Entscheidung objektiv zu
> treffen.

Na, ich kann sagen, warum ich mit C begonnen habe:
ich höre herum: C und C und nochmal C, dann "void" - und verstehe 
nichts! So etwas kann ich nie dulden.
Deshalb :)

Ich habe früher C51 mit Maschinencode programmiert - und komischerweise 
funktionierte das. Noch ohne Computer. So ist Denken mit Register, 
Speicherzellen usw. für mich verständlicher als mit Abstraktionen.

: Bearbeitet durch User
Beitrag #5957778 wurde von einem Moderator gelöscht.
von Einer K. (Gast)


Lesenswert?

Maxim B. schrieb:
> So ist Denken mit Register,
> Speicherzellen usw. für mich verständlicher als mit Abstraktionen.

Die Angst vor dem fremden/neuen?
;-) ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Maxim B. schrieb:

> Na, ich kann sagen, warum ich mit C begonnen habe:
> ich höre herum: C und C und nochmal C, dann "void" - und verstehe
> nichts! So etwas kann ich nie dulden.
> Deshalb :)

Du verstehst 'void' nicht?

von Maxim B. (max182)


Lesenswert?

Arduino Fanboy D. schrieb:
> Die Angst vor dem fremden/neuen?

Ja, ich mag alles haben "wie immer" :)

von Einer K. (Gast)


Lesenswert?

Maxim B. schrieb:
> Ja, ich mag alles haben "wie immer" :)
Ich verstehe das...

Möglichst viel Assembler Denke mit in C einschleppen.
Und dann 3 Jahre später, möglichst C Artig in C++ weiter machen.

Ja, so kann man das Optimum auch aus diesem Problem raus holen.
Da ist nix seltsames dran, alles total menschlich.

von Maxim B. (max182)


Lesenswert?

Arduino Fanboy D. schrieb:
> Sowas?void tuWas()
> {
>    SPI_SAVE(SPI1)
>    {
>      // hier tuwas mit SPI1
>    }
> }
>
> Dann schaue dir das ATOMIC_BLOCK makro an, das tut es so!

Ja!!! Ich glaube, das hat geklappt!
1
// spi_atomic.h
2
#ifndef SPI_ATOMIC_H
3
#define SPI_ATOMIC_H
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h> 
7
8
#include "main.h"
9
10
static __inline__ uint8_t __iSetSpiBesetztRetVal(void)
11
{
12
    FLAGG |= (1<<SPI_BS);
13
    return 1;
14
}
15
16
static __inline__ void __iResSpiBesetztParam(const uint8_t *__s)
17
{
18
    FLAGG &= ~(1<<SPI_BS);
19
    __asm__ volatile ("" ::: "memory");
20
    (void)__s;
21
}
22
23
#define SPI_BLOCK(type) for ( type, __ToDo = __iSetSpiBesetztRetVal(); \
24
                         __ToDo ; __ToDo = 0 ) 
25
26
#define SPI_FORCEON uint8_t spi_save \
27
  __attribute__((__cleanup__(__iResSpiBesetztParam))) = 0
28
29
30
#endif  /* SPI_ATOMIC_H */

Dann
1
SPI_BLOCK(SPI_FORCEON){
2
    lcd_adrmode();
3
    spi_intern_start();
4
5
    spi_master_transmit(0x1f);
6
    spi_master_transmit(data & 0x0f);
7
    spi_master_transmit(data >> 4);
8
9
    spi_intern_stop();
10
  }
In Disassembler ist alles wie gedacht.

Was mir noch stört: Code arbeitet, aber ich kapiere noch nicht ganz, wie 
genau :)
Und noch eins: Da ich RESTORESTATE nicht benutze, ist spi_save 
eigentlich überflüssig? Aber ohne will Compiler nichts machen!

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Maxim B. schrieb:
> __iSetSpiBesetztRetVal

Bezeichner mit 2 Unterstrichen, oder Unterstrich + Großbuchstabe, sind 
in C und C++ reserviert und der Standard Bibliothek vorenthalten.

Maxim B. schrieb:
> _asm_ volatile ("" ::: "memory");

Das ist hier wohl unnötig (bzw. kann für suboptimalen Code sorgen) und 
ein Überbleibsel von ATOMIC_BLOCK.

Manche Leute beschweren sich über die kryptische Syntax von C++, obwohl 
sie vielen bekannt ist und es viele Bücher darüber gibt. Andere 
schreiben wilde C Makros mit Compiler spezifischen Erweiterungen...

von Maxim B. (max182)


Lesenswert?

Dr. Sommer schrieb:
> Das ist hier wohl unnötig (bzw. kann für suboptimalen Code sorgen) und
> ein Überbleibsel von ATOMIC_BLOCK.

Ja, das ist Überbleibsel. Compiliert wird in sbi-cbi an vorgesehenen 
Stellen. Ich habe schon Angst, Zeichen zu wechseln, da endlich 
funktioniert :)

Ich habe die Namen für SpiBesetztRestore usw. ersetzt.

> Andere schreiben wilde C Makros mit Compiler spezifischen Erweiterungen...

Wie schrieb J.S.Bach in seiner Kantate BWV 163...

: Bearbeitet durch User
von Maxim B. (max182)


Lesenswert?

Peter D. schrieb:
> Man legt ein Array von Callbacks (Funktionspointer) an, die der
> SPI-Interrupt aufruft. Ein Indexzähler zeigt dann jeweils auf das
> auszuführende Callback. Ist es fertig, löscht es sich aus der Liste
> (Nullpointer) und setzt den Index eine Stelle weiter. Ist die Liste
> leer, disabled sich der SPI-Interrupt. Wird ein SPI-Job in die Liste
> eingetragen, enabled er den SPI-Interrupt wieder. Jedes Callback
> behandelt immer nur ein Byte, d.h. muß sich den Bytezähler selber
> merken. Oder der Bytezähler wird mit in der Liste gespeichert und dem
> Callback übergeben.
> Der Timerinterrupt trägt seinen Callback dann in die nächste freie
> Stelle ein.

Ein Problem sehe ich hier:
SPI-Intrface ist sozusagen eine halbfertige Schnittstelle. SPI-Interface 
senden byte und nimmt byte, aber es ist nichts in Interface bzg. CS 
definiert. Sendungen können 1 byte, 2 bytes, 3 bytes und auch hunderte 
bytes zwischen CS low und CS high sein. Deshalb die Worte "Jedes 
Callback
> behandelt immer nur ein Byte" scheinen mir etwas zweifelhaft zu sein. Eine 
Funktion, die aus Array gerufen wird, sollte vollständige Übertragung beinhalten: 
CS-Adresse einstellen (je nach System entweder entsprechende CS-Pin wählen, oder 
wie bei mir 3 Bit für HC138), CS runter, alle bytes wie es sind, CS rüber. Vor 
Einstellung der Adresse bis "CS rüber" darf die Sendung nicht unterbrochen werden.

Wenn SPI in ISR gleich die Serien von bytes senden sollte, dann braucht 
man vielleicht FIFO-Array von Structuren, wo Datenarray selbst, 
Bytezahl, SPI-Adresse und SPI-Einstellungen (Mode, Geschwindigkeit und 
Bitordnung) gespeichert werden. Alles das ist natürlich möglich...

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Maxim B. schrieb:

> Ein Problem sehe ich hier:
> SPI-Intrface ist sozusagen eine halbfertige Schnittstelle. SPI-Interface
> senden byte und nimmt byte, aber es ist nichts in Interface bzg. CS
> definiert. Sendungen können 1 byte, 2 bytes, 3 bytes und auch hunderte
> bytes zwischen CS low und CS high sein. Deshalb die Worte "Jedes
> Callback
>> behandelt immer nur ein Byte" scheinen mir etwas zweifelhaft zu sein. Eine
> Funktion, die aus Array gerufen wird, sollte vollständige Übertragung 
beinhalten:
> CS-Adresse einstellen (je nach System entweder entsprechende CS-Pin wählen, oder
> wie bei mir 3 Bit für HC138), CS runter, alle bytes wie es sind, CS rüber. Vor
> Einstellung der Adresse bis "CS rüber" darf die Sendung nicht unterbrochen 
werden.
>
> Wenn SPI in ISR gleich die Serien von bytes senden sollte, dann braucht
> man vielleicht FIFO-Array von Structuren, wo Datenarray selbst,
> Bytezahl, SPI-Adresse und SPI-Einstellungen (Mode, Geschwindigkeit und
> Bitordnung) gespeichert werden. Alles das ist natürlich möglich...

... und wir sind bei function-overloading angekommen

von Maxim B. (max182)


Lesenswert?

Ich fürchte, dann wird Array von Structuren, wo jede Structur auch Array 
für zu sendende Daten hat, zu groß für Mikrocontroller.

Deshalb bleibt vielleicht bessere Lösung: FIFO für Aufgaben, die auch 
aus ISR gestellt sein können, gemacht werden aber alle in der 
Hauptschleife.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:

>> Wenn SPI in ISR gleich die Serien von bytes senden sollte, dann braucht
>> man vielleicht FIFO-Array von Structuren, wo Datenarray selbst,
>> Bytezahl, SPI-Adresse und SPI-Einstellungen (Mode, Geschwindigkeit und
>> Bitordnung) gespeichert werden. Alles das ist natürlich möglich...
>
> ... und wir sind bei function-overloading angekommen

Ich wollte noch hinzufügen, war aber zu langsam mit dem Bearbeiten: 
viele denken, C++ sei eine objektorientierte Sprache. Das stimmt nur 
bedingt, denn C++ ist eine Multiparadigmen-Sprache, OOP ist nur ein 
Aspekt von vielen anderen Paradigmen dabei.

von Maxim B. (max182)


Lesenswert?

Ich werde mich freuen, wenn ich einmal mit C gut vertraut werde. Zu 
viele Aufgaben auf einmal sind nicht nur für Mikrocontroller, sondern 
auch für Menschen nicht wünschenswert.
1
int main(void){
2
3
1. init
4
2. Aufgaben starten, die im Hintergrund laufen sollten
5
while(1){
6
   wdt_reset();
7
   TaskManager();
8
}
9
  return 0;
10
}

Deshalb habe ich für LCD je zwei Versionen von data_out und command_out 
vorgesehen: mit Verzögerung danach (für Init) und ohne Verzögerung (für 
Arbeit mit TaskManager).

: Bearbeitet durch User
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.