Hi ich hab ein Problem. Ich besitze nur recht einfache kenntnise in Assambler, muss aber für einen Prüfaufbau einen Zähler programmieren der eben bis auf max. 1 Mio. zählen kann und dann einen Ausgang schaltet. Die Ab-/Schaltgrenze muss einstellbar sein. Nun hab ich echt keine ahnugn wie ich das realisieren kann. Könnt ihr mir bitte helfen?? Hat vlt schon jemand da was gemacht?? MfG Eddy
Man nehme einen atmega8. konfiguriert den Timer so das der Zähltakt von ausen kommt. Dan macht man einen Interrupt beim Wert z.B. 50000 und wartet bis dies 20mal passiert ist und schlatet dann den Pin. Das dürften in c so max 40Zeilen Code sein ;-) (PS: jetzt halten bitte alle Trolle ihre Fresse zum Thema Zeilenlänge!!!!!!!!!!!!)
In C würde man ein long-Variable nehmen, in Assembler steht es dir frei, nur 3 Bytes zu benutzen . 2^24 >16Mio, reicht also. Im Prinzip hast du zwei kleine Probleme: 1. Zähler Du addierst zum kleinsten Byte (sagen wir mal der Einfachheit halber r16) eine Eins. Falls Übertrag, auch das nächste Byte um eins erhöhen Falls dort Übertrag, auch 3.Byte erhöhen Damit ist der Zähler schon erledigt. Der nächste Teil: Vergleich. Geht im Prinzip genauso, allering ziehst du deinen Vergleichswert nur virtuell ab, am Ende hast du ein Ergebnis, <,= oder >. Weiss ich nicht mehr so genau, wie das in Assembler ging, mit cp und cpc jedenfalls auch über mehrere Bytes. Bei Atmel gibts da einiges drüber.
Zuwenig Info. Wie soll der Schalt-Zählerstand eingegeben und angezeigt werden? Soll der laufende Zählerstand angezeigt werden, wenn ja, wie? Woher kommt das Zählsignal, wie schnell ist es, muss es entprellt werden? Das ist mit einem Mega8, einem LCD, einem Tastenblock recht gut realisierbar, mit 20 Zeilen Assemblercode (ein Befehl + Kommentar pro Zeile) packe es aber nicht, dazu bin ich zu unerfahren. ...
Wenn der Vergleichswert oft geändert werden muss bieten sich digitale Vorwahlschalter (Daumenradschalter) für die Eingabe an.
Dieter Werner wrote: > Wenn der Vergleichswert oft geändert werden muss bieten sich digitale > Vorwahlschalter (Daumenradschalter) für die Eingabe an. Ja sicher ist die Eingabe mittels Drehgeber (mit Tastfunktion zur Digitauswahl) möglich. Alternativen wäre auch ein 12er Tastenblock (Pollin) mit ein paar Widerständen am ADC-Eingang oder 4 Menütaster (up, down, left, right) mit Dannegger-Entprellung an Portpins. Doch meine Nachfrage richtete sich an den Threadstarter, er muss entscheiden, was er will. ...
Hannes Lux wrote:
> dazu bin ich zu unerfahren.
@Hannes: Argh, immer deine Bescheidenheit! ;)
Simon Küppers wrote: > Hannes Lux wrote: >> dazu bin ich zu unerfahren. > > @Hannes: Argh, immer deine Bescheidenheit! ;) Bescheidenheit ist eine Zier sie steht auch dir ;) @Hannes: Hab leztens mal deine Schaltung zum Melodiegenerator aufgebaut (allerdings mit BC847/48 und eigenem Programm) funzt ganz gut!
Läubi Mail@laeubi.de wrote: > Bescheidenheit ist eine Zier sie steht auch dir ;) Guter Spruch, aber dass der bei Simon zutrifft, wage ich zu bezweifeln. > @Hannes: Hab leztens mal deine Schaltung zum Melodiegenerator aufgebaut > (allerdings mit BC847/48 und eigenem Programm) funzt ganz gut! Naja, "Schaltung" kannst Du das nicht nennen. ;-) Den Melodiegenerator habe ich immer noch nicht real aufgebaut, den gab's nur auf dem Steckbrett. Das war auch nur eine Spielerei. So richtig praxistauglich (Batteriebetrieb) ist das Ding aufgrund des nicht zu vernachlässigenden Sleep-Stroms des Tiny15 auch nicht. Ich habe die Sache auch nicht weiter verfolgt, da ich ein bedeutend besseres Projekt mit Tiny45 und DDS gesehen habe. ...
Also ich hab nen Atmel AT89C51ED2. Das Signal muss vlt entprellt werden aber das stellt sich erst bei einem Testlauf heraus. Die Zählgeschindigkeit ist max. 2 klicks pro Sekunde, sollte also keine größere Probleme bereiten. Das ganze sollte nach möglcihkeit von der eingestellten Zahl rückwerts auf einem LCD (2x16) angezeigt werden. Die Zahl kann momentan noch einfach im PC eingetippselt werden und dann die Hey in die CPU laden. Aber auf weite sicht wäre es besser wenn man die zahl über ein "Mäuseklavier" einstellen könnte. So in der Art von z.B. einzustellende zahl: 432.100 ; Erste und zweiter Schiebetaster = 0 Betätigungen ; Dritter Schiebetaster 1-mal On/Off schalten ; Vierter = 2-mal On/off etc. so das quasi immer mit der steigenden flanke der Wert gegeben wird. Aber das ist noch ncith so dringend. MfG DasZissel
Bei Mega8 (oder Mega48), Tastenblock und LCD wäre ich dabeigewesen, bei 8051 aber nicht. Viel Erfolg... ...
@crazy horse Also das mit dem Zählen hab ich verstanden aber das mit dem vergleich noch nicht so ganz...
@ Eddy (Gast) >Also das mit dem Zählen hab ich verstanden aber das mit dem vergleich >noch nicht so ganz... Das Zauberwort heisst Arithmetiki mit Überlauf. Dabei werden grosse Zahlen, welche die Registerbreite der CPU überschreitenin mehreren Variablen gespeichert. Beim Rechnen (Addieren, Subtrahieren) rechnet man wie per Hand auf Papier. 23 +19 ---- 9+3 = 12, schreibe 2 merke 1 1+2+1(gemerkt) = 4, merke 0 Ergebnis : 41 Das gleiche macht man in Assembler. Siehe hier. http://www.mikrocontroller.net/articles/AVR_Arithmetik Siehe Addititon/Subtraktion 32-32(Bit) Das Prinzip ist überall gleich, allerdings hier für den AVR demonstriert. Die 8051 haben ähnliche Befehle, mit denn man das auch machen kann. Vergleichen tut man per Subtraktion. A - B Ist das Ergebnis grösser Null (Carry Flag NICHT gesetzt) ist A > B Ist das Ergebnis gleich Null (Zero Flag gesetzt) ist A = B Ist das Ergebnis kleiner Null (Carry Flag gesetzt) ist A < B MFG Falk
Ich frage mal so blöd dazwischen: Zählinpulse von aussen sind schön und gut, aber wozu d. ganze HW-Aufwand? Hier scheinen alle von linearen Zählregistern besessen zu sein, wieso nicht dann etwas geschickter programmieren? Nimmt doch einfach einen Register eurer Wahl, zählt hoch z.B. 5-mal und dann wieder 4 runter. Wieder 5 hoch, wieder 4 runter...... Über das Verhältnis beider Zahlen kann man so ziemlich alles zählen.... Feineinstellung: alle 10 Perioden o.ä. ein anderes Zahlenverhältnis nehmen. Wenn das immer noch nicht reicht, kann man mit dieser Methode auch in Potenzen rechnen. (2 hoch, 1 runter, 3 hoch, 2 runter, 4 hoch 3 runter z.B.) --> Prinzip Reihenentwicklung, Fourier und Kumpels lassen grüssen Für die Programmierung in C reichen im Normalfall 2-3 Zählvariablen und ebenfalls 2-3 verschachtelte For- Schleifen. Sollte kein Problem sein..... Geschickter ist das Ganze in asm zu realisieren, da man hier einiges Zusammenfassen kann. Mit 40 Zeilen Code kommt man locker hin, und das ohne externe HW. Nur so als Denkanstoss.
@Steffan: Gut dein Zähler wird +11 mal inkrementiert und dann -10 dekremetiert. Er hat den Wert +1, wie gehts dann deiner Meinung nach weiter ? Also aus meiner Sicht ist das was du vorschlägst totaler Mist, warum nicht in einem 24 Bit Zähler immer +1 hochzählen ? >Wenn das immer noch nicht reicht, kann man mit dieser Methode auch in >Potenzen rechnen. (2 hoch, 1 runter, 3 hoch, 2 runter, 4 hoch 3 runter >z.B.) --> Prinzip Reihenentwicklung, Fourier und Kumpels lassen grüssen Jo, warum nicht gleich mit komplexen Zahlen Fourierreihen hochzählen lassen ? >Für die Programmierung in C reichen im Normalfall 2-3 Zählvariablen und >ebenfalls 2-3 verschachtelte For- Schleifen. Sollte kein Problem >sein..... Klar, man könnte auch einen 24 Zeichen langen String definieren und jedes Zeichen in 24 Schleifen hochzählen lassen. Oder man nimmt 24 * 24 Zeichenstring und zählt sowas in 24*24 Schleifen hoch. Man könnte aber auch auf einem binären Rechner einfach 24 Bits aneinanderhänge, was 3 Bytes ergäbe und mit 3x ADD/ADC den Mist um +1 inkrementieren, ganz ohne komplexe Zahlen und Fourierreihenentwicklung die mit 24*24 Zeichen langen String ihre Zahlen abspeichern. Es sei denn, ich habe den Witz in deinem Posting nich bemerkt :) Dann LOL. Gruß Hagen
>Nimmt doch einfach einen Register eurer Wahl, zählt hoch z.B. 5-mal und >dann wieder 4 runter. Wieder 5 hoch, wieder 4 runter...... Über das >Verhältnis beider Zahlen kann man so ziemlich alles zählen.... >Feineinstellung: alle 10 Perioden o.ä. ein anderes Zahlenverhältnis >nehmen. ??? Ich hab nicht verstanden, wie das funktionieren soll. Kannst Du es mal genau erklären? Danke im Voraus.
Stefan wrote: > Nimmt doch einfach einen Register eurer Wahl, zählt hoch z.B. 5-mal und > dann wieder 4 runter. Wieder 5 hoch, wieder 4 runter...... Über das > Verhältnis beider Zahlen kann man so ziemlich alles zählen.... > Feineinstellung: alle 10 Perioden o.ä. ein anderes Zahlenverhältnis > nehmen. Hä? Wovon sprichst du? Wenn ich ein Register um 1 erhöhen will, dann zähle ich 1 dazu und nicht erst 5 hoch und dann 4 runter. Oder hab ich da nicht verstanden worauf du hinauswillst.
Schreib Dir erstmal alle Funktionen, die Du brauchst auf und mache nen Ablaufplan, z.B.: -Zahlenausgabe -Zahleneingabe -entprellen -zählen -vergleichen -schalten usw. Wenn die Funktionen zu komplex sind, dann unterteile sie weiter, z.B.: Zahlenausgabe: -binär-dezimal Wandlung -7-Segment Wandlung -Timerinterrupt -Multiplexausgabe usw. Und dann erst kannst Du den PC einschalten und programmieren. Wer Programmieraufgaben als einen großen monolithischen Block ansieht, kommt nie voran (also teile und herrsche). Peter
Sag mal, wie machst du dass wenn du weiter als 5 zählen willst? Geheimtipp: nimm die zweite Hand dazu. Und wie könnte das jetzt wohl funktionieren, wenn du weiter als 255 Zählen willst? /Ernst
:-) Interessante Reaktionen Es war eigentlich ein Scherz für Fortgeschrittene :-) Rumgetrolle war es jedoch nicht, nur eine etwas andere Art der Programmierung. Funktionieren würde es durchaus.Nur nicht auf einem AVR. (Na ja, selbst da würde es laufen, aber wer verschwendet schon einen uC darauf, in einem Register rumzurechnen, wenn alle anderen Register brach liegen?) Auf einem Multicore macht aber soetwas manchmal durchaus Sinn. Einen entsprechenden Programm habe ich für einen Parallax Propeller geschrieben, dort stört es ja nicht, wenn ein Core mal beschäftigt ist, 7 weitere warten ja immer noch auf Arbeit. Dafür geht aber nur ein Register weg für die Zählerei. Gut, die Zahlen waren in der Anwendung wirklich sehr gross, da haben auch die 32-bit Register aufgegeben in der "traditionellen" Ansteuerung. --> Problem: Zählen bis 1 Mio. mit EINEM 8 bit Register ohne externe HW und ohne Timer. Also zum Vorgehen: - Init: Register auf 0 setzen - 5 mal in 1-er Schritten hochzählen (5 Takte) - 4 mal in 1-er Schritten runterzählen (5 Takte) - Registerinhalt : 1 nach 10 Takten - 5 mal in 1-er Schritten hochzählen (5 Takte) - 4 mal in 1-er Schritten runterzählen (5 Takte) - Registerinhalt: 2 nach 20 Takten --> die Kombination 5 hoch 4 runter ist eigentlich ein Prescaler 1:10 andere Zahlenkombinationen ergeben andere Teiler. @Ernst: ja, wenn man das Prinzip verstanden hat, kann man damit auch weit über 255 Takte Zählen, selbst mit einem 8 bit Register. Das sind schon eine Menge Hände, da hilft die zweite Hand auch nicht mehr viel. Eine Spezialfrage mal an dich: wie weit kann man mit dieser Methode denn mit einem 8-bit Register maximal zählen? Geheimtipp: Oben ist nur eine Ebene dargestellt, die Zeile "Registerinhalt" kann man ja wieder als eine Variable auffassen, der 6 mal hochzählt und dann 5 mal runter... Und wenn das nicht reicht, kommen halt nochmal 20 Ebenen hinzu. Alles in sich verschachtelte For- Schleifen... Gruss: Stefan
So aber wie erkennst du das du 5 mal hochgezählt hast OHNE ein weiteres Register zu benutzen ? Das was du vorschlägst geht nur mit einem zweiten Register das man bis 5 zählt und dann auf 0 zurücksetzt. Wie dämlich ist das ? So verschwendest du wertvolle Bits. Denn ideal wäre es dann das Register bis 255 + Überlauf hochzuzählen und dann den Überlauf in ein weiteres Register zu propagieren. Das ist dann nichts anderes als wenn wir einen 24 Bit Zähler aus 3 Bytes zusammensetzen und das MSB inkrementieren und die Überlüfe in die höherwertigen Bytes propagieren. Es gibt nur eine Außnahme bei der sowas Sinn macht -> BCD Darstellung um später die Umwandlung in der Anzeige auf einem LCD zu vereinfachen. Sprich ohne Divisionen auskommen zu können. Gruß Hagen
Zitat Hagen: So aber wie erkennst du das du 5 mal hochgezählt hast OHNE ein weiteres Register zu benutzen ? Das was du vorschlägst geht nur mit einem zweiten Register das man bis 5 zählt und dann auf 0 zurücksetzt. Wie dämlich ist das ? So verschwendest du wertvolle Bits. ___________________________________ Gegenfrage: bist du dir wirklich ganz sicher, dass du dafür einen Register brauchst??? Gruss: Stefan
Na aber sicher Am Anfang steht 0 drinnen, +5 = 5, nun -4 steht im register +1. Nun nochmals +5 inkrementieren steht +6 drinnen. Du müsstest entweder ein zweites Register haben das zum Vergleich dient und das +5,+6,+7 usw. enthält nach jedem Dekremetieren. Oder ein zweites Register das du immer bis +5 inkrementiert und beim erreichen der +5 auf 0 gesetzt wird und ein zweites Register um +1 inkrementiert. Wie willst du bei deiner Methode mit nur einem Zählregister erkennen bei welcher Zahl zu dekrementieren musst ? Oder du meinst es es ds bei jedem Schritt einmal +5 addiert wird und dann -4 subtrahiert wird. Das ergäbe einen effektiven Inkrementierungsschritt von +1. Warum sollte man aber 2 Operationen durchführen wenn eine +1 Operation ausreicht ? Egal wie ich es drehe und wende, du trollst. Und komme mir nicht mit Parallax Propeller, es ist egal ob man Single oder Multicores hat, die arbeiten alle nach den gleichen Gesetzen. Gruß hagen
:-) Dann ist ja gut, ich brauche kein zusätzliches Register. Allerdings mit einem kleinen Trick in der Codierung der Zahlen. Zugegeben, bei einem 8-bit Register ist mein Vorschlag mit Sicherheit zu kompliziert, aber bei 16-bit oder aufwärts sieht es anders aus. Anyway, wenn du meinst dass ich trolle, nur zu. Jeder hat so sein "way of programming" und irgendwann erreicht man auch die Grenzen dessen. Da ich mich nicht darüber streiten werde, ob das was bei mir in einer konkreten Anwendung läuft überhaupt lauffähig ist, ist die Diskussion hiermit für mich abgeschlossen. Viel Spass noch mit den uC's, und in der Zukunft bloss nichts neues/anderes/unkonventionelles zeigen lassen! Gruss: Stefan
Stop mal, ich bin ja lernfähig und jetzt frage ich dich wie das was du vorschlägst gehen sollte. Es gehört zwar nicht in diesen Thread, da der Fragesteller offensichtlich ein Anfänger ist, und diese Diskussion ihm keinerlei Antworten gibt. >- Init: Register auf 0 setzen >- 5 mal in 1-er Schritten hochzählen (5 Takte) >- 4 mal in 1-er Schritten runterzählen (5 Takte) >- Registerinhalt : 1 nach 10 Takten >- 5 mal in 1-er Schritten hochzählen (5 Takte) >- 4 mal in 1-er Schritten runterzählen (5 Takte) >- Registerinhalt: 2 nach 20 Takten Erkläre mir wie du erkennst das du 5mal in 1-er Schritten hochgezählt hast ohne dafür ein weiteres Register zu verbrauchen ? Gruß Hagen
>Erkläre mir wie du erkennst das du 5mal in 1-er Schritten hochgezählt >hast ohne dafür ein weiteres Register zu verbrauchen ? So ganz klar ist es mir auch noch nicht, aber ich glaub, es läuft darauf hinaus, dass bei dieser Methode der Program Counter (!) eines Prozessorkerns des Propeller Chips als "verstecktes" weiteres Zählregister fungiert. Die zu zählenden Impulse takten diesen Kern, der dann auch keine weiteren Aufgaben mehr wahrnehmen kann, weil sonst Zählinformation verloren ginge. @Stefan: Einigermaßen Richtig? ;-)
Ja gut, nun klabüsern wir das für ein Single Core System auseinander und schon haben wir 2 Register und 1 Core statt 2 Cores mit jeweils 1 Register. Einen Core für sowas zu benutzen ist ja noch mehr Verschwendung als mit 2 Registern in einem Core zu arbeiten die dort immer +1 inkrementert werden, also so wie es alle anderen Programmierer auch machen, einen 16/24 Bit Zähler aufbauen. Gruß Hagen
Das ist weder neu noch unkonventionell, sondern einfach nur eine komplizierte Schreibweise für
1 | nop; nop; nop; nop; nop; nop; nop; nop; nop; inc register |
Man zählt langsamer, das ändert aber nichts daran dass man nur bis 255 zählen kann.
Man dann stelle ich den Prescaler des T1 Taktes des Timers so ein das ich nur jeden 10 Impuls zähle. Noch komplizierter als mit 2 Cores zu arbeiten gehts wohl nicht ? Kann es sein das der Parallax keinen Zähler mit rescaler bestzt ? Gruß Hagen
Stefan wrote: > Also zum Vorgehen: > > - Init: Register auf 0 setzen > - 5 mal in 1-er Schritten hochzählen (5 Takte) > - 4 mal in 1-er Schritten runterzählen (5 Takte) > - Registerinhalt : 1 nach 10 Takten > - 5 mal in 1-er Schritten hochzählen (5 Takte) > - 4 mal in 1-er Schritten runterzählen (5 Takte) > - Registerinhalt: 2 nach 20 Takten Registerinhalt aber auch 2 nach 11 Takten. > > --> die Kombination 5 hoch 4 runter ist eigentlich ein Prescaler 1:10 Auch wenn es der OP nicht explizit gesagt hat, denke ich nicht, dass er CPU Takte zählen will.
>nur eine etwas andere Art der Programmierung. Nein, keine "andere Art der Programmierung", sondern ein ALGORITHMUS. >Funktionieren würde es durchaus. "Würde"? >Nur nicht auf einem AVR. Woher weißt Du das? >(Na ja, selbst da würde es laufen, [...] Also doch? Du widersprichst Dir? >[...] aber wer verschwendet schon einen uC darauf, in einem Register >rumzurechnen, wenn alle anderen Register brach liegen?) Das ist kein Argument, weil die Frage prinzipieller Natur ist. >Auf einem Multicore macht aber soetwas manchmal durchaus Sinn. >Einen entsprechenden Programm habe ich für einen Parallax Propeller >geschrieben, Mich würde der relevante Teil des Codes sehr interessieren. >dort stört es ja nicht, wenn ein Core mal beschäftigt ist, >7 weitere warten ja immer noch auf Arbeit. Wieso? Sie könnten doch schon mit anderen Aufgaben ausgelastet sein. >Dafür geht aber nur ein Register weg für die Zählerei. Die Worte hör ich wohl, allein mir fehlt der Glaube. >Gut, die Zahlen waren in der Anwendung >wirklich sehr gross, da haben auch die 32-bit Register aufgegeben in der >"traditionellen" Ansteuerung. Ah ja, sie waren also größer als 4 Milliarden. Wow! >--> Problem: Zählen bis 1 Mio. mit EINEM 8 bit Register ohne externe HW >und ohne Timer. > >- Init: Register auf 0 setzen >- 5 mal in 1-er Schritten hochzählen (5 Takte) >- 4 mal in 1-er Schritten runterzählen (5 Takte) >- Registerinhalt : 1 nach 10 Takten >- 5 mal in 1-er Schritten hochzählen (5 Takte) >- 4 mal in 1-er Schritten runterzählen (5 Takte) >- Registerinhalt: 2 nach 20 Takten > >--> die Kombination 5 hoch 4 runter ist eigentlich ein Prescaler 1:10 Woher weiß das Programm, ob es bei einem eintreffenden Impuls das Register hoch- oder runterzuzählen hat? >andere Zahlenkombinationen ergeben andere Teiler. Hm.... >[...] die Zeile "Registerinhalt" kann man ja wieder als >eine Variable auffassen, der 6 mal hochzählt und dann 5 mal runter... >Und wenn das nicht reicht, kommen halt nochmal 20 Ebenen hinzu. >Alles in sich verschachtelte For- Schleifen... "in sich verschachtelte For- Schleifen..." Wie soll das genau zu verstehen sein? Poste mal ein Stück Code - das dürfte manche Frage klären.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.