Forum: Mikrocontroller und Digitale Elektronik Drehzahlmesser in Assembler (ATmega328)


von Uwe (swed24)


Angehängte Dateien:

Lesenswert?

Hallo an alle.
Ich arbeite an einem Drehzahlmesser mit 2 Modi. Die Messung der Drehzahl 
bzw. die Anzahl der Umdrehungen. Ich habe auf der Motorwelle 3 Magnete 
die ich über einen Hallsensor einen PC-Interrupt auslösen, sind also 6 
Interrupts (Impulse) je Umdrehung. Das Zählen der Umdrehungen funzt 
perfekt. Aber bei der Anzeige der Drehzahl wird nur Müll angezeigt. Die 
Berechnung mache ich so.
Der PC-Interrupt zählt die Impulse fortlaufend und der Timer1 liefert 
mir einen 0,5-sek-Takt. Ich addiere die letzten beiden Messungen, und 
bekomme damit die Impulse pro Sekunde. Die Zahl zerlege ich in die 3 
Ziffern, die 1000er, die 100er und 10er Stelle eine 0 dran fertig. Hier 
ein Beispiel:
ich habe 60 Impulse im Register, addiere die vorige Messung dazu. Jetzt 
habe ich 120 Impulse pro Sekunde. Zerlege das in 1-2-0 das 4.Digit ist 
immer 0. Dann sollte ich 1200 U/min auf der Anzeige haben. Aber die 
Zahlen auf der Anzeige springen wie wild, ein Ablesen ist unmöglich.
Irgendwo habe ich einen Fehler in meinem Programm und kann ihn nicht 
finden. Kann mir bitte jemand helfen.

Gruss  Uwe

von S. L. (sldt)


Lesenswert?

Nur zwei Randbemerkungen:

> 120 Impulse pro Sekunde
> Dann sollte ich 1200 U/min auf der Anzeige haben
Nicht 7200?

> Takt: 8 MHz ext
> Ti_on  = (1<<WGM12)|(1<<CS11)|(1<<CS10)
> OCR1A ... 3D09 (15625)
Also ich komme da auf 8 Hz, entsprechend 0.125 s, nicht die angegebenen 
0.5.

von Rainer W. (rawi)


Lesenswert?

S. L. schrieb:
> Nur zwei Randbemerkungen:
>
>> 120 Impulse pro Sekunde
>> Dann sollte ich 1200 U/min auf der Anzeige haben
> Nicht 7200?

Du solltest zwischen Umdrehungen und Impulsen unterscheiden. Das ist 
noch einmal ein Faktor 6.

von Uwe B. (uwe_beis)


Lesenswert?

Ich habe den Assembler-Code nicht weiter untersucht, dass ist mir zu 
aufwändig. Dein Phänomen ließe sich dadurch erklären, dass ein Zähler 
oder Akkumulator nicht vor jeder neuen Messperiode gelöscht wird. Eine 
Löschroutine habe ich aber gesehen.

Anderseits: Wer macht denn Software-Entwicklung ohne Debugger? Damit 
kann man systematisch untersuchen, was in welche Routine, in jeden 
Schritt hinein geht, und was dabei heraus kommt. Ist die Summe zweier 50 
ms-Perioden plausibel? Wenn nein - muss vorher sein. Wenn ja - muss 
hinterher sein. Sind die Zählwerte in den Registern plausibel? U.s.w.

Systematische Fehlersuche, zu der die Kenntnis gehört, was sich im 
Inneren tut, ist selbstverständlich für Profis und Semiprofis. Nur 
Anfänger (waren wir alle mal) wechseln aus Verzweiflung alle Elkos im 
Gerät und hoffen, damit zufällig einen Fehler beseitigt zu haben.

Noch ein Uwe

von Steve van de Grens (roehrmond)


Lesenswert?

Gibt es einen guten Grund, sich für so eine Aufgabe Assembler anzutun? 
Das kann man doch viel einfacher in C, C++ oder Basic erledigen. Dann 
kann man auch seriell Debug Meldungen ausgeben, wenn man schon keinen 
Debugger hat.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Steve van de Grens schrieb:
> Gibt es einen guten Grund, sich für so eine Aufgabe Assembler anzutun?

Weil man halt einfach Assembler lernen will und dafür ja schliesslich 
irgendwelche Anwendungen zum Testen braucht, um die Erfolge der 
Bemühungen zu bestimmen?

> in C, C++ oder Basic erledigen. Dann
> kann man auch seriell Debug Meldungen ausgeben

Als wenn das in Asm nicht ginge... So ein Schwachsinn können eindeutig 
nur Leute schreiben, die es wirklich niemals selber auch nur versucht 
haben...

Als nachgewiesermaßen völlig Inkompetenter: halt dich raus aus dem 
Funkverkehr. SHUT UP. Und spiel artig weiter mit deinen 
Arduino-Trivialitäten. Da bleibst du innerhalb der Grenzen deine 
Kompetenz.

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> Als wenn das in Asm nicht ginge...

Ja geht, aber einen printf() Ersatz schüttelt man sich nicht mal eben 
aus dem Ärmel. Dann eben doch wenigstens in einen Debugger investieren, 
oder im Simulator üben oder einen anderen Mikrokontroller nehmen, wo der 
Debugger billiger zu haben ist, falls es am Geld scheitert.

> Als nachgewiesermaßen völlig Inkompetenter

Bleibe bei den Fakten, du elender Meckersack.

Ich habe Assembler in den 90er Jahren gelernt und seit dem auf 
unterschiedlichen Architekturen verwendet. Für AVR habe ich ein ASM 
Tutorial geschrieben, das mehrere Schulen im Unterricht verwendet haben.

Beruflich arbeite ich an einem Softwarprojekt, in das unser GF bisher 
mehr als 6 Millionen Euro investiert hat (nicht Mikrocontroller). Ich 
bin dort einer von zwei Chef-Entwicklern.

Also erzähle du mir nicht, ich sei inkompetent.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

an swed24:

Was hat es mit diesem "  PinC2 Zähler 'Nullen' " auf sich? Kommentiere 
ich das " rcall nullen" aus, wird die Anzeige stabil; soll heißen, eine 
Ausgabe auf USART0, denn die LED-Ausgabe kann ich hier nicht so ohne 
weiteres nachbauen - mag sein, dass dort (§Multiplex) auch noch ein 
Fehler steckt.

von S. L. (sldt)


Lesenswert?

an Steve van de Grens:

Da hat ein Neuling ein Projekt und bittet in seinem ersten Beitrag hier 
um Hilfe. Und dann ist von Ihnen zu lesen: "C, C++ oder Basic", d.h. 
andere Programmiersprache, "in einen Debugger investieren", "im 
Simulator üben", "anderen Mikrokontroller nehmen", "falls es am Geld 
scheitert" - versetzen Sie sich in Uwes Lage: finden Sie nicht auch, 
dass bei solcher Miesmacherei Lust&Spaß an der Sache vergehen kann?

von Gerhard H. (hauptmann)


Lesenswert?

S. L. schrieb:
> Da hat ein Neuling ein Projekt und bittet in seinem ersten Beitrag hier
> um Hilfe

Naja, trivial und selbstverständlich ist es nicht gerade, ganze 
Assemblerprogramme von anderen analysieren und korrigieren zu lassen. Da 
wär eine höhere Sprache mehr Publikum zugänglich gewesen und selbst da 
wird man nicht allzuoft bereit sein, die Arbeit für andere zu machen.

Uwe B. schrieb:
> Systematische Fehlersuche

sollte aber hier kein Hexenwerk sein wenn man die Sache in ihre Teile 
zerlegt und einzeln testet. Z.B. Kommen die Impulse die zu erwarten 
sind? Zeigt die Anzeige was sie soll wenn man deren Wertebereich einzeln 
manuell durchgeht?

