Guten Abend!
Ich möchte möglichst viele 5 Bit breite Datensätze speichern. Bisher
habe ich im RAM ein Byte Array (uint8_t Daten[1024]) angelegt und in
jedem Byte einen 5 bit breiten Datensatz gespeichert. Damit verschenke
ich 3 * 1024 potentielle Speicherstellen. Wenn ich einen Zeiger hätte,
der 5 Bit weit zeigt, wäre das Problem zu lösen. Leider weiß ich nicht,
wie ich einen solchen Zeiger erstellen kann. Könnt Ihr helfen? Eine
Nebenbedingung ist aber, es darf nicht allzuviel Rechenzeit dauern, weil
die 5 bit breiten Datensätze möglichst schnell von einem Port gelesen
werden müssen. Es soll ein Logic Analyzer werden. Ich benutze C auf
einem Atmega 328P.
Danke!
ArduStemmi schrieb:> nicht allzuviel Rechenzeit dauern, weil die 5 bit breiten Datensätze> möglichst schnell von einem Port gelesen werden müssen.
Vergiss es. Dein RAM ist byteorientiert, alles was davon abweicht,
kostet Rechenzeit. Oder andersrum: für 5 von 8 Kombinationen fallen dann
gleich 2 der aufwändigen Speicheroperationen zusätzlich zusammen mit den
nötigen Schiebe- und Maskieroperationen an...
@ArduStemmi (Gast)
>jedem Byte einen 5 bit breiten Datensatz gespeichert. Damit verschenke>ich 3 * 1024 potentielle Speicherstellen. Wenn ich einen Zeiger hätte,>der 5 Bit weit zeigt, wäre das Problem zu lösen. Leider weiß ich nicht,>wie ich einen solchen Zeiger erstellen kann. Könnt Ihr helfen?
Du musst dir eine Funktion schreiben, welche deine 5 Bit Datensatz in
das 8 Bit Array einfügt. Dazu brauchst du Bitmanipulation, in dem
Artikel sind auch Beispiele drin.
1
voidwrite_5bit(uint8_tdata,uint16_tindex){
2
// selber ausfüllen
3
}
4
5
uint8_tread_5bit(uint16_tindex){
6
uint8_tdata;
7
// selber ausfüllen
8
returndata;
9
}
> Eine>Nebenbedingung ist aber, es darf nicht allzuviel Rechenzeit dauern, weil>die 5 bit breiten Datensätze möglichst schnell von einem Port gelesen>werden müssen. Es soll ein Logic Analyzer werden.
Alles relativ. Welche maximale Samplerate strebst du an? 100kHz?
Vielleicht reichen ja auch 4 Bit, dann kannst du einfach 2 Samples in 1
Byte packen.
ArduStemmi schrieb:> Ich möchte möglichst viele 5 Bit breite Datensätze speichern. Bisher> habe ich im RAM ein Byte Array (uint8_t Daten[1024]) angelegt und in> jedem Byte einen 5 bit breiten Datensatz gespeichert.
Pack deine Datenbits in 40Bit große Datenblöcke. Dann wird alles gut.
das klingt doch nicht wirklich kompliziert.
Dafür würde ich einfach mal in einem C Forum fragen oder Pascal!
Ja Pascal :-) klingt jetzt komisch ist aber so, die Leute dort sind
meist extrem Hilfreich, und können Dir den richtigen Denkanstoß geben
Ich hätte da schon eine Idee, weiß aber auch nicht wie das geschickt
umgesetzt wird.
Hier wirst Du nur hören, geht nicht, gibts nicht oder kauf Dir ein Buch
:-)
Das mit den 4 Bit klingt schonmal gut :-) Ich dachte eher an fortlaufend
sammeln und sobald 8 Vollständig sind schreiben oder so
Gibt sicher noch etliche andere schnelle Lösungen
bzw 10 bit splitten in 5 und dann warten bis das nächste 8er Paket
kommt..jeder der hier jetzt wieder rummaulen will, soll erstmal
überlegen, dann versteht er wie ich es meine
Tom Thomsen schrieb:> Pack deine Datenbits in 40Bit große Datenblöcke. Dann wird alles gut.
Wobei man bei AVRs mangels effizienter Shifts etwas kreativ vorgehen
muss. Also erst 8 4-Bit Blöcke speichert und fehlenden Bits in einem
Byte sammelt.
>Dann kannst du entscheiden: Speicher vs. Geschwindigkeit.
Wenn man dann noch einen ATMeg1284 mit 16kB RAM nimmt
fällt die Wshl nicht mehr ganz so schwer. Oder gleich
einen Cortex-M4;) Der wäre mit per Timer getriggertem
DMA sowieso besser geeignet für einen LA.
MSP430 schrieb im Beitrag #4470101:
> Besser wird das von Hand auch nicht.
Doch. Bei einem AVR wird es schneller, wenn man die 5 Bits in 4+1
aufspaltet und getrennt speichert. Das macht aber kein Compiler von sich
aus. Darf er nicht.
Tom Thomsen schrieb:> Pack deine Datenbits in 40Bit große Datenblöcke. Dann wird alles gut.
Das klingt gut, aber wie mache ich 40 bit große Datenblöcke?
ArduStemmi schrieb:> Ja! Aber wie greife ich auf Bit 0, 5, 10, ... 35 zu?
Du rechnest dir erst mal mit viel Aufwand die passende Adresse aus und
maskierst dann am besten über eine Tabelle das passende Bit heraus.
Langer Rede kurzer Sinn: es ist unsinnig. Nimm einen grösseren
Controller und/oder lies 8 Bits ein. Nicht umsonst haben übliche LA
genau solche Podbreiten...
Ich würde es in 8 bit Variablen lassen.
Du kannst über Bitmanipulation 2 5-bit zahlen in 2 8-bit Variablen
Speichern
Würde dann so ausschauen
var1 var2
-------- --------
12345123 45.....
die Zahlen beschreiben die Wertigkeit der 5 bit zahl.
Aufwendig wird es wenn du genau den x-ten Wert adressieren möchtest.
Hier würde ich
Bytenummer = (Anzahl_5-bit_var * 5)/8 // Berechnet dir in welchen Byte
deine 5 bit anfangen
start nummer = (anzahle_5-bit_var * 5)%8 // Berechnet die stelle des
ersten Bytes der 5-bit zahl
bsp
bytenummer: 1 2 3
byte: 01234567 01234567 01234567 .....
-------- -------- -------
5-bit: 12345123 45123451 23451234 5.....
gesucht x
Startadresse der 3. 5bit Wertes (x)
3.var
Bytenummer 3*5/8 = 2
start nummer 2*5%8 = 7
Nun musst du nur einen Start wert bestimmen und den Speicher Reservieren
Grüße
basti195
Du verschenkst 3072 Bit wenn du 8 Bit Variablen verwendest.
Ist ja beeindruckend.
Bist du dir vollkommen sicher, dass sich dafür der Thread überhaupt
gelohnt hat, geschweige denn das Programmieren und der
Performanceverlust durch die Bitoperationen?
Das ist richtig!
Einer der wichtigsten Gründe, warum ich mich mit Mikrocontrollern
beschäftige, ist das damit verbundene Lernen! In Wirklichkeit brauche
ich gar keinen Logicanalyzer! Aber ich wollte mich mal mit der Sache
umfassend beschäftigen. Also das komplette Programm: Hardwareentwurf und
Basteln, Mikrocontroller programmieren und PC-Programm mit allerlei
Schnickschnack schreiben!
In diesem Zusammenhang kam mir die Frage, ob man den RAM nicht Bit für
Bit beschreiben und lesen kann!
Das geht scheinbar nicht ohne aufwendiges Bitgeschiebe (also viel Zeit,
naja im Mikrosekundenbreich viel) Wieder was gelernt!
Ich werde von fünf auf vier Kanäle wechseln und kann dann 2048 Samples
speichern!
Ich habe übrigens bei 16 MHz auf 800 kHz samplingrate (entspricht 1,25
Mikrosekunden Samplingtime) gebracht! Passt ganz genau, weil es muss ja
ein ganzzahliges Vielfaches von 0,0625 Mikrosekunden sein! Ach ja!
Geeicht ist es nicht! Es ist so genau wie der Quartz taktet! Für meine
Anwendung ausreichend!
Und Spaß macht das!
Danke für Deine Bemühungen! Du hast natürlich Recht! Für 800 kHz
ungeeignet! Aber für Samplingrates kleiner 100 kHz könnte es gehen! Ich
werde das mal testen!
Fuer etwas aehnliches: 4 10 bit AD-gewandelte Werte in 5 Bytes
zu packen habe ich mir fuer die Midrange PICs (12F675/683, 16F684)
mal eine Assemblerroutine programmiert.
Die kann ich dann bequem vom Compiler aus aufrufen und
brauch das widerliche Geschiebe nicht in C zu formulieren.
Die Routine zum "Einpacken" und zum "Auspacken" ist lustigerweise
dieselbe. (Die Speicherbereiche auf denen gearbeitet wird,
natuerlich nicht.)
> Einer der wichtigsten Gründe, warum ich mich mit Mikrocontrollern> beschäftige, ist das damit verbundene Lernen!
Dann mach mal.
Mehr als ein wenig Zeit und "Brain" braucht es nicht.
Falk B. schrieb:> Eben. Man sollte nicht den Schinken nach der Wurst werfen.
Das sagen die Hochsprachler immer.
Und genau deswegen merkt man von dem Leistungszuwachs der Hardware in
den letzten Jahrzehnten auch so gut wie garnix. Alles wurde in immer
tieferen Schichten von in Hochsprachen geschriebenen Abstraktionen
versenkt...
Das klappte in den 80ern, 90ern und auch in den 00er Jahren noch
ziemlich gut. Aber seitdem etwa ab 2008 das Moore'sche Gesetz doch ein
wenig in's Hinken gekommen ist, merkt man doch sehr deutlich, dass
dieser Weg letztlich in den Abgrund führen wird, ja führen muss.
Das Lustige ist, dass ausgerechnet eine Sprache, die das Prädikat
"Hochsprache" eigentlich garnicht verdient, den Weg in den Abgrund
geebnet hat. Und diese Sprache heißt "C". Und sie wird wohl auch bis zum
bitteren Ende signifikant beteiligt sein...
Es gibt verschiedene Arten es zu realisieren, und es spricht auch nichts
dagegen mehrere parallel zu implementieren.
z.B.
- Einfach die bits verschwenden, dafür maximale Samplerate
- den mode nur 4 Bits zu speichern, die dann in ein Byte zu packen,
fehlt ein bit, aber doppelte länge, evt etwas langsammer
- 8 Bytes auf einmal einlesen, einlesen b1 und b2, 4+4 bit zusammen
packen wegschreiben, das 5 bit in ein anderes byte reinschieben, nach 8
spamples auch das wegschreiben.
- Einlesen, gucken ob der Wert identisch mit dem vorherigen, dann einen
Counter zählen, bis 3 Bit, Die drei Bit werden dann in den freien Bits
abgelegt.
- wie vorher nur das die Wiederholung im Extrabyte gespeichert wird
oder die 3 Bit noch mitbenutzt, damit kann man je nach Signal lange
Aufzeichungsdauer erreichen.
Später beim Benutzen sucht man sich den Mode aus, den man braucht hohe
Samplingrate oder lange Aufzeichung. Beim überprüfen von seriellen
Bussen reicht oft 2 oder 3 Bit.
Wichtig ist nur das beim Einlesen jedes Sample den gleichen Abstand zum
nächsten hat, da sonst das Timing nachher nicht stimmt. Bei Auswerten
hat man Zeit und muss nicht so tricksen. Wenn man eine sehr effektive
Einleseroutine haben will, kann man da schon einiges an Zeit
reinstecken.
@ArduStemmi
Das könnte man doch mit einer Hard-/Softwarekombination lösen.
Beim LA willst Du ja nur wissen ob am Messpunkt zum Zeitpunkt x L oder H
Pegel anliegt. Du brauchst also einen Puffer in welchen der Pegel
entsprechend Deiner gewünschten Samplingrate eingeschrieben wird. Für
sowas verwendet man normalerweise ein Schieberegister. Die Daten werden
hierbei bei jedem Sampleimpuls in das Schieberegister seriell
eingeschrieben und stehen nach 8 Samples an den Ausgängen des Registers.
Jetzt kann man das Register auslesen und damit ein 8 Bit breites
Datenwort, welches man nun als Byte speichern könnte. Dann werden wieder
8 Samples eingelesen und das Register ausgelesen. Das Auslesen des
Registers muß natürlich zwischen 2 Samples passieren.
Du brauchst natürlich für jeden Kanal ein Register. Das Einschreiben in
die Register wird mit dem gleichen Impuls für alle Register ausgelöst,
also für alle Kanäle synchron.
So würde ich das realisieren. Nachteil es braucht natürlich zusätzliche
Hardware. Vorteil die Anzahl der Kanäle kann sehr groß gewählt werden,
allerdings geht das auf Kosten der Samplerate, da ja alle Register nach
jedem 8. Sample zwischen 2 Samples gelesen werden müssen.
Ist nur mal so als Denkanstoß gedacht und erhebt keinen Anspruch auf
Perfektion.
Zeno