Hi ich habe mal ein paar Fragen zu dem Code eines RC5-Decoders, das ursprüngliche Projekt kann man unter http://www.roboternetz.de/wissen/index.php/RC5-Decoder_f%C3%BCr_ATMega betrachten, ich habe das ganze ein bisschen (stümperhaft) an die GCC 4 Version angepasst und auch zum Laufen gebracht, leider weiß ich nicht WARUM es läuft ;-) Ich habe meinen Code mal hier gepostet C Datei: http://nopaste.debianforum.de/7636 Header Datei: http://nopaste.debianforum.de/7637 Meine erste Frage: Zeile 30 ##define RC5_TICKS ((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US 1000 RC5_PRESCALE))) Warum wird hier 2 mal gecastet? Ich sehe bei diesem Codeteil keinen Sinn darin... bei F_CPU von 1Mhz = 10^6 müsste das Ergebnis 27 sein richtig?? heißt das, dass man 27 Controller Takte braucht um die Zeitdauer eines RC5-Bits zu durchlaufen? Wie kommt man auf die Rechnung?? Hier noch die Beschreibung des RC5-Standards: http://www.roboternetz.de/wissen/index.php/RC5-Code Danke für eure Hilfe Greetz Anubis
Hallo! #define RC5_BIT_US (64*27) Bei RC5 wird die Information auf eine Trägerfrequenz aufmoduliert. Ein Bit besteht immer aus einem High- und einem Low-Teil. Die Phasenlage gibt dann die Bedeutung ob High oder Low an. Ein Halbbit hat immer 32 Schwingungen der Trägerfreuenz. Damit hat ein ganze Bit 64 Schwingungen. Die 27 scist dann Dauer einer Trägerschwingung. (da käme ich dann auf 37 kHz, was mir etwas komisch erscheint, weil ich eher mit 36 oder 38kHz gerechnet hätte) Somit beschreibt der Ausdruck die Länge eines Bits in µs. Die Trägerfrequenz wird übrigens vom Empfänger eliminiert. #define RC5_TICKS \ ((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US / 1000 / RC5_PRESCALE))) Die Berechnung wird dazu genutzt, die µs in Takte des Timers (nicht der CPU) umzurechnen. Die casts müsstest Du Dir eigentlich selbst erklären können, wenn Du etwas Programmiererfahrung hast. Es ist doch klar, dass F_CPU selbst bei 1MHz also 1 000 000 niemals in ein uint8_t passt. Durch die Divisionen ergibt sich dann ein Wert, der klein genug ist, dass er in 8 bit passt. Dieser cast wird gemacht, damit der Controller, er hat ja nur 8 bit, nicht den unnötigen Ballast mitschleppen muss. Respekt, wenn Du ohne diese Kenntnisse das Programm zum Laufen gebracht hast. Ich habe letzte Woche das gleiche für ein Sony-Protokoll gemacht und war schon am Verzweifeln. Letztendlich war es eine falsche Subtraktion. Gruß Matthias
hmm also um genau auf 32kHz zu kommen müsste man 31,25 nehmen, heißt das dann dass man eigentlich auch 64*32 nehmen könnte und es müsste immer noch funktionieren und hier wurden halt 27 genommen, dass man noch ein bisschen mehr Spiel hat??
zur Zeile 30: im Prinzip ist die Rechnung ja so: (Takte die der Mega8 pro Sekunde gibt) * (Dauer eines bits) / (Vorteiler, da ich ja nur jeden 64. Takt zähle) warum teile ich die Takte und die Dauer dann nochmal durch 1000? Das Casten macht bei 1MHz meines Erachtens aber keinen Sinn, da ich ja erst alles ausrechne und dann erst caste und bei einem Gesamtergebnis von 27 reicht mir ein 8 bit Datentyp ja locker aus. Oder ist es so, dass man als "ersten" Datentyp immer den größten der gesamten Rechnung nehmen muss? Was ich leider immer noch nicht verstehe ist warum ich überhaupt von einem großen in einen kleinen caste, angenommen ich habe das Ergebnis 500 und behalte dann nur die hinteren 8 bit, dann erhalte ich als Ergebnis ja 244, was ja ein TOTAL anderer Wert ist?? Ich sollte dazu sagen, dass ich aus der Java Programmierung komme und mich bisher in keinster weise um einzelne Bits gekümmert habe ;-)
Der cast auf uint32_t schließt die ganze Rechnung ein. Das heißt, dass w ä h r e n d dieser Berechnung mit 32 bit gerechnet wird, da manche Operanden doch recht groß sind. Erst n a c h der Berechnung liegt ein Ergebnis vor, dass wieder auf 8 bit gecastet werden kann. Warum 2 mal durch 1000 teilen? - ist auch einfache Mathematik! Das define für F_CPU gibt die Takte pro S e k u n d e an. Dein define für 1 Bit ist in µs angegeben. Zwei mal durch 1000 teilen heisst durch 1 Million teilen. Und 1µs ist eine millionstel Sekunde. Warum teilt man nicht gleich durch 1 Million wirst Du fragen. Das ist ganz einfach: Bei Ganzzahlberechnungen sollte man immer erst die Multiplikationen und dann die Divisionen ausführen, um keine Auflösung zu verlieren. Das ist in dem Makro natürlich nicht ganz konsequent gemacht - aber sei's drum. Als kleines Beispiel rechne doch mal 1050 / 100 * 3 bzw. 1050 * 3 / 100 ganzzahlig. Der Unterschied ist 30 zu 31. Wenn Du sicher bist, dass Dein System mit 32kHz Trägerfrequenz arbeitet, dann kannst Du das define natürlich anpassen. Dein Code funktioniert bei Dir aber trotzdem, weil als Toleranz immer die Mitte eines Halbbits genommen wird. Da bei jeder Flanke neu gemessen wird akkumuliert sich der Fehler auch nicht auf. Gruß Matthias
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.