: Bearbeitet durch User
von Uwe B. (uwe_beis)


Lesenswert?

S. L. schrieb:
> an Steve van de Grens:
>
> Da hat ein Neuling...
Danke, du sprichst mir aus dem Herzen. "Das Mikrocontroller Forum - Ihre 
Möglichkeit, ihre Überlegenheit gegenüber den Fragestellern drastisch zu 
demonstrieren und dabei eine tiefe Befriedigung zu erfahren!"

Mein Tipp für eine Antwort in diesem Sinne wäre: "Kauf' dir einen 
billigen Drehzahlmesser und lass' die Finger von dem, wovon du nix 
verstehst."

Zugegeben, ich bin auch einer dieser Underdogs, der Mikrocontroller nur 
in Assembler programmiert, dafür aber genau weiß, was bei jedem Schritt 
in seinen Registern vor sich geht und dass nicht mehr passiert, als 
unbedingt nötig ist. Mein Hobby, ineffizient, aber genau so mag ich es. 
Meine Spezialität liegt anderswo.

Die nächste Generation wird sich über die armseligen C, C++ oder Python 
Soft- und Hardware-Entwickler mokieren. Das macht doch alles die KI, 
incl. Schaltungsentwurf, Layout, Bauteilebeschaffung, Bestückung, 
Inbetriebnahme und natürlich Fehlersuche und -beseitigung... Was für 
eine überflüssige Frage, an welchem Ende ein Lötkolben (was war das doch 
gleich?) heiß wird...

Aber zum Thema: "in einen Debugger investieren": Gibt es (in diesem Fall 
für Atmel), eine Software, mit der man Assembler schreiben und den Code 
ins Target downloaden, aber nicht debuggen kann? So ähnlich, wie sich 
eine komplexe Schaltung auszudenken und aufzubauen, aber kein Messmittel 
zu haben, mit dem man analysieren kann, wo etwas anders läuft, als man 
erwartet?

Ich will sagen: Sollte nach den ersten selbstgeschriebenen 
Programmzeilen nicht als nächstes der Code z. B. schrittweise im 
Debugger ausgeführt werden, um ihn (den Debugger) kennen zu lernen oder 
den Code zu korrigieren!?!

(Und Danke an alle die, wo auch immer, die helfende Antworten geben!)

Der andere Uwe

: Bearbeitet durch User
von Gerhard H. (hauptmann)


Lesenswert?

Steve van de Grens schrieb:
> aber einen printf() Ersatz schüttelt man sich nicht mal eben aus dem
> Ärmel. Dann eben doch wenigstens in einen Debugger investieren

Die Bytes zum Testen (= Debug Infos) einfach auf ein (richtig 
initialisiertes) UART schicken. Ein Debugger wär natürlich 
professioneller- aber eben auch erst mal zu durchschauen. Einen Hinweis 
kann ich mir allerdings nicht verkneifen: Assembler fängt man heute auf 
einem AKTUELLEN AVR an und keinem Oldie. Mit einem aktuellen 
Programmier/Debuginterface ausgestattet (UPDI) gestaltet sich auch das 
Entwickeln leichter. Auf einem Curiosity Nano Modul etwa brauchts für 
alles nur noch den USB Anschluss- inklusive dem Senden/Empfang von 
Debug-Infos.

von Achim H. (pluto25)


Lesenswert?

Geht das so? "lpm dr,Z" Oder müssen das zwei Zeilen werden:
lpm
mov dr,r0
Dann wäre es ratsam auch beim Counter das Sreg zu sichern.
Bei jedem Impuls zu teiler scheint auch nicht zielführend;-)

von Spess53 .. (hardygroeger)


Lesenswert?

Hi

>Geht das so? "lpm dr,Z" Oder müssen das zwei Zeilen werden:
>lpm
>mov dr,r0

Einfach mal das 'AVR-Instruction Set Manual' lesen.

Mfg Spess

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Uwe schrieb:
> Irgendwo habe ich einen Fehler in meinem Programm und kann ihn nicht
> finden. Kann mir bitte jemand helfen.

Musst Du selbst debuggen. Wenn Du es nicht kannst, musst Du es lernen, 
sofern es Dir wichtig ist – solche Situationen werden in Assembler immer 
wieder vorkommen, damit dann auf Foren auftauchen und jedes mal um Hilfe 
bitten/betteln wird auf Dauer einen zermürben. Meine längste Suche nach 
einem Assemblerbug (war aber AT89C52) lag bei ein paar Wochen mit vielen 
Unterbrechungen – am Ende waren es zwei Bitverschiebungen, die die Bits 
auf der anderen Seite wieder eingeschoben haben (allgemein als ROR/ROL 
bekannt), was ich die ganze Zeit nicht finden konnte. Hätte ich zu 
diesem Zeitpunkt besser das Debuggen gekonnt, hätte es wohl nicht so 
lange gedauert – deswegen ist das gekonnte Debuggen das A und O hier: 
das Debuggen richtig lernen und anwenden. Man kann auch ohne einen 
IDE-Debugger debuggen, indem man beispielsweise an bestimmten 
Stellen/Zeilen im Code etwas Sichtbares umschaltet oder sich auf ein 
Terminal ein paar Bytes (oder wenigstens ein Byte) über UART rausschickt 
– ist etwas umständlicher, aber vom Prinzip her geht es genauso.

Als ich mit den AVRs angefangen habe, habe ich hierfür alles in 
Assembler geschrieben, auch meine Bibliotheken – später bin ich aus 
Komfortgründen zu C-Sprache übergegangen, weil das doch einen auf Dauer 
sehr ermüdet und man quasi 99% der Zeit mit Fehlersuche verplempert 
statt sich auf das Wesentliche konzentrieren zu können, und habe dann 
nach und nach alles bis dato Erstellte auf C umgeschrieben. Vor den AVRs 
kannte ich aber schon Assembler und habe entsprechend programmiert – 
8085, Z80, 6502, 68000, µC51. AVR-Assembler (der 8-bitter) ist auf jeden 
Fall etwas freundlicher und einfacher als die teilweise sehr komplexe 
Adressierung mit vielen Operanden und Ausnahmen der CISC-Architektur 
damaliger Zeit – beim 68000 musste ich deswegen beim Programmieren so 
gut wie immer gleichzeitig in entsprechenden Tabellen nachschauen. Je 
mehr komplexe Berechnungen man im Assemblercode machen möchte, desto 
problematischer wird es – wenn es zu 99% nur ums Bitschaufeln geht, ist 
der Aufwand noch relativ überschaubar. Nichtsdestoweniger ist Assembler 
auf Dauer schon ziemlich anstrengend – wenn man es aber kann, ist es 
immer von Vorteil und hilfreich, auch wenn man z.B. später nur noch in C 
programmiert, denn man kann so immer nachschauen und versteht relativ 
schnell oder kann überhaupt nur so verstehen, wie der C-Compiler etwas 
übersetzt, interpretiert und konstruiert hat – bei zeitkritischen 
Anwendungen weiß man das zu schätzen. Man kann den Compiler dann auch 
dazu bringen, den Assemblercode anders, z.B. effizienter, zu generieren 
bzw. herauszusspucken.

: Bearbeitet durch User
von Carsten-Peter C. (carsten-p)


Lesenswert?

Moin,
mir ist aufgefallen, das Du in der ISR keine Register sicherst. Das wird 
nicht funktionieren.
Vielleicht so:

Multiplex:
push r16
in r16,SREG
push r16
push …              ;jetzt ev. andere genutzten Register sichern

  in    ir,SREG
  cpi    zi,3      ; letzte Ziffer angezeigt
  brlo    anzeige      ; Zahl neu einlesen
  mov    dr,z4

    ;Deine ISR
    ;und wieder herstellen
Pop …
pop  r16
out  SREG,r16
pop r16
reti

