Hallo, da ich nichts passendes im Web finden konnte, frage ich hier mal. Ich suche eine (vergleichsweise einfache) Logikschaltung, welche mir die Anzahl der gesetzten Bits, also '1' er, zurückgibt. Z.B.: 00001100 -> Ausgabe: 00000010 Gibt es so etwas? Ich meine, ohne das umständlich über Tables oder dergleichen zu lösen?
Mit einer analogen Summierer-Schaltung ist das kein Problem. Digital lohnt m.E. nur ein µC.
Man könnte ein Schieberegister mit einem Binärzähler kombinieren. Erst wird das Byte parallel ins Schieberegister geladen und der Binärzähler gelöscht. Dann werden die Bits seriell ausgegeben. Jedes mal, wenn der Ausgang des Schieberegisters eine 1 liefert, wird ein Binärzähler einmal getaktet. Du brauchst also ein Schieberegister mit parallel-in/serial-out, einen Binärzähler, ein Und Gatter und einen Taktgeber. m.n. hat Recht: Mit einem Mikrocontroller braucht man weniger Bauteile. Aber für Leute ohne entsprechende Kenntnisse und Equipment könnte die Lösung mit Logikgattern dennoch attraktiv sein. Eine andere Lösung: Lege das Byte an die Adress-Leitungen eines 256x8. Bei geschickter Programmierung liefert es dann am Ausgang direkt den gewünschten Zählwert, ganz ohne Taktung. Dafür braucht man natürlich einen Eprom-Brenner.
Danke Stefan! Die Lösung mit dem EEPROM scheint mir am günstigsten zu sein
Stefan us schrieb: > Lege das Byte an die Adress-Leitungen eines 256x8 Wobei es so einen Speicher nicht (mehr) gibt, ein EProm mit 1 MBit wäre erheblicher Overkill. Als es noch bipolare kleine Proms gab habe ich es so gemacht. Eine weitere Möglichkeit ist die Programmierung eines PAL oder CPLD. Jeromyo schrieb: > Gibt es so etwas? Machen lässt sich das schon (20pol IC). Brauchst du das nur einmal oder in Serie? Gruss Reinhard
Schnell könnte ein EPROM sein, in das man Tabellen programmiert. Ein Makroassembler kann sowas vielleicht schon bewerkstelligen, den Code erzeugen. Ich weiß es aus dem Stehgreif nicht genau, man müßte sich damit näher beschäftigen. Mit einem Makroassembler machte ich mal Bitmuster in leere Speicherbereiche, die nichts mit dem eigentlichen Code zu tun hatten. Diese Dinger können einiges.
Eher nicht in Serie, das Problem ist jetzt bloss schon öfter aufgetaucht, und da ich mich aktuell wieder damit beschäftige und nur schwer drum herum komme, muss ich wohl eine Lösung finden
Ein entsprechend programmierter ATtiny84A würde reichen (14 Pins). Wird bestimmt nicht schwer sein. Wie schnell muss die Umrechnung erfolgen? Reicht ca. 1 µs?
Die Umrechnungszeit ist semikritisch, 1 uS ist akzeptabel. Dann werde ich die Lösung mittels Mikrocontroller wohl umsetzen, danke für eure Mithilfe!
Jeromyo schrieb: > Die Umrechnungszeit ist semikritisch, 1 uS ist akzeptabel. Dann werde > ich die Lösung mittels Mikrocontroller wohl umsetzen, danke für eure > Mithilfe! Ein EPROM würde es locker schaffen. Leider hat aber heute nicht jeder einen Programmer. Ein µC mit zwei Ports zu je 8 bit kann auch noch energiesparender sein, wie ich es bspw. an den Ultra-Low-Power PIC12F675 sehe. Der hat aber ein paar Pins zu wenig. Ist eine µS mit einem einfachen µC erreichbar? Denn die Software muß ja noch ein wenig einlesen, zählen, und wieder ausgeben.
Herbert schrieb im Beitrag #3385074: > Wilhelm F. schrieb: >> Ist eine µS mit einem einfachen µC erreichbar? > > Look-Up Table vielleicht? Genau so war mein Vorschlag mit dem ATtiny84A gedacht. 1 Takt: Einlesen des Bytes 3 Takte: Lookup im Flash 1 Takt: Ausgeben des Hamming-Gewichts 2 Takte: Sprung zum Programmanfang Macht in Summe 7 Takte, das heißt, bei Verwendung des internen Oszillators eines ATtiny84A benötigt ein Programm-Durchlauf 7/(8 MHz), also 875 ns.
Ein paralleles EEPROM kann man durchaus von Hand programmieren. Dazu genügen eine passende Fassung, Mäuseklaviere und ein paar Taster. Es ist zwar etwas Zeitaufwändig, aber für ein Hobby-Einzelstück durchaus machbar.
Als Logikschaltung geht das natürlich auch. Man braucht 1x 7486 1x 7408 und 3x 7483. Welcher Weg sinnvoll ist, hängt vom Einsatzzweck und den eigenen Möglichkeiten ab (EPROM, uC Programmer etc.)
Markus Weber schrieb: > Herbert schrieb im Beitrag #3385074: >> Wilhelm F. schrieb: >>> Ist eine µS mit einem einfachen µC erreichbar? >> >> Look-Up Table vielleicht? > > Genau so war mein Vorschlag mit dem ATtiny84A gedacht. > > 1 Takt: Einlesen des Bytes > 3 Takte: Lookup im Flash > 1 Takt: Ausgeben des Hamming-Gewichts > 2 Takte: Sprung zum Programmanfang > > Macht in Summe 7 Takte, das heißt, bei Verwendung des internen > Oszillators eines ATtiny84A benötigt ein Programm-Durchlauf 7/(8 MHz), > also 875 ns. OK. Eine Table kann im µC immerhin eine feste Zyklenzahl haben. Also: Einen geeigneten µC wählen. Befehle, um Tables zu verarbeiten, haben bestimmt alle. Ich persönlich würde das EPROM versuchen, aber einfach nur, weil ich einen Programmer besitze. Die gängigen EPROM haben Zugriffszeiten um 100ns, das ist auf jeden Fall besser als eine µs. Allerdings haben sogar CMOS-EPROM einen höheren Strombedarf bei Chip Enable, als ein moderner Ultra-Low-Power-µC. Das muß man halt abwägen. Beim PIC12F675 war ich ja erstaunt, als ich erst viel später lange nach der Verwendung sah, daß der ein Ultra-Low-Power-Typ ist. Braucht auch nur was um die 500µA herum bei internem RC-Oszillator 4MHz. Den 12F675 gibt es auch mit 6 I/O mehr als 16F630. Das ist aber immer noch zu wenig. Bestimmt gibt es da einen mit genug Pins, kenne sie nicht alle.
Der ATTiny84A hat genug SRAM, um die Tabelle dort abzulegen. Dann sind es nur noch 5 Takte für die Schleife und im schlimmsten Fall 7 Takte von der Änderung bis zur Ausgabe.
1 | loop: |
2 | in r31, PINA |
3 | ld r16, Z |
4 | out PORTB, r16 |
5 | rjmp loop |
Wer Strom sparen will, kann das natürlich noch in den PCINT packen und den µC in den Schlaf schicken. Auswertung dauert dann halt n paar Takte länger.
kein Gast schrieb: > Der ATTiny84A hat genug SRAM, um die Tabelle dort abzulegen. Wieso SRAM? ROM, es braucht nur 256 Bytes.
kein Gast schrieb: > Der ATTiny84A hat genug SRAM, um die Tabelle dort abzulegen. Dann sind > es nur noch 5 Takte für die Schleife und im schlimmsten Fall 7 Takte von > der Änderung bis zur Ausgabe. Richtig. Damit kann man die Reaktionszeit noch einmal verkürzen, gute Idee. Ich hab aber noch etwas anderes übersehen: Für 8 Bits am Eingang gibt es 9 verschiedene Hamming-Gewichte (0 bis 8) und nicht nur 8. Folglich braucht man als Ausgang nicht 3 Pins, sondern 4. Damit ist das ATtiny84A bis zum Rand voll, man muss das Reset-Pin als Ausgang verwenden. Je nach Programmier-Tool kann es dann besser sein, auf einen ATtiny4313 umzusteigen (kostet eh das Gleiche). Hier ein Programmvorschlag (ungetestet!):
1 | ; Hamming-Gewicht 2013-11-01 18:00 |
2 | ; Markus Weber, Nuernberg |
3 | .include "tn84Adef.inc" |
4 | |
5 | ldi r16,0b1111 ; PB0..PB3 als Ausgang |
6 | out DDRB,r16 |
7 | |
8 | ldi r16,(1<<CLKPCE) |
9 | out CLKPR,r16 |
10 | ldi r16,0b00000000 ; CPU-Prescaler 1 |
11 | out CLKPR,r16 |
12 | |
13 | ldi ZH,1 |
14 | |
15 | in ZL,PINA |
16 | lpm r16,Z |
17 | out PORTB,r16 |
18 | rjmp -3 |
19 | |
20 | .org 128 ; Tabelle mit den Hamming-Gewichten |
21 | .db 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 |
22 | .db 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 |
23 | .db 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 |
24 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
25 | .db 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 |
26 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
27 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
28 | .db 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 |
29 | .db 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 |
30 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
31 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
32 | .db 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 |
33 | .db 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 |
34 | .db 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 |
35 | .db 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 |
36 | .db 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 |
kein Gast schrieb: > Wenn ich mich recht erinnere, braucht LPM 3 Takte, LD nur einen. Hab deine Idee mal umgesetzt. Hat sogar den Vorteil, dass man die Hamming-Gewicht-Tabelle bei der Initialisierung automatisch berechnen lassen kann und damit Tippfehler vermeidet. Hier der Vorschlag – wieder ungetestet:
1 | ; Hamming-Gewicht 2013-11-01 18:30 |
2 | ; Markus Weber, Nuernberg |
3 | .include "tn84Adef.inc" |
4 | |
5 | ldi r16,(1<<CLKPCE) |
6 | out CLKPR,r16 |
7 | ldi r16,0b00000000 ; CPU-Prescaler 1 |
8 | out CLKPR,r16 |
9 | |
10 | ldi r16,0b1111 ; PB0..PB3 als Ausgang |
11 | out DDRB,r16 |
12 | |
13 | ; erzeuge Tabelle der Hamming-Gewichte |
14 | ldi ZH,1 |
15 | ldi ZL,0 |
16 | mov R0,0 |
17 | next_value: |
18 | ldi r17,0 ; Zähler für Hamming-Gewicht |
19 | mov r16,ZL |
20 | lsr r16 |
21 | adc r17,r0 |
22 | lsr r16 |
23 | adc r17,r0 |
24 | lsr r16 |
25 | adc r17,r0 |
26 | lsr r16 |
27 | adc r17,r0 |
28 | lsr r16 |
29 | adc r17,r0 |
30 | lsr r16 |
31 | adc r17,r0 |
32 | lsr r16 |
33 | adc r17,r0 |
34 | lsr r16 |
35 | adc r17,r0 |
36 | st Z,r17 |
37 | inc ZL |
38 | bne next_value |
39 | |
40 | ; Hauptschleife |
41 | in ZL,PINA |
42 | ld r16,Z |
43 | out PORTB,r16 |
44 | rjmp -3 |
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.