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.
...
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.
...
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
@ 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
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.