Versuche Dein Programm in überschaubare Teile zu zerlegen und teste 
diese gut aus.
Ich nutze gerne das Atmel Studio 6.2. mit dem JTAGICE mkII. Da kannst Du 
mit angeschlossener HW Haltepunkte setzen und Dir dort die Register 
anschauen.
Die oberen Register ab r16 würde ich nicht für Variablen wählen.
Gruß
 Carsten

von S. L. (sldt)


Lesenswert?

So - Originalprogramm von gestern abend, mit vierstelliger 
LED-7-Segment-Anzeige, PC1 auf GND, Takt an PC0: Die Anzeige ist stabil 
und gibt den 5-fachen Wert aus, also zum Beispiel bei 120 Hz " 600" oder 
bei 250 Hz "1250"; nur manchmal erhöht sich die 10er-Stelle um eins.

Das
> Zahlen auf der Anzeige springen wie wild
kann ich nicht nachvollziehen.

PS:
Das mit der 10er-Stelle könnte auch an meinem (simplen) Taktgenerator 
liegen.

: Bearbeitet durch User
von Uwe (swed24)


Lesenswert?

Hallo an alle,
mit so vielen Beiträgen hatte ich nicht gerechnet. Das Problem wurde 
gleich am Anfang direkt erkannt. Danke an S.L. Es war der Vorteiler von 
Timer1.
Ich bin das Programm mehrere Male in "Einzelschritten" durchgegangen und 
habe die Werte in den Registern überprüft. Keine Fehler. Aber mal die 
Timereinstellungen zu kontrollieren, auf die Idee bin ich nicht 
gekommen. Ist ja schon peinlich. Jetzt läuft alles Super.
Ich habe da aber noch eine Denkaufgabe: Ich überprüfe das Eingangssignal 
mit einem Oszi, und das zeigt mir eine Frequenz von z.B. 70Hz an. Mein 
Drehzahlmesser zeigt 700 U/min an (das enspricht 70 Impulse je sek). Das 
Oszi zählt doch die Frequenz von einer HL-Flanke zur nächsten HL-Flanke. 
Der PCint dagegen löst aber bei jeder Flanke aus. Sollte ich da nicht 
140 Interrupts haben? Und dann ist da noch der vorige Beitrag von S.L. - 
das sind ja wieder ganz andere Werte.

Gruss Uwe

von S. L. (sldt)


Lesenswert?

Zu Ihrem aktuellen (also korrigierten) Programm kann ich (natürlich) 
nichts sagen.
  Beim ursprünglichen Programm wird OC1Aaddr, d.h. §Tacho_Takt, alle 
0.125 s angesprungen; je zwei Zählerstände werden addiert, folglich 
beträgt die Messperiode effektiv eine viertel Sekunde. Im von mir 
genannten Beispiel von 250 Hz, das sind 500 Pin-Changes, entspricht das 
500/4= 125: Anzeige von "1250".

von S. L. (sldt)


Lesenswert?

Noch ein Detail, das ich völlig vergessen hatte, in Ihrem Fall jedoch 
eine vernachlässigbare Rolle spielt; und vielleicht haben Sie es ja auch 
schon selbst erkannt: die Zählung des Timers beginnt bei 0, folglich 
muss der OCR-Wert um 1 verringert werden.

PS:
Also, zum Beispiel bezogen auf das ursprüngliche Programm (und man kann 
durchaus die dezimale Schreibweise verwenden):
1
  ldi  ar,high(15625 -1)
2
  sts  OCR1AH,ar
3
  ldi  ar,low (15625 -1)
4
  sts  OCR1AL,ar

: Bearbeitet durch User
von Thomas (kosmos)


Lesenswert?

wenn du eine Sekunde lange Impulse zählst, ist deine Aktualisierungsrate 
eben sehr gering, schneller wäre es du wertest von Flanke zu Flanke aus. 
Dazu müssen aber die Flanken alle gleich lang sein, also einen 
vorbeirauschenden Magneten mit eine Hallgeber auszuwerten wird genau 
solche unterschiedlich langen Flanken erzeugen, besser wäre es den 
Magneten genau gegenüber des Hallgebers zu positionieren und eine Blende 
mit gleichlangen Ausschnitten vorbeizubewegen.

Falls deine Drehzahl an der Anzeige zu stark hüpft, kannst du einfach zu 
kleine Änderungen verwerfen. Also wenn die jetzige Drehzahl zur letzten 
ermittelten weniger als 20 U/Min abweicht, dann schickst du die neuen 
Daten eben nicht zur Anzeige. Irgendwann weicht sie dann um 30 U/Min ab 
und wird wieder aktualisiert.

Durch das Auswerten der jetzigen zur vorherigen Drehzahl kannst du auch 
ein Beschleunigen oder Verzögerung erkennen und das zum Auf- oder 
Abrunden verwenden.

von Thomas (kosmos)


Lesenswert?

hatte den atmega328 noch nicht in den Fingern, bei anderen AVRs konnte 
ich aber bisher immer die Flanke einstellen auf die reagiert wird und 
habe diese teilweise in der ISR wieder umgeschaltet, so könnte man bei 
unterschiedlichen langen Ausschnitten auch nur die gewünschten 
auswerten. z.B. immer nur die High-Low Flanken.

von Mi N. (msx)


Lesenswert?

Thomas schrieb:
> Falls deine Drehzahl an der Anzeige zu stark hüpft, kannst du einfach zu
> kleine Änderungen verwerfen. Also wenn die jetzige Drehzahl zur letzten
> ermittelten weniger als 20 U/Min abweicht, dann schickst du die neuen
> Daten eben nicht zur Anzeige. Irgendwann weicht sie dann um 30 U/Min ab
> und wird wieder aktualisiert.

Bei solchen Vorschlägen sträuben sich mir immer die Nackenhaare, weil 
man damit letztlich immer auf die Nase fällt.

Hier wird in Assembler programmiert, was sicherlich seine Reize hat und 
bei zeitkritischen Anforderungen auch Sinn ergibt. Kenn ich, war ich, 
weiß ich schon ;-)

Sobald die Aufgabe komplexer wird, geht dabei allerdings der Überblick 
verloren. Ein Programm in einfachem 'C' geschrieben kann wie ein 
Assembler verwendet werden, schafft aber für sich selbst und auch für 
Außenstehende mehr Transparenz. (Unterschiedliche Messwerte siehe oben.)
Dadurch rückt das eigentliche Problem in den Vordergrund und nicht die 
Kodierung selbst. Mein Vorschlag.
Ein weiterer Vorschlag, in der Codesammlung nach Beispielen sehen, wie 
man Frequenzen flexibel ohne "Torzeit" messen kann.

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Steve van de Grens schrieb:
> Gibt es einen guten Grund, sich für so eine Aufgabe Assembler anzutun?

Gibt schon etwas dazu. Ausführlicher auskommentiert.
Autor: Jürgen Woetzel www.avr-projekte.de Version vom 29.09.2013
Schau mal hier: "Auf Unterschiedliche Art, den Gesamtmesswert bilden"
Und von AtTiny2313 auf AT Mega noch anpassen.

ciao
gustav

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Mi N. schrieb:

> Sobald die Aufgabe komplexer wird, geht dabei allerdings der Überblick
> verloren.

Nur denen, die's halt nicht richtig beherrschen. Für alles, was in einen 
AVR8 reinpasst, kommt man mit Asm noch gut klar. Wenn man es halt 
wirklich kann und die entsprechende Übung auch bei der Umsetzung 
komplexerer Probleme hat.

Ist wie bei jeder anderen Sache auch: allein die Übung macht den 
Meister. Man muss es schlicht tun und immer wieder tun, um irgendwann 
gut darin zu werden.

> Ein Programm in einfachem 'C' geschrieben kann wie ein
> Assembler verwendet werden, schafft aber für sich selbst und auch für
> Außenstehende mehr Transparenz.

