Guten Morgen, ich habe folgenden Code: while ((PIN_SHT & (1<<PIN_DATA)) && (i < 320000)) i++; if (i >= 320000) *error_code = 3; mit 2Mhz; 320000 = 320ms So die while schleife kontrolliert, ob der Pin_data high wird oder die Zählvariable 320000 erreicht hat und bricht dann die Schleife ab. jetzt zu meiner frage bei 2MHz habe ich eine Periodendauer von 500ns. Ich bin ich davon ausgegangen, dass die Prüfung der Bedingung einen Takt benötigt und die Inkrementierung einen weiteren Takt. Wodurch ich 2 Takte habe oder 1µs. Stimmt das oder brauch die Schleife zur Prüfung der Bedingung mehr als 1 Takt? Vielen Dank für eure Hilfe!
Frank O. schrieb: > Ich bin ich davon ausgegangen, dass die Prüfung der Bedingung einen Takt > benötigt nie. Es sind schon mal 2 Bedingungen die geprüft werden müssen PIN_SHT & (1<<PIN_DATA) und i < 320000 also wenn überhaupt schon mal 2 Takte. Da wir nicht wissen ob um welche CPU es sich handelt gehe ich einfach mal von einer 8bit CPU aus. Damit braucht man hier schon mal wieder 2 Takte weil das ganze mindestens 16bit ist. Aber sinnvoller ist es einfach mal in das erzeugte assembler file zu schauen und selber zu rechnen.
Hi >Stimmt das oder brauch die Schleife zur Prüfung der Bedingung mehr als 1 >Takt? Sieh dir einfach den erzeugten Assemblercode an. Aber es sind auf jeden Fall einige Takte mehr als 1. MfG Spess
Ich gehe mal von einem 8 Bit Prozessor aus: 1 Takt für die Überprüfung der Schleifenbedingung ist kaum realistisch, da ja 2 voneinander unabhängige Bedingungen geprüft werden. Zusätzlich führst du mit i<320000 einen vergleich mit einer 32-bit Variable durch. i++ inkrementiert eine 32-bit Variable, also geht das auch nicht in einem Takt.
Hallo, Die Pruefung brauhct natürlich mehr als einen Takt, Du hast ja auch 2 bedingungen verknüpft Pin einlesen, bit schiften, verunden, zählvariable prüfen... und damm noch ein und verknüpfung der beiden Ergebnisse am besten du schasut Dir mal den Assembler Code an, den der Compiler daraus macht. Die anzahl der Takte sind vermutlich auch noch von der Eingestellten Optimierungsstufe den Compilers (-O0 oder -O2) abhängig. ps. Die schleife bricht ab, wenn der Pin_data low wird
Und dann gibt es noch uCs die schon 4..16 Takte für die Ausführung einer einzelnen ASM-Instruktion benötigen...
nobi schrieb: > ps. Die schleife bricht ab, wenn der Pin_data low wird Jop mein Fehler in der Erklärung Es handelt sich um einen ATmega32 ich gucke mir mal den assemblercode an und poste ihn später mal Vielen Dank schonmal
Kann mir einer helfen herauszufinden, wieviele Takte das sind ich kenn mich mit assembler absolut nicht aus! while ((PIN_SHT & (1<<PIN_DATA)) && (i < 320000)) bfa: 86 9b sbis 0x10, 6 ; 16 bfc: 09 c0 rjmp .+18 ; 0xc10 <SHT75Temperature+0x50> bfe: 80 30 cpi r24, 0x00 ; 0 c00: 22 ee ldi r18, 0xE2 ; 226 c02: 92 07 cpc r25, r18 c04: 24 e0 ldi r18, 0x04 ; 4 c06: a2 07 cpc r26, r18 c08: 20 e0 ldi r18, 0x00 ; 0 c0a: b2 07 cpc r27, r18 c0c: 99 f7 brne .-26 ; 0xbf4 <SHT75Temperature+0x34> c0e: 08 c0 rjmp .+16 ; 0xc20 <SHT75Temperature+0x60> i++; Was wird denn jetzt alles gezählt? Vielen Dank
Da fehlt was: Der Sprung zurück geht nach 0xbf4, dein Auszug fängt aber erst bei 0xbfa an.
Frank O. schrieb: > mit 2Mhz; 320000 = 320ms > So die while schleife kontrolliert, ob der Pin_data high wird oder die > Zählvariable 320000 erreicht hat und bricht dann die Schleife ab. Mal ganz abgesehen von deiner Milchmädchenrechnung mit den Taktzyklen in der Schleife ist das ein ganz schlechtes Design, weil es nicht portabel ist. Schon eine simple Änderung der Compilerflags (z.B. Debug-Build vs. Release) wird voraussichtlich die Wartezeit verändern. Dito eine Änderung der Taktfrequenz. Wenn du überhaupt busy-waiting verwenden willst, dann geh wenigstens über _delay_us() aus <util/delay.h>. Angesichts der mit 320ms eher langen Wartezeit würde ich aber eher einen Timer empfehlen. XL
Axel Schwenke schrieb: > Wenn du überhaupt busy-waiting verwenden willst, dann geh wenigstens > > über _delay_us() aus <util/delay.h>. Angesichts der mit 320ms eher > > langen Wartezeit würde ich aber eher einen Timer empfehlen. Ja vielen Dank! Ich hätte auch noch einen Timer frei nur das müsste ich wieder über Interrupts laufen lassen und ich hab da schon einige verwendet und wollte nicht noch weitere verwenden, wodurch sich die chance, dass sich 2 überschneiden und dadurch versetzt ausgeführt werden erhöht! Aber ich hab es mal im hinterkopf und werde es einfach mal später ausprobieren. Im Anhang habe ich mal die komplette Funktion hochgeladen! Ich glaube muss mich mal was mit assembler beschäftigen, dass ist alles nicht verstänlich für mich!
Dann machs wenigstens so
1 | i = 0; |
2 | while ((PIN_SHT & (1<<PIN_DATA)) && (i++ < 320)) |
3 | _delay_ms( 1 ); |
4 | |
5 | if (i >= 320) |
6 | *error_code = 3; |
dann stimmt die Zeit wenigstens so einigermassen, weil der Rest der SChleife im Vergleich zum _delay_ms unter "ferner liefen" fungiert.
Karl Heinz Buchegger schrieb: > Dann machs wenigstens so > > i = 0; > > while ((PIN_SHT & (1<<PIN_DATA)) && (i++ < 320)) > > _delay_ms( 1 ); > > > > if (i >= 320) > > *error_code = 3; > > dann stimmt die Zeit wenigstens so einigermassen. Ja habe ich mir auch überlegt genau muss es ja eh nicht sein! ob jetzt 310 oder 330ms spiel keine Rolle
Frank O. schrieb: > Was wird denn jetzt alles gezählt? Im Datenblatt Deines AVRs gibt es eine Tabelle "Instruction Set Summary", in der ist zu jedem ASM-Befehl unter anderem auch die Abarbeitungszeit (in Taktzyklen) aufgelistet. Falls damit immernoch Unklarheiten bestehen, hilft die Hilfe des AVR-Studios (Cursor auf ASM-Befehl stellen und F1-Taste drücken) oder das PDF mit der ausführlichen Beschreibung des Instruction-Set. Der Rest ist dann einfaches Addieren... ...
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.