Hallo liebe Gemeinde! Vorab, ich bin kein Profi in diesem Gebiet, hatte nur einige Stunden µController in der Schule. Deswegen seit bitte nicht zu hart. Jetzt zu meinem Problem, ich wollte eine Witterungsbedingte Temperatursteuerung simulieren. Jetzt "hängt" der sich nur schon bei der Rechnung für die Solltemperatur auf, die Formel funktioniert einwandfrei, bis ich die Division durch 10 einfüge, danach springt der mir in die disassembly Tabelle! Dies bezog sich jetzt auf die Rechnung mit der Variable "sollwert". Bei der Variable "b" funktioniert eine Division bzw rechnet er hier auch mit 1.2 warum eigentlich? Da er aber, sobald ich Variablen ins spiel bringe, nicht mehr mit 1.2 rechnet sondern abrundet auf 1, muss ich eben mal 12 multiplizieren und dann später durch 10 dividieren. Die Rechnung soll mit Integervariablen erfolgen kein float! Ich benutze AVR Studio 6.0, und einen Atmega8A Quelltext: int main(void) { int heizkurve = 12; int sollwert = 0; int aussentemp = 100; int konstante = 500; while(1) { int b = ((500-600)*1.2)+500; sollwert = (((konstante-aussentemp)*heizkurve)+konstante)/10; } }
Seijsschmeer schrieb: > > Bei der Variable "b" funktioniert eine > Division bzw rechnet er hier auch mit 1.2 warum eigentlich? Da er aber, > sobald ich Variablen ins spiel bringe, nicht mehr mit 1.2 rechnet > sondern abrundet auf 1, muss ich eben mal 12 multiplizieren und dann > später durch 10 dividieren. Hallo, Im Fall mit den 1.2 rechnest Du mit einer konstanten, packst Du diese aber in eine Integer-Variable, die nur Ganzzahlen kann, dann wird der Wert gerundet. Du kannst also, wie Du es schon versucht hast, deinen Wert mal 12 nehmen und dann durch 10 teilen.
Seijsschmeer schrieb: > int b = ((500-600)*1.2)+500; In diesem Fall rechnet der Mikrocontroller überhaupt nicht. Es wird nur die Variable b mit dem Wert 380 initialisiert. Mehr nicht. Die Rechenarbeit übernimmt der Compiler während der Übersetzungszeit. Wahrscheinlich rechnet aber auch der Compiler nichts, denn die Variable b wird nirgends verwendet und daher "wegoptimiert".
Außerdem ist anzumerken dass die Formeln für b und Sollwert verschieden sind, denn die Division durch 10 ist in Sollwert falsch gesetzt.
Danke schonmal für die antworten. Wobei mein eigentliches problem bei der zweiten rechnung liegt, die mit der variablen "sollwert". Sobald ich durchsteppe, hängt sich das programm an dieser stelle auf. Und es hat irgendwas mit der division durch 10 zu tun. Ich weiß nur nicht was. Sobald ich die division herausnehme, funktioniert die rechnung. Mfg
... *Heizkurve)÷10)+ konstante Ansonsten würdest du nämlich nicht die konstante addieren sondern nur (konstante/10)
Leider funktioniert das so auch nicht. Sobald ich eine Variable dividieren möchte funktionierts nicht, also avr studio springt in die disassembly tabelle und das Prog hängt sich auf. Habe jetzt einfach mal folgende Zeile hineingeschrieben. int test = konstante (hat der wert von 500) /10; funktioniert auch nicht. Wenn ich die 10 selbst als Int Variable deklariere und dieser den Wert 10 zuweise geht es auch nicht, also z.B. int div = 10; int konstante =500; int test=konstante/div; Ich verzweifel noch, bei sowas simplen eigentlich oder eher doch nicht... MfG
Poste doch mal den disassenmby des Programms hier hin. Hast du eventuell (aus versehen) in die folgezeile einen breakpoint gesetzt?
00000063 97.fb BST R25,7 Bit store from register to T Auf diese Zeile werde ich direkt verwiesen
du solltest schonmal etwas mehr posten als das also z.b. die komplette while schleife
Da ich nicht genau weiß was du brauchst, das hier ist alles von Anfang bis zu der Zeile in der ich verwiesen werde. --- No source file ------------------------------------------------------------- 00000000 12.c0 RJMP PC+0x0013 Relative jump 00000001 2c.c0 RJMP PC+0x002D Relative jump 00000002 2b.c0 RJMP PC+0x002C Relative jump 00000003 2a.c0 RJMP PC+0x002B Relative jump 00000004 29.c0 RJMP PC+0x002A Relative jump 00000005 28.c0 RJMP PC+0x0029 Relative jump 00000006 27.c0 RJMP PC+0x0028 Relative jump 00000007 26.c0 RJMP PC+0x0027 Relative jump 00000008 25.c0 RJMP PC+0x0026 Relative jump 00000009 24.c0 RJMP PC+0x0025 Relative jump 0000000A 23.c0 RJMP PC+0x0024 Relative jump 0000000B 22.c0 RJMP PC+0x0023 Relative jump 0000000C 21.c0 RJMP PC+0x0022 Relative jump 0000000D 20.c0 RJMP PC+0x0021 Relative jump 0000000E 1f.c0 RJMP PC+0x0020 Relative jump 0000000F 1e.c0 RJMP PC+0x001F Relative jump 00000010 1d.c0 RJMP PC+0x001E Relative jump 00000011 1c.c0 RJMP PC+0x001D Relative jump 00000012 1b.c0 RJMP PC+0x001C Relative jump 00000013 11.24 CLR R1 Clear Register 00000014 1f.be OUT 0x3F,R1 Out to I/O location 00000015 cf.e5 LDI R28,0x5F Load immediate 00000016 d4.e0 LDI R29,0x04 Load immediate 00000017 de.bf OUT 0x3E,R29 Out to I/O location 00000018 cd.bf OUT 0x3D,R28 Out to I/O location --- C:\home\tools\hudson\workspace\avr8-gnu-toolchain\src\gcc\gcc\config\avr \libgcc.S 1: 00000019 10.e0 LDI R17,0x00 Load immediate 1: 0000001A a0.e6 LDI R26,0x60 Load immediate 1: 0000001B b0.e0 LDI R27,0x00 Load immediate 1: 0000001C e8.ed LDI R30,0xD8 Load immediate 1: 0000001D f0.e0 LDI R31,0x00 Load immediate --- C:\home\tools\hudson\workspace\avr8-gnu-toolchain\src\gcc\gcc\config\avr \libgcc.S 1: 0000001E 02.c0 RJMP PC+0x0003 Relative jump 1: 0000001F 05.90 LPM R0,Z+ Load program memory and postincrement 1: 00000020 0d.92 ST X+,R0 Store indirect and postincrement 1: 00000021 a0.36 CPI R26,0x60 Compare with immediate 1: 00000022 b1.07 CPC R27,R17 Compare with carry 1: 00000023 d9.f7 BRNE PC-0x04 Branch if not equal 1: 00000024 10.e0 LDI R17,0x00 Load immediate 1: 00000025 a0.e6 LDI R26,0x60 Load immediate 1: 00000026 b0.e0 LDI R27,0x00 Load immediate 1: 00000027 01.c0 RJMP PC+0x0002 Relative jump 1: 00000028 1d.92 ST X+,R1 Store indirect and postincrement 1: 00000029 a0.36 CPI R26,0x60 Compare with immediate 1: 0000002A b1.07 CPC R27,R17 Compare with carry 1: 0000002B e1.f7 BRNE PC-0x03 Branch if not equal --- No source file ------------------------------------------------------------- 0000002C 02.d0 RCALL PC+0x0003 Relative call subroutine 0000002D 3c.c0 RJMP PC+0x003D Relative jump 0000002E d1.cf RJMP PC-0x002E Relative jump --- C:\Users\Alex\Documents\Atmel Studio\Heizung\Heizung\Debug/.././Heizung.c -- 15: { 0000002F cf.93 PUSH R28 Push register on stack 00000030 df.93 PUSH R29 Push register on stack 00000031 00.d0 RCALL PC+0x0001 Relative call subroutine 00000032 00.d0 RCALL PC+0x0001 Relative call subroutine 00000033 cd.b7 IN R28,0x3D In from I/O location 00000034 de.b7 IN R29,0x3E In from I/O location 19: int konstante = 500; 00000035 84.ef LDI R24,0xF4 Load immediate 00000036 91.e0 LDI R25,0x01 Load immediate 00000037 9a.83 STD Y+2,R25 Store indirect with displacement 00000038 89.83 STD Y+1,R24 Store indirect with displacement 23: int test = konstante/10; 00000039 89.81 LDD R24,Y+1 Load indirect with displacement 0000003A 9a.81 LDD R25,Y+2 Load indirect with displacement 0000003B 2a.e0 LDI R18,0x0A Load immediate --- C:\Users\Alex\Documents\Atmel Studio\Heizung\Heizung\Debug/.././Heizung.c -- 0000003C 30.e0 LDI R19,0x00 Load immediate 0000003D b9.01 MOVW R22,R18 Copy register pair 0000003E 04.d0 RCALL PC+0x0005 Relative call subroutine 0000003F 9b.01 MOVW R18,R22 Copy register pair 00000040 3c.83 STD Y+4,R19 Store indirect with displacement 00000041 2b.83 STD Y+3,R18 Store indirect with displacement 25: } 00000042 f6.cf RJMP PC-0x0009 Relative jump --- C:\home\tools\hudson\workspace\avr8-gnu-toolchain\src\gcc\gcc\config\avr \libgcc.S 1: 00000043 97.fb BST R25,7 Bit store from register to T
>Da ich nicht genau weiß was du brauchst,
Das komplette Projekt? So das man das auch mal selber kompilieren
könnte?
Mehr ist das nicht... #include <avr/io.h> int main(void) { int konstante = 500; while(1) { int test = konstante/10; } }
>Mehr ist das nicht...
Wird wegoptimiert wenn die Optimierung eingeschaltet ist.
Versuchs mal so:
1 | #include <avr/io.h> |
2 | |
3 | |
4 | int main(void) |
5 | {
|
6 | |
7 | volatile int konstante = 500; |
8 | |
9 | while(1) |
10 | {
|
11 | volatile int test = konstante/10; |
12 | }
|
13 | }
|
also im disassembly sehe ich wie 500 und 10 in den registern landen. ich sehe aber nirgends die ausführung der division. schreib mal bitte unter die division PORTA=test>>8; PORTB=test & 0xff; das zwingt den kompiler das ergebnis an den ports auszugeben und die division wird entweder ausgeführt oder durch den compiler vorberechnet.
@ holger, funktioniert leider auch nicht, hatte es damit aber auch schon probiert gehabt, ich vergaß zu erwähnen das die Optmierung ausgeschaltet ist, sorry. @ich, nicht du, leider auch kein Erfolg mit deiner Variante. In der disassembly Liste steht doch was über die Division, 23:.....oder nicht? Kann es sein das Generell Divisionen einen großen Akt darstellen, habe ja vorher schonmal nach Lösungen gegoogelt, da wird dann Registerschieberei erwähnt, oder es wurden eigene Algorithmen geschrieben usw...z.B. hier http://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Division.htm Versteh da leider nur Bahnhof.
Man definiert doch keine Variablen in einer Schleife oO Zudem gewöhnte dir int ab und bedenke, das du der 10 den entsprechenden Variablentyp anhängen solltest...
Da ist ja momentan ein reines Testprogram, ich definiere keine Variablen in einer Schleife, wenn ich sie vorher deklariere passiert das selbe. sunfloweer_seed schrieb: > Zudem gewöhnte dir int ab und bedenke, das du der 10 den entsprechenden > Variablentyp anhängen solltest... wie soll ich das verstehen? Falls du meinst das ich eine Integervariable erstellen sollte und der den Wert 10 zuweisen sollte, funktioniert auch nicht. Und was meinst du mit Integer abgewöhnen? Ich möchte aber damit rechnen...
Ein Integer ist aber nicht gleich Integer: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_Datentypen_.28Integer.29 Du musst überlegen wie groß das Ergebnis werden soll. Standardmäßig erzeugt die Division immer ein int16 Wert oder iwie sowas. Eventuell musst du ein Cast machen oder zur Sicherheit einfach dem dividenden der Konstanten einen Datentyp zuweisen: http://www.mikrocontroller.net/articles/FAQ (Datentypen in Operationen und Welche Datentypen haben Konstanten)
Seijsschmeer: Probier es mit Bounenschlupp, das geht bestimmt besser. ;-)
Die volatile-Variablen sollten auf globaler Ebene sein. Innerhalb der Funktion machts nicht viel Sinn, da dort von außerhalb keine Zugriffsmöglichkeit besteht. Probiers mal so:
1 | volatile int konstante = 500; |
2 | volatile int test; |
3 | |
4 | int main(void) |
5 | {
|
6 | while(1) |
7 | {
|
8 | test = konstante / 10; |
9 | }
|
10 | }
|
Wilhelm F. schrieb: > Seijsschmeer: > > Probier es mit Bounenschlupp, das geht bestimmt besser. ;-) Wasn das?? @ Hans funtkioniert auch nicht, alles schon probiert...
@sunflower Hab sämtliche Datentypen durch, die Konstanten auch gecastet usw. leider kein Erfolg. Sobald ich aber durch "digitale" Zahlen dividiere also durch 2,4,8,16 usw funktioniert es Problemlos...habs auch schon mit hex Schreibweise probiert...auch nichts.
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.