"Außenstehende" ist einfach dein Ausdruck für Leute, die zu dumm oder zu 
faul sind, Assembler zu lernen. Ja klar, wer nur C kann, wird natürlich 
weniger Schwierigkeiten haben, ein in C verfasstes Programm zu lesen als 
eins, was in Asm geschrieben ist.

Wer beides kann, kann beides lesen. Und nur allzu oft sogar das 
Asm-Programm besser. Wenn nämlich die richtigen C-Cracks am Werke waren 
und ihr C-Programm möglichst unleserlich geschrieben haben. Diese 
"Klartextverschlüsselung" wird leider recht häufig verwendet. Da ist man 
dann froh, wenn man einfach das Dissemblat lesen kann, statt sich 
stundenlang mit der Analyse des C-Machwerks gegen den C-Standard zu 
beschäftigen, um rauszubekommen, was da eigentlich passiert.

Noch viel heftiger wird das in C++. In dieser Sprache können Programme 
so geschrieben werden, dass wirklich nur noch ganz wenige Leute auf der 
Welt allein aus dem Quelltext (ohne die Möglichkeit, den Standard 
einzusehen) überhaupt eine Chance haben, herauszubekommen, was das 
Programm tut.

Was nicht weiter verwundert bei einer sehr gut vierstelligen Zahl 
Seiten, die mittlerweile rein zur Dokumentation der Sprache benötigt 
werden. Das ist völlig abartig und krank. Eine Hochsprache sollte die 
Komplexität eigentlich tendenziell eher verringern, statt sie maßlos zu 
erhöhen.

Dagegen ist die Doku für AVR8-Assembler mit insgesamt deutlich unter 50 
Seiten sehr, sehr überschaubar. Das kann man recht problemlos im 
"eingebauten Speicher" behalten. Wenn man es will.

von Mi N. (msx)


Lesenswert?

Ob S. schrieb:
>> Sobald die Aufgabe komplexer wird, geht dabei allerdings der Überblick
>> verloren.
>
> Nur denen, die's halt nicht richtig beherrschen.

Ich hatte auch schon 'float'-Berechnungen in Assembler gemacht. Das muß 
man sich nicht antun. Und erzähle mir jetzt nichts von Klimmzügen, die 
letztlich die Aufgabe nicht lösen können und nur noch mehr Verwirrung 
stiften.

Ob S. schrieb:
> "Außenstehende" ist einfach dein Ausdruck für Leute, die zu dumm oder zu
> faul sind, Assembler zu lernen.

Vollmundiger Stuss wie immer - der geistige Sohn von c-hater.

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> Noch viel heftiger wird das in C++. In dieser Sprache können Programme
> so geschrieben werden, dass wirklich nur noch ganz wenige Leute auf der
> Welt allein aus dem Quelltext (ohne die Möglichkeit, den Standard
> einzusehen) überhaupt eine Chance haben, herauszubekommen, was das
> Programm tut.

Das ist dann aber ein schlechter Programmierstil. Arduino macht vor, 
dass C++ nicht zwingend kompliziert verwendet werden muss.

> Was nicht weiter verwundert bei einer sehr gut vierstelligen Zahl
> Seiten, die mittlerweile rein zur Dokumentation der Sprache benötigt
> werden.

Die Sprache ist in der Tat zu lange gewachsen, oder soll ich verwachsen 
sagen? Java ist das gleiche passiert. Einige Firmen haben deswegen 
Regeln aufgestellt, welches Subset von C++ bei ihnen zugelassen ist, 
oder welche Version (nicht selten die erste von 1998).

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Mi N. schrieb:

> Ich hatte auch schon 'float'-Berechnungen in Assembler gemacht. Das muß
> man sich nicht antun.

Für welche (auf eine AVR8 sinnvoll umsetzbare) Aufgabe braucht man 
wirklich float? Nenne wenigstens eine!

> Und erzähle mir jetzt nichts von Klimmzügen, die
> letztlich die Aufgabe nicht lösen können und nur noch mehr Verwirrung
> stiften.

Du meinst wohl Festkommaarithmetik. Nein, das ist kein "Klimmzug", 
sondern eine pragmatische Lösung. Und zwar eine die praktisch immer 
ausreicht. Jedenfalls bei den Sachen, die man für eine AVR8-Target 
sinnvoll umsetzen könnte.

Übrigens auch für die allermeisten Sachen, die mit einem Arm-M0 sinnvoll 
gehen. Das erwähne ich, weil deine Spielwiese derzeit ja eher der RP2040 
ist.

Nö, float benutzt man allenfalls, wenn das Target auch eine Hardware 
dafür bietet. Alles andere ist ein Offenbarungseid.

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> float benutzt man allenfalls, wenn das Target auch eine Hardware
> dafür bietet.

Blödsinn. Float benutzt man, wenn es praktisch ist. Man bekommt kein 
Geld für ungenutzte Rechenleistung oder Speicher. Man bekommt Geld für 
fertig gewordene Projekte. Je schneller man dabei ist, umso mehr Geld 
bekommt man.

In C ist float leicht zu benutzen, egal ob mit oder ohne FPU.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Steve van de Grens schrieb:

> Blödsinn. Float benutzt man, wenn es praktisch ist. Man bekommt kein
> Geld für ungenutzte Rechenleistung oder Speicher.

Tja, wenn es ungenutzten Speicher oder ungenutzte Rechenleistung in 
nennenswertem Ausmaß gibt, war wohl schon das Hardwarekonzept nicht 
kostenoptimiert.

Hast du das schonmal so betrachtet?

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> war wohl schon das Hardwarekonzept nicht kostenoptimiert.
> Hast du das schonmal so betrachtet?

Ja habe ich. Es gibt nicht nur Massenware, wo es auf 50 Cent mehr oder 
weniger ankommt.

Ein Entwickler, der 2 Arbeitstage mit unnötiger Code-Optimierung 
vergeudet kostet wie viel? Schätzen wir mal grob 1000 Euro. Damit kann 
man 2000 Mikrocontroller einer höheren Leistungsklasse finanzieren sind. 
Auf die Stückzahl muss man erstmal kommen, damit sich die 
Code-Optimierung gelohnt hat.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Steve van de Grens schrieb:

> Damit kann
> man 2000 Mikrocontroller einer höheren Leistungsklasse finanzieren sind.
> Auf die Stückzahl muss man erstmal kommen, damit sich die
> Code-Optimierung gelohnt hat.

Tja, wenn man halt nur Entwickler hat, die zwei Tage brauchen, um simple 
Festkommarithmetik z.B. für eine primitive Verhältnisgleichung 
umzusetzen, dann geht deine Rechnung auf. Aber eben nur dann...

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Der Krieg ASM vs. Hochsprache wurde schon vor über 50 Jahren 
entschieden.

Zu blöd für C++ zu sein, oder zu faul 1000 Seiten zu lesen, kann man als 
Argument gegen C++ oder allgemein gegen Hochsprachen anwenden. Ist aber 
eher ein Armutszeugnis einzelner.

C++ hat übrigens eher weniger Schlüsselworte als die üblichen Assembler.

Ob S. schrieb:
> Eine Hochsprache sollte die
> Komplexität eigentlich tendenziell eher verringern, statt sie maßlos zu
> erhöhen.
Eine seltsame Begründung!

Nein.
Der Fokus liegt eher auf Wiederverwendung von Code, u.A. durch 
Portabilität.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Arduino F. schrieb:

> C++ hat übrigens eher weniger Schlüsselworte als die üblichen Assembler.

Das ist übrigens ein wesentlicher Nachteil von C++. Zu wenige 
Schlüsselwörter. Insbesondere natürlich vor allem die Konsequenz daraus: 
deren Mehrfachverwendung für völlig unterschiedliche Zwecke. Aber das 
hat C++ natürlich von C geerbt, betrifft also C weitestgehend genauso.

von Steve van de Grens (roehrmond)


Lesenswert?

Ob S. schrieb:
> deren Mehrfachverwendung für völlig unterschiedliche Zwecke

Betrifft nur ganz wenige unrühmliche Ausnahmen, denen man zum Glück nur 
selten begegnet. Insbesondere in dem C mit ++, denn der 
Objektorientierte Ansatz hat das Schlüsselwort "static" weitgehend 
überflüssig gemacht.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Arduino F. schrieb:

> Der Fokus liegt eher auf Wiederverwendung von Code, u.A. durch
> Portabilität.

Die nur allzu oft nur eine Pseudo-Portbilität ist. Erkauft durch riesige 
ifdef-Orgien im Präprozessor. Das kann man auch in Assembler haben. Dazu 
müssen zwei (ansonsten völlig verschiedene) Assembler nur je einen 
Präprozessor haben, der zumindest #ifdef, #else und #endif gleichermaßen 
kann und gleich behandelt.

Nu liegst du auf'm Rücken mit Schnappatmung, wa?

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ob S. schrieb:

> Dazu
> müssen zwei (ansonsten völlig verschiedene) Assembler nur je einen
> Präprozessor haben, der zumindest #ifdef, #else und #endif gleichermaßen
> kann und gleich behandelt.

In der Aufzählung der nötigen Präprozessor-Anweisungen fehlt natürlich: 
#define.

Mea maxima culpa.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ob S. schrieb:
> Nu liegst du auf'm Rücken mit Schnappatmung, wa?
Ganz sicher, nicht!

Wie schon gesagt:
Der Krieg ist vor langer Zeit beendet worden.
Kann sein, dass du das nicht mitbekommen hast....

Alle Argumente liegen, seit einer kleinen Ewigkeit, öffentlich aus.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Arduino F. schrieb:

> Wie schon gesagt:
> Der Krieg ist vor langer Zeit beendet worden.
> Kann sein, dass du das nicht mitbekommen hast....

Du hast zumindest eins nicht mitbekommen: deine ganze 
Compiler-Herrlichkeit funktioniert nur deshalb, weil die Leute, die halt 
auch Assembler können, immer wieder die Grundlagen dafür zusteuern...

Ohne diese Leute und ihre Kenntnisse gäbe es diese Rückzugsmöglichkeit 
für all die (selbst zensiert) Leute wie dich erst garnicht...

Und nun denke mal in die Zukunft: Wenn keiner mehr sich mit Asm 
beschäftigt, wer schreibt dann die Compiler (oder zumindest du vielen 
nötigen Asm-Einschübe, die sie erst praktisch brauchbar machen).

von H. H. (Gast)


Lesenswert?

Arduino F. schrieb:
> Der Krieg ist vor langer Zeit beendet worden.

Es gab gar keinen Krieg, nur ein paar Deppenscharmützel.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ob S. schrieb:
> Und nun denke mal in die Zukunft
Du weißt schon, wie irrational das ist?!

Merke:
C++23 ist gerade in der Verbreitung
Ein C++25 oder 27 sicher schon in Vorbereitung.

von Gerhard H. (hauptmann)


Lesenswert?

Arduino F. schrieb:
> Portabilität

Braucht man in der Regel nicht wenn vor der Programmierung die 
Hardware-Auswahl gewissenhaft war.

Arduino F. schrieb:
> Merke:
> C++23 ist gerade in der Verbreitung
> Ein C++25 oder 27 sicher schon in Vorbereitung.

Und immer weniger Einsteiger.
Entsprechende Programmierer werden immer verzweifelter gesucht.
Die Sprache ist mit ihrer Komplexität vor die Wand gefahren worden. 
Arduino sehe ich übrigens auf dem gleichen Weg.

Arduino F. schrieb:
> Der Krieg ASM vs. Hochsprache wurde schon vor über 50 Jahren
> entschieden.

Das wird täglich neu entschieden.
Ganz nach Hardware, Anforderungen, Vorlieben, Wissen, vorhandenem Code.

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Ob S. schrieb:
> Nö, float benutzt man allenfalls, wenn das Target auch eine Hardware
> dafür bietet. Alles andere ist ein Offenbarungseid.

Damals auf dem ATmega328 'double'-Berechnungen zu machen, um eine 
10-stellige Auflösung zu erhalten, durfte ich garnicht?
Gut, das habe ich dann auch auf dem STM32H750 gemacht, ist Deiner 
geschätzen Aufmerksamkeit aber wohl entgangen.

@Uwe
Seinerzeit hatte ich 'C' verwendet, um bei verschiedenen Controllern 
nicht mehr nachsehen zu müssen, ob nach einem 16-Bit Vergleich das 
carry-Flag nun gesetzt oder gelöscht sein sollte. Gut, beim 68k gab es 
diese Probleme nicht.

Betrachte einen 'C'-Compiler zunächst als einen verbesserten 
Makroassembler, der Dir die ganze Fußarbeit abnimmt. Allein schon 
Vergleiche und Grundrechenarten nicht mehr Byte für Byte codieren zu 
müssen, erleichtert die Arbeit sehr. Es bedeutet ja nicht, daß man es 
nicht kann. Den erzeugten Code sollte man sich im Zweifelsfall auch 
ansehen, ob der Compiler einen auch richtig verstanden hat.

Nimm Dein Problem mit den drei Magneten, die sicherlich nicht in 120° 
Winkeln angeordnet sind. Es ensteht ein wenig Jitter, der unter 
Umständen nicht mehr tolerierbar ist. Allein schon mit Grundrechenarten 
kannst Du hier sinnvoll mitteln oder die 'optimale' Gerade durch die 
Messpunkte legen. In 'C' recht einfach zu formulieren, in Assembler 
unüberschaubar und fehlerträchtig.

von Thomas (kosmos)


Lesenswert?

Mi N. schrieb:
> Thomas schrieb:
>> Falls deine Drehzahl an der Anzeige zu stark hüpft, kannst du einfach zu
>> kleine Änderungen verwerfen. Also wenn die jetzige Drehzahl zur letzten
>> ermittelten weniger als 20 U/Min abweicht, dann schickst du die neuen
>> Daten eben nicht zur Anzeige. Irgendwann weicht sie dann um 30 U/Min ab
>> und wird wieder aktualisiert.
>
> Bei solchen Vorschlägen sträuben sich mir immer die Nackenhaare, weil
> man damit letztlich immer auf die Nase fällt.

Viele Wege führen nach Rom. Man kann seine Messwerte auch Mitteln oder 
die Refreshrate des Displays runtersetzten.... aber eine springende 
Anzeige hilft meist nichts. Man kann das ja auch beliebig feiner machen 
das +-5 U/Min nichts auf der Anzeige bewirken. Es ist einfach eine 
Möglichkeit ohne viel Programmieraufwand das ganze ruhiger zu bekommen 
und beim nächsten größeren Wechsel ist trotzdem sofort die Genauigkeit 
wieder gegeben, beim Mitteln dauert es eben wieder ein paar Zyklen. Es 
gibt eben nicht nur Vorteile.

Aber gut einem Profi (wahrscheinlich seit dem ersten Tag an) mögen sich 
da eben die Nackenhaare sträuben. Ich kann damit leben.

von Ein T. (ein_typ)


Lesenswert?

Ob S. schrieb:
> Als nachgewiesermaßen völlig Inkompetenter: halt dich raus aus dem
> Funkverkehr. SHUT UP. Und spiel artig weiter mit deinen
> Arduino-Trivialitäten. Da bleibst du innerhalb der Grenzen deine
> Kompetenz.

Nachdem ich nun viele Deiner "Beiträge" in diesem und anderen Threads 
gelesen habe, frage ich mich, ob Du auch nur ein Hundertstel so gut 
bist, wie Du mit Deinem penetranten Gepöbel suggerieren willst. Bisher 
kann ich mich nämlich leider an keinen einzigen konstruktiven Beitrag 
von Dir erinnern, und auch hier kommt ja wieder einmal nichts Sinnvolles 
von Dir, nur Pöbeleien und eine große Klappe. Offensichtlich hast Du es 
nötig.

von Gerhard H. (hauptmann)


Lesenswert?

Mi N. schrieb:
> Allein schon Vergleiche und Grundrechenarten nicht mehr Byte für Byte
> codieren zu müssen, erleichtert die Arbeit sehr.

Die alleine sind kaum das Problem. Die paar Instruktionen sind kaum der 
Rede wert und tägliches Brot. Für diverse Operationen und 
Konvertierungen liegen passende Codeschnipsel parat.

Umfangreiche Berechnungen jedoch, insbesondere mit sehr großen oder 
kommabehafteten Zahlen, werden in Asm schnell stupide und 
unübersichtlich. Nur hat man die längst nicht in jedem Programm. Und 
wird sie je nach Leistungsanforderung bereits auf stärkerer 32bittiger 
Hardware implementieren, die sowieso kaum noch für Assembler infrage 
kommt.

Wieviel Mühe etwas macht hängt entscheidend von Wissen und Erfahrung ab. 
Die Gegenseite zu betrachten ist dabei für den Nur-Hochsprachler 
zuweilen genauso unverständlich wie umgekehrt.

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Carsten-Peter C. schrieb:
> mir ist aufgefallen, das Du in der ISR keine Register sicherst. Das wird
> nicht funktionieren.

Ob so etwas funktionieren wird oder nicht, hängt von dem Konzept ab, das 
man sich ausgedacht hat – ein AVR hat so viele Register, dass man das 
durchaus auch umgehen könnte, da man ja im Assembler alles andere, was 
in den anderen Programmteilen passiert, auch selbst in der Hand hat und 
die Interrupts in der Ausführung per default nicht verschachtelt werden; 
das Statusregister muss allerdings immer gerettet werden, leider dann 
auch über ein Hilfsregister, da hier im Befehlssatz der direkte Befehl 
dafür fehlt – entweder gab es dafür keine Kombination in der 
Befehlsmatrix mehr oder man musste an den Abmessungen des Silizium-Dies 
sparen. So etwas kann aber auch schnell in die Hose gehen, wenn das 
Programm nach und nach wächst und man später vergisst, was man sich in 
puncto Registerverwendung hier und dort so vorgenommen hat – so einen 
Fehler zu finden wird dann auch schwierig, weil er unter Umständen nicht 
immer passieren wird, deswegen sollte man sich am besten von Anfang an 
angewöhnen, die angetasteten Register auch fachgerecht auf dem Stapel 
alle vorher zu retten und in umgekehrter Reihenfolge am Ende eines 
Interrupts entsprechend wiederherzustellen. Da die Hälfte der Register 
eines 8-Bit-AVRs etwas eingeschränkt in der Verwendung ist, kann man 
später doch relativ schnell in die Versuchung kommen, etwas zu 
verwenden, was man sich vorher woanders als Tabu in der Verwendung 
selbst vorgeschrieben hat, oder man muss das Konzept und das ganze bis 
dato geschriebene Programm dann komplett abändern/umbauen, was wieder zu 
zusätzlichen Fehlern führen kann – deswegen lieber gleich alles nach dem 
Schulbuch machen, wie der Silizium-Gott es vorgesehen hat, insbesondere 
dann, wenn man bedenkt, dass es oft nur 3-5 Register sind, die man 
retten muss und der Compiler in C einem in der Interruptroutine manchmal 
eine absurde Rettungs-Orgie veranstaltet und gleich 10-16 einfach so per 
default in einer bestimmten Optimierungsstufe rettet und am Ende das 
alles wieder umgekehrt wiederherstellt, obwohl das so gar nicht nötig 
wäre. Die zusätzlichen 6-12 CPU-Takte, die man für das Retten der paar 
Register innerhalb einer in Assembler selbstgeschriebenen 
Interruptroutine opfern muss, kann man in den meisten Fällen auch 
problemlos verschmerzen und entgeht so den ganzen Fallen, die überall so 
lauern.

Man kann das Retten der Register auch in normalen Subroutinen verwenden, 
um so der Zerstörung der Inhalte vorzubeugen, was sich manchmal als sehr 
praktisch für das Schreiben des Hauptprogramms dann erweisen kann, weil 
man es nicht immer wieder wiederholen muss und auch nicht versehentlich 
irgendwo vergessen kann.

: Bearbeitet durch User
von Gerhard H. (hauptmann)


Lesenswert?

Gregor J. schrieb:
> Konzept .. , das man sich ausgedacht hat – ein AVR hat so viele Register

Und weil das so ist kann man es sich in Asm leisten einzelne Register 
für wiederkehrende Standardaufgaben (etwa zum Backup in Interrupts) in 
allen seinen Programmen gleich zu verwenden. Vorzugsweise sind dafür die 
"minderwertigeren" Register von R2 bis R15 geeignet. Für schnellere 
Interrupts kann man so meist ganz auf PushPop Orgien verzichten.

> Interrupts in der Ausführung per default nicht verschachtelt werden

Diese alten AVRs haben ja nur eine Prioritätsebene, die neueren derer 
zwei.
Braucht man die wirklich wirds natürlich etwas knapper mit verfügbaren 
Backup-Registern und man wird bei einer Interruptsorte das eine oder 
andere PushPop verwenden müssen. Immerhin, in Asm hat man das alles 
selber in der Hand und kann strikt nach wirklichem Bedarf verfahren.

: Bearbeitet durch User
von Carsten-Peter C. (carsten-p)


Lesenswert?

Moin,
ich hab erst später gesehen, das Du nur bei

Counter:
  inc    imp1      ; Sensor-Impuls
  sbic  PinC,1
  rcall  teiler
  reti

das SREG nicht gesichert hast. Mit  in ir, SREG und out SREG, ir  sparst 
Du einen Takt aber blockierst ein Register – kann man so machen.
Gruß
 Carsten

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Gerhard H. schrieb:
> Braucht man die wirklich wirds natürlich etwas knapper mit verfügbaren
> Backup-Registern und man wird bei einer Interruptsorte das eine oder
> andere PushPop verwenden müssen.

Wie ich bereits sagte, lieber nicht den Helden spielen, sondern alles 
schön nach dem Schulbuch machen, damit man nicht versehentlich in 
Teufels Küche kommt, was schneller passieren kann als man denken und 
schreiben kann. Ist am Ende klar, was aus dem Registerfile tatsächlich 
gebraucht oder nicht gebraucht wird, kann man in der Hinsicht immer noch 
etwas im Gesamtkonzept optimieren und anpassen, wenn man sich von Anfang 
an an das Schulbuch gehalten hat – es umgekehrt machen, wird deutlich 
schwieriger und fehleranfälliger.

von Gerhard H. (hauptmann)


Lesenswert?

Gregor J. schrieb:
> lieber nicht den Helden spielen, sondern alles schön nach dem Schulbuch
> machen

Dann verzichtest Du aber auf ein gutes Stück kreativer Lösung die es so 
nur mit Assembler gibt.

Der Ängstliche greift besser gleich zur Hochsprache. Oder beißt sich 
durch und sammelt wertvolle Erfahrung :)

> immer noch etwas im Gesamtkonzept optimieren und anpassen,

Nein, besser nicht. Sondern ein optimales, funktionierendes 
Gesamtkonzept für Standardvorgänge wie Interrupts entwickeln und immer 
wiederverwenden!

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Gerhard H. schrieb:
> Dann verzichtest Du aber auf ein gutes Stück kreativer Lösung die es so
> nur mit Assembler gibt :)

Nein, das tue ich nicht – ich weiß einfach nur, wann es sinnvoll ist, 
auf irgendwelche kreative Lösungen nicht zu verzichten, und wann oder an 
welchen Stellen des Programmms es nicht besonders Sinn macht, unnötig 
„kreativ” zu sein, meistens macht ein Held es auch nur, um sich oder den 
anderen etwas beweisen zu müssen, obwohl es hardwaremäßig gar nicht 
nötig wäre, so etwas zu tun, weil man damit insgesamt ein hohes Risiko 
eingeht, sich schwer zu findende Fehler zu generieren. Den Helden 
spielen geht dreimal gut und einmal dann voll in die Hose – ich hoffe, 
es passiert einem Helden dann bei einem Projekt, das extrem wichtig war 
und bei dem Zeitknappheit vorherrscht, um alles korrigieren zu können, 
damit er es lernt, solche Dinge richtig einordnen zu können und damit er 
den Ball künftig einfach mal lieber flachhält.

von Gerhard H. (hauptmann)


Lesenswert?

Gregor J. schrieb:
> damit er den Ball künftig einfach mal lieber flachhält

... am besten in Hochsprache :)

Aber Du hast Recht, letztlich zählt das Ergebnis. Dem erwartungsgemäß 
funktionierenden Produkt sieht man die mehr oder weniger schlaue 
Codeausführung und den Speicherverbrauch nicht an.
Der Spielraum für mehr Effizienz kann hier oder da noch besser sein, 
doch was soll's. Alles entscheidend ist doch, daß das Hobby Spaß 
macht. Ob man's glaubt oder nicht!

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Uwe schrieb:
> Ich bin das Programm mehrere Male in "Einzelschritten" durchgegangen und
> habe die Werte in den Registern überprüft. Keine Fehler. Aber mal die
> Timereinstellungen zu kontrollieren, auf die Idee bin ich nicht
> gekommen. Ist ja schon peinlich. Jetzt läuft alles Super.

Läuft es jetzt wie es soll? Wegen der fehlenden Sicherung von SREG ja 
kaum vorstellbar.

> Ich habe da aber noch eine Denkaufgabe: Ich überprüfe das Eingangssignal
> mit einem Oszi, und das zeigt mir eine Frequenz von z.B. 70Hz an. Mein
> Drehzahlmesser zeigt 700 U/min an (das enspricht 70 Impulse je sek). Das
> Oszi zählt doch die Frequenz von einer HL-Flanke zur nächsten HL-Flanke.
> Der PCint dagegen löst aber bei jeder Flanke aus. Sollte ich da nicht
> 140 Interrupts haben? Und dann ist da noch der vorige Beitrag von S.L. -
> das sind ja wieder ganz andere Werte.

Oder sind 'ganz andere Werte' noch ein Zeichen für Fehlfunktion?
Da sich der TO nicht mehr gemeldet hat, ist es müßig, hier weiter zu 
diskutieren. Aus Jux mal den Assembler 'anzuwerfen', kann ich mir dann 
auch verkneifen.

von Helmut H. (helmuth)


Lesenswert?

Mi N. schrieb:
> Wegen der fehlenden Sicherung von SREG ja
> kaum vorstellbar.

Fällt doch nur auf wenn ein Int z. B. während der 8 CPI oder direkt vor 
den 2 ADC oder 2 ROL auftritt, im Interrupt-Handler das entsprechende 
Flag geändert wird und Mensch aufs Display schaut.

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Helmut H. schrieb:
> Fällt doch nur auf wenn ein Int z. B. während der 8 CPI oder direkt vor
> den 2 ADC oder 2 ROL auftritt, im Interrupt-Handler das entsprechende
> Flag geändert wird und Mensch aufs Display schaut.

Auch wenn so ein Fehler sehr selten passieren sollte, z.B. nur einmal 
zufällig in der Stunde oder einer Woche, ist dann die ganze Arbeit mit 
der Assemblerschreiberei Murks gewesen, war quasi alles umsonst, eine 
vergebliche Liebesmüh. Liegt meistens daran, dass jemand die Grundlagen 
der µProzessortechnik nicht kennt und somit auch nicht weiß, was da so 
zum jeweiligen Zeitpunkt intern im Prozessor vor sich geht und passiert. 
Ergo und die gleichzeitig von mir bereits mehrfach oben abgesandte, 
wichtigste Botschaft an alle kreativen Helden dieser Welt => alles 
lieber nach einem Schul- bzw. Fachbuch – und zwar nicht nur mit SREG, 
sondern mit allen angetasteten Registern – machen und wie sich das 
gehört auch ordentlich den Stack dafür verwenden, dann passiert genau so 
etwas erst gar nicht. Ein Assemblerprogramm muss zu 100% sicher sein, 
ein kleiner Denk- oder Tippfehler, z.B. auch bei der Reihenfolge der 
PUSH/POPs, und es wird zu einem unkontrollierten Irgendwas, was man als 
ein funktionsfähiges Programm leider nicht mehr bezeichnen kann.

: Bearbeitet durch User
von Gerhard H. (hauptmann)


Lesenswert?

Gregor J. schrieb:
> die gleichzeitig von mir bereits mehrfach oben abgesandte, wichtigste
> Botschaft an alle kreativen Helden dieser Welt => alles lieber nach
> einem Schul- bzw. Fachbuch – und zwar nicht nur mit SREG, sondern mit
> allen angetasteten Registern – machen und wie sich das gehört

Jetzt wirst Du mir aber langsam zum Helden der Langweiligkeit und des 
starren Kästchendenkens. Nein, ich werde weder nach "Schulbuch"- noch 
nach Deinen Vorgaben verfahren und mich irgendwie beim größten kreativen 
Vorteil von Assembler einschränken lassen den es gibt: Seiner 
Flexibilität und totalen Freiheit.

Du müsstest im Übrigen auch mal lernen, einen Unterschied zwischen 
Anfängern und Fortgeschrittenen zu machen. Da findet durchaus eine 
Entwicklung statt. Nachdem mein Spaß beim Programmieren weiter gegeben 
ist werde ich dabei schon nicht allzuviel falsch machen! Nach einiger 
Zeit kommt da nämlich die Phase, wo Du bei solch "primitiven" Dingen wie 
der Registerverwendung/ Sicherung kaum noch Fehler machst- sondern nur 
noch dort wie überall in beliebigen Sprachen: In Algorithmen und 
logischem Programmablauf. Und in der Reaktion auf unvorhergesehene 
Einflüsse in der Praxis, z.B. Störungen, ungewöhnliche Messwerte und 
besonders ungeplante Zeitverzögerungen + Prioritäts-Einordnungen.

Mehr als 99% der banalen Tippfehler sortiert inzwischen der 
Build-Prozess aus. Sollte man sich tatsächlich mal im Register geirrt 
haben ist das nach intensiver Kontrolle wie bei anderen Fehlern auch: 
Zum Ziel führt eine methodische Fehlersuche, die den Programmablauf in 
abgrenzbare Teilprobleme zerlegt und einzeln testet. Gut macht sich 
immer der regelmäßige Blick auf den Speicher mit einem Debugger. Ob 
Resultate so sind wie sie sein sollen. Da kann man ruhig mal die eine 
oder andere Speicherstelle zusätzlich für investieren. Zum Ziel führt 
insbesondere ein genereller Plan in der Register-Verwendung, der 
weitestgehend gleich bleibt. Meinen habe ich gefunden. Daneben geht es 
um eine gewisse Systematik im Programmaufbau- wiewowann welche Aufgaben 
organisiert werden.

Um unnötige Fehler gar nicht erst entstehen zu lassen empfielt sich, 
Programmieren weder in Stresssituationen noch abgelenkt oder übermüdet 
zu betreiben und so seinen Code hinterher womöglich zeitaufwendig 
bereinigen zu müssen. Binsenweisheiten zwar, aber immer wieder gerne 
vernachlässigt!

: Bearbeitet durch User
von Peter (pittyj)


Lesenswert?

Ich habe lange nicht so viel Blödsinn gelesen, wie in diesem Thread.

Ich mußte letztens auch eine Drehzahlmessung in eine existierende 
Maschinensteuerung einbauen. Einmal auf einem NXP11, parallel auf einem 
STM32H Prozessor. Das habe ich mit C++ erledigt. Das gesamte Framework 
ist schon C++. Dieses stellt mir auch einen Microsekunden-Timer zur 
Verfügung, weil ich den auch für andere Zeitmessungen brauche.
Also Interrupt aufgesetzt. Im Interrupt wird das Timer-Objekt (C++) 
abgefragt, und daraus eine Differenzzeit gebildet. Die RPMs werden 
ausserhalb des Interupts beim normelen Arbeiten berechnet.

Es geht also auch in einer Hochsprache. Meine Hochsprache ist lesbar und 
portabel, denn der NXP-Code compiliert exakt so auch auf dem STM. Alles 
war in einem Arbeitstag erledigt.

Ich kann die Assembler Prediger hier nicht verstehen. Assembler habe ich 
vor 40 Jahren programmiert (Z80, 68000, Vax) . Aber heute brauche ich 
etwas, was wartbar ist, und wo Kollegen in endlicher Zeit sich 
einarbeiten können. Und um Registersicherung soll sich der Compiler 
kümmern. Das will ich nicht mehr machen, viel zu fehleranfällig.

von Mi N. (msx)


Lesenswert?

Gregor J. schrieb:
> Helmut H. schrieb:
>> Fällt doch nur auf wenn ein Int z. B. während der 8 CPI oder direkt vor
>> den 2 ADC oder 2 ROL auftritt, im Interrupt-Handler das entsprechende
>> Flag geändert wird und Mensch aufs Display schaut.
>
> Auch wenn so ein Fehler sehr selten passieren sollte, z.B. nur einmal
> zufällig in der Stunde oder einer Woche, ist dann die ganze Arbeit mit
> der Assemblerschreiberei Murks gewesen, war quasi alles umsonst, eine
> vergebliche Liebesmüh.

Bei Deinen klugschwafeligen Schwätzereien ist Dir die Ironie dieser 
Aussage völlig entgangen.

von Gerhard H. (hauptmann)


Lesenswert?

Peter schrieb:
> Einmal auf einem NXP11, parallel auf einem STM32H Prozessor. Das habe
> ich mit C++ erledigt. Das gesamte Framework ist schon C++.

> Es geht also auch in einer Hochsprache

Selbstverständlich Peter.
Auf diesem Hardware-Level geht es eigentlich nur so.
Gepflegt überlesen hast Du, um welche Sorte einfacher Controller sich 
dieser Thread dreht. Da stehen mehr Optionen offen.

> und wo Kollegen in endlicher Zeit sich einarbeiten können

Im Hobby ist das weit weniger relevant.
Dennoch: Je einfacher die Hardware desto mehr Leute können auch bei 
Asm-Texten noch helfen.

Hochsprache entfremdet von der Hardware.
Spannt ihr ganz eigenes Universum auf.
Man weiß, wie lernintensiv sie werden kann.
Das steht nun im richtigen Verhältnis zu den damit entwickelten 
Projekten und lohnt den Aufwand- oder tut es nicht.
Man mag sie - oder mag sie nicht.
Wie schön, daß wenigstens das Hobby frei von allen ideellen Zwängen 
bleibt.

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Peter schrieb:
> Es geht also auch in einer Hochsprache. Meine Hochsprache ist lesbar und
> portabel, denn der NXP-Code compiliert exakt so auch auf dem STM. Alles
> war in einem Arbeitstag erledigt.
>
> Ich kann die Assembler Prediger hier nicht verstehen. Assembler habe ich
> vor 40 Jahren programmiert (Z80, 68000, Vax) . Aber heute brauche ich
> etwas, was wartbar ist, und wo Kollegen in endlicher Zeit sich
> einarbeiten können. Und um Registersicherung soll sich der Compiler
> kümmern. Das will ich nicht mehr machen, viel zu fehleranfällig.

Genau so ist es und so mache ich es heute auch, was ich ganz am Anfang 
auch schon kommuniziert habe, alles andere ist heute einfach nicht mehr 
zielführend/zeitgemäß und wer von den „kreativen Helden” auf die Idee 
kommen sollte, etwas für die STM32 in Assembler schreiben zu wollen, der 
wird – abgesehen davon, dass man sich so etwas gar nicht erst antun 
sollte – hier deutlich schneller scheitern und bestraft werden als es 
mit dem relativ einfachen Assembler für einen 8-Bit-AVR der Fall wäre. 
Es gibt Dinge im Zusammenhang mit dem Assembler für STM32, die nur in 
den Dokus wie z.B. den Erratas stehen und die der Compiler deswegen bei 
der Codegenerierung explizit nicht machen wird, weil er mit diesen 
Informationen der Hersteller gefüttert worden ist und es weiß; jemand, 
der das Schreiben des Assemblerprogramms selbst in die Hand nimmt und 
keine Kenntnis davon hat, wird diese fehlerbehafteten Befehle irgendwann 
mal verwenden. Und wer tatsächlich den 8-bit-AVR-Assembler lernen will, 
der sollte die Sache ganz anders angehen, sich vor allem die Grundlagen 
aneignen, die in den Fachbüchern zu finden sind, um unter anderem 
erfahren zu können, wofür die Konstrukteure den Stapelspeicher erfunden 
und entworfen haben, was hier im Thread das Scheitern in voller Breite 
auch erklärt.

: Bearbeitet durch User
von Gerhard H. (hauptmann)


Lesenswert?

Gregor J. schrieb:
> Es gibt Dinge im Zusammenhang mit dem Assembler für STM32, die nur in
> den Dokus wie z.B. den Erratas stehen und die der Compiler deswegen bei
> der Codegenerierung explizit nicht machen wird

Kurze Nachfrage:
WER hat hier Assembler als Projekt-Sprache für STM32 empfohlen?

> wofür die Konstrukteure den Stapelspeicher erfunden
> und entworfen haben

Halte Dich bitte dran.
Erkläre nur nicht anderen mit etwas mehr Fantasie, was sie tun dürfen.

von Uwe (swed24)


Lesenswert?

Hallo,
ich war jetzt 2 Wochen lang nicht hier und die Flut an Beiträgen ist 
schon gewaltig. Einiges Nützliches aber auch vieles, was mit dem Thema 
nichts zu tun hat. Leider.
Das Programm läuft jetzt super. Es war noch ein saublöder Fehler von 
mir. Ich arbeite vorrübergehend mit dem Arduino Uno und war der Meinung 
(warum auch immer) das das mit einem 8 MHz Takt arbeitet. Das Teil hat 
aber einen 16 MHz Quarz on Board (steht ja gross drauf). Ich habe die 
Timer1-Einstellungen noch einmal geändert. Das war's. Hab jetzt auch das 
SREG im "Counter Interrupt" gesichert. Danke für alle Sinnvollen 
Beiträge !
Gruss  Uwe

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Uwe schrieb:
> Das Teil hat
> aber einen 16 MHz Quarz on Board (steht ja gross drauf).

Der originale UNO hat einen Quarz für den ATMEGA16U2, nicht für den 
ATMega328P.
Der muss mit einem Keramikresonator auskommen. Und der hat eben 
(meistens?) keine Beschriftung.
Somit vermute ich, dass du die falsche Stelle untersucht hast, aber 
trotzdem, aus versehen, zu einem brauchbaren Ergebnis gekommen bist.

Tipp:
Der Weg in die Hölle ist mit falschen Annahmen gepflastert.

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.