Hallo Zusammen, gibt es eine Möglichkeit Codesequenzen innerhalb der Hauptschleife respektive in while(1) auszulagern? Ich habe z.B. Codesequenzen, welche mehrmals gebraucht werden in der Schleife. Danke und Gruss Alain void Programmteil1(void) while(1); Programmteil1();
klar, in eine eigene funktion auslagern und daran denken, dass d die nötigen parameter übergiebst
Stichwort: Strukturierte Programmierung. Wenn es sehr, sehr, sehr zeitkritisch ist, geht das auch per include. Das ist aber kein guter Stil.
Da ist das Problem ich habe es schon wie oben ausprobiert. Das geht auch, aber wenn ich Variablen etc. habe dann klappt das nicht mehr. Gibt es da ein Beispiel?
Alain F. schrieb: > Gibt es da ein Beispiel? ja in jeden C bucht. Versuch es doch einfach mal, wenn es fehler gib dann frag uns.
> Wenn es sehr, sehr, sehr zeitkritisch ist, geht das auch per include.
Das macht man dann aber eher per inline als per include.
Alain F. schrieb: > Da ist das Problem ich habe es schon wie oben ausprobiert. Das geht > auch, aber wenn ich Variablen etc. habe dann klappt das nicht mehr. Geht es dir darum, einfach nur den Programmcode, also den reinen Programmtext mehrfach zu verwenden? Dann mach das mit "#define". Beispiel:
1 | #define IRGENDWAS a= 1; \
|
2 | b= 2;
|
3 | |
4 | while(i==0) { |
5 | IRGENDWAS
|
6 | i++; |
7 | }
|
8 | IRGENDWAS
|
9 | c= 3; |
>> The specification for inline is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). http://www.greenend.org.uk/rjk/tech/inline.html
int16_t foo () schrieb: > inline gehört zu C++ oder auch nicht http://www.greenend.org.uk/rjk/tech/inline.html
Peter II schrieb: > oder auch nicht > http://www.greenend.org.uk/rjk/tech/inline.html Ok, wieder etwas gelernt. :-) Aber ist inline nicht nur eine Empfehlung an den Compiler? Oder wird garantiert der Code eingefügt?
Er muss das beim Kompilieren dann nicht berücksichtigen, wenn er nicht will. Aber es geht ja um den Code, nicht darum, was der Compiler daraus macht!
Markus E. schrieb: > Aber es geht ja um den Code, nicht darum, was der Compiler daraus macht! Nö, es geht hier darum, den Code an der Stelle einzufügen, also genau das was der Compiler daraus macht! Sonst nimmt natürlich Funktionen.
Alain F. schrieb: > while(1); > > Programmteil1(); zum Programmteil1 kommt das Programm nie, bei Makros gibt es auch einen beliebten Fehler: #define IRGENDWAS a= 1; \ b= 2; while(i==0) IRGENDWAS macht nicht das was du eigentlich vor hattest
int16_t foo () schrieb: > Nö, es geht hier darum, den Code an der Stelle einzufügen, also genau > das was der Compiler daraus macht! denke ich nicht, es soll so aussehen ob der code an der stelle ist. Ob der Funktionaufruf noch stattfindet wird den Threadersteller ziemlich egal sein. Wer solche Fragen stellt, schreibt allegmeint nicht hochoptimierten C code wo es auf 4 Takte drauf ankommt.
Peter II schrieb: > denke ich nicht, int16_t foo () schrieb: > Wenn es sehr, sehr, sehr zeitkritisch ist, geht das auch per include. Ich beziehe mich auf meinen Post und die Variante mit include. Dann bekomme ich garantiert den Code an den gewünschten Punkt. Und: int16_t foo () schrieb: > Das ist aber kein guter Stil. Bitte die letzten Post in diesem Zusammenhang sehen.
genau der Code sollte genau an dieser Stelle so eingesetzt werden. void sleep_p(void){ } und einfügen geht nicht. Copile Error. #define benutze ich schon z.B. für das #define Enable (1<<PD5). ist aber auch das falsche. Denn auch hier werden die Variablen etc. nicht berücksichtigt. Ich möchte einfach den Code 1:1 rauskopieren z.B.
1 | Code 1 { |
2 | bla bla bla |
3 | }
|
4 | |
5 | int main (void) { |
6 | while(1){ |
7 | Code 1; |
8 | }
|
9 | }
|
Alain F. schrieb: > Ich möchte einfach den Code 1:1 rauskopieren z.B. > Code 1 { > bla bla bla > } > main{} > while(1){ > Code 1; > } > } zeig uns bitte ein sinnvolles Beispiel. Dann es muss gehen. Es sollte also wenigstens sinnvoller C code sein.
Alain F. schrieb: > #define benutze ich schon z.B. für das #define Enable (1<<PD5). > ist aber auch das falsche. Denn auch hier werden die Variablen etc. > nicht berücksichtigt. Doch, "#define" ist schon richtig. Ich hab dein Beispiel mal umgebaut:
1 | #define CODE(x) { \
|
2 | bla bla \
|
3 | variable= x; \
|
4 | bla bla \
|
5 | }
|
6 | |
7 | int main (void) { |
8 | while(1){ |
9 | CODE(1) |
10 | }
|
11 | }
|
1 | #define LED4 (1<<PD0)
|
2 | #define LED3 (1<<PD1)
|
3 | #define LED2 (1<<PD7)
|
4 | #define LED1 (1<<PD4)
|
5 | |
6 | int main (void) { |
7 | |
8 | while(1){ |
9 | |
10 | if ( (DIM_value == 290) ){ |
11 | PORTD&=~LED1; |
12 | PORTD&=~LED2; |
13 | PORTD|=LED3; |
14 | PORTD&=~LED4; |
15 | _delay_ms(500); |
16 | }
|
17 | |
18 | }
|
19 | }
|
so ich hätte jetzt gerne den ganzen Block if ausgelagert. z.B.
1 | #define LED4 (1<<PD0)
|
2 | #define LED3 (1<<PD1)
|
3 | #define LED2 (1<<PD7)
|
4 | #define LED1 (1<<PD4)
|
5 | |
6 | int main (void) { |
7 | |
8 | while(1){ |
9 | Code1; |
10 | }
|
11 | }
|
12 | |
13 | Code1{ |
14 | if ( (DIM_value == 290) ){ |
15 | PORTD&=~LED1; |
16 | PORTD&=~LED2; |
17 | PORTD|=LED3; |
18 | PORTD&=~LED4; |
19 | _delay_ms(500); |
20 | }
|
21 | }
|
#define ist erstmal der falsche weg, schreibe eine normale funktion. #defines sind mehr eine notlösung. Versuche es erstmal so es andere auch machen - mit funktionen.
1 | #define LED4 (1<<PD0)
|
2 | #define LED3 (1<<PD1)
|
3 | #define LED2 (1<<PD7)
|
4 | #define LED1 (1<<PD4)
|
5 | |
6 | void Code1() { |
7 | if ( (DIM_value == 290) ){ |
8 | PORTD&=~LED1; |
9 | PORTD&=~LED2; |
10 | PORTD|=LED3; |
11 | PORTD&=~LED4; |
12 | _delay_ms(500); |
13 | }
|
14 | };
|
15 | |
16 | |
17 | int main (void) { |
18 | while(1){ |
19 | Code1(); |
20 | }
|
21 | }
|
so sollte es passen.
es geht auch nicht um die defines diese finde ich gut, z.B. wenn man den Pin ändert etc. dann kann man nur ganz oben im Code den neuen Pin zuweisen und gut ist. Ausserdem gibt es eine Übersicht. Aber das ist hier nicht die Frage, sondern wie bekomme ich irgend einen Code raus. das muss doch gehen, das der Compiler diesen Code in einem Abschnitt genau so in mein Code einfügt als ob er dort stehen würde.
@Peter II make: *** [ATMEGA8.o] Fehler 1 Build failed with 3 errors and 11 warnings...
Alain F. schrieb: > make: *** [ATMEGA8.o] Fehler 1 > > Build failed with 3 errors and 11 warnings... und welche Fehler?
../ATMEGA8.c:511:1: warning: implicit declaration of function 'Sleep_p'
Alain F. schrieb: > 'Sleep_p' kommt doch im code überhaupt nicht vor? welche includes hast du noch? Zeig doch mal den completten code.
Alain F. schrieb: > Aber das ist hier nicht die Frage, sondern wie bekomme ich irgend einen > Code raus. das muss doch gehen, das der Compiler diesen Code in einem > Abschnitt genau so in mein Code einfügt als ob er dort stehen würde. Nicht der Compiler, sondern der preprocessor. Das Zauberwort heisst include, auch wenn es den anderen Jungs nicht schmeckt.
Ich kann nicht den ganzen Code posten ist zu lang und zu komplex. ich habe:
1 | void sleep_p() { |
2 | PORTD&=~LED1; |
3 | PORTD&=~LED2; |
4 | PORTD&=~LED3; |
5 | PORTD&=~LED4; |
6 | |
7 | Off2:; |
8 | |
9 | EIMSK |= (1 << INT0); // Interupt auf INT0 freigeben |
10 | |
11 | Off:; //OFF Marker |
12 | On = 0; |
13 | PORTD&=~Enable; |
14 | ADMUX = 0b00000000; // Internal Reference Disabled |
15 | ADCSRA = ~(1<<ADEN); //ADC Disable = Stromsparen 0.3mA |
16 | TCCR1A = ~(1<<COM1A1); // Disable PWM |
17 | _delay_ms(150); |
18 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
19 | sleep_mode(); |
20 | }
|
vor main so hinzugefügt und
1 | im while hier eingefügt: |
2 | if (Sleep_c == 1) { |
3 | |
4 | sleep_p(); |
5 | |
6 | }
|
Hi Alain, ich habe keine Möglichkeit, es auszuprobieren. Allerdings sehe ich einen gravierenden Fehler in deinem Code: Du definierst die Funktion Code1 NACH der main Funktion. In C geht das nicht. Also entweder wie Peter die Funktion VOR der main Funktion schreiben, oder aber NACH der main Funktion (wie du es gemacht hast) - dann aber vorher deklarieren.
1 | void Code1(); |
2 | ...
|
3 | ...
|
4 | ...
|
5 | deine main funktion |
6 | |
7 | ...
|
8 | ...
|
9 | ...
|
10 | void Code1() { |
11 | if ( (DIM_value == 290) ){ |
12 | PORTD&=~LED1; |
13 | PORTD&=~LED2; |
14 | PORTD|=LED3; |
15 | PORTD&=~LED4; |
16 | _delay_ms(500); |
17 | }
|
18 | };
|
Gruß
Alain F. schrieb: > Ich kann nicht den ganzen Code posten ist zu lang und zu komplex. also das Forum hat keine Begrenzung. Wenn du ihn nicht posten willst uns die fehler nicht nennst. Dann kann man dir leider auch kaum helfen.
Wobei ich finde, dass die Warnung ziemlich eindeutig klingt: Alain F. schrieb: > ../ATMEGA8.c:511:1: warning: implicit declaration of function 'Sleep_p' http://www.cplusplus.com/doc/tutorial/functions2/ Abschnitt "Declaring functions" Oder übersehe ich etwas? Gruß
Ja okay, ich habe einen wesentlichen Beitrag überlesen. Alain F. schrieb: > Some code... > vor main so hinzugefügt undim while hier eingefügt: > if (Sleep_c == 1) { > > sleep_p(); > > } Mein Fehler :)
BaldAbsolvent schrieb: > Wobei ich finde, dass die Warnung ziemlich eindeutig klingt: das ist aber nur dir Warung, diese könnte man in diesem fall ignorieren, es würde auch so gehen. > Build failed with 3 errors and 11 warnings... mich stören mehr diese 3 errors
Hi, Wo ist der Unterschied zwischen "Sleep_p" und "sleep_p" bei dir im Code? Alain F. schrieb: > void sleep_p() { > PORTD&=~LED1; > PORTD&=~LED2; > PORTD&=~LED3; > PORTD&=~LED4; > > Off2:; > > EIMSK |= (1 << INT0); // Interupt auf INT0 freigeben > > Off:; //OFF Marker > On = 0; > PORTD&=~Enable; > ADMUX = 0b00000000; // Internal Reference Disabled > ADCSRA = ~(1<<ADEN); //ADC Disable = Stromsparen 0.3mA > TCCR1A = ~(1<<COM1A1); // Disable PWM > _delay_ms(150); > set_sleep_mode(SLEEP_MODE_PWR_DOWN); > sleep_mode(); > } Alain F. schrieb: > ../ATMEGA8.c:511:1: warning: implicit declaration of function 'Sleep_p'
so habe den Code gekürzt. Also ich möchte alles was in if (Sleep_c == 1) auslagern.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <inttypes.h> |
4 | #include <avr/pgmspace.h> |
5 | #include <avr/wdt.h> |
6 | #include <avr/sleep.h> |
7 | #include <math.h> |
8 | #include <avr/eeprom.h> |
9 | |
10 | |
11 | #define F_CPU 2000000UL /* Quarz mit 8.0Mhz */ |
12 | #include <util/delay.h> |
13 | |
14 | |
15 | |
16 | #define Enable (1<<PD5)
|
17 | #define PWM (1<<PB1)
|
18 | |
19 | |
20 | |
21 | #define Taster_INT0 (1<<PD2)
|
22 | // PinB5 ON = Never off UnderVoltageCutOut OFF
|
23 | // PinB4 ON = Power on on Voltage
|
24 | |
25 | |
26 | #define fosc 2000000 //Taktfrequenz in Hz
|
27 | #define UpperLimit (unsigned int) (fosc*0.0022) // Anzahl Ticks für 2,2ms
|
28 | #define LowerLimit (unsigned int) (fosc*0.0008) // Anzahl Ticks für 0,8ms
|
29 | #define Middle (unsigned int) (fosc*0.0015) // Anzahl Ticks für 1,5ms
|
30 | |
31 | |
32 | //************************************************************************
|
33 | //------------------------------------------------------------------------
|
34 | //************************************************************************
|
35 | //------------------------------------------------------------------------
|
36 | // Hauptprogramm
|
37 | //------------------------------------------------------------------------
|
38 | //************************************************************************
|
39 | //------------------------------------------------------------------------
|
40 | //************************************************************************
|
41 | |
42 | int main (void) { |
43 | |
44 | |
45 | |
46 | |
47 | //------------------------------------------------------------------------
|
48 | // PORTX DDRX
|
49 | //------------------------------------------------------------------------
|
50 | DDRB = 0b00111110; //0= Eingang; 1 = Ausgang |
51 | PORTB = 0b00111110; //0= act. Low; 1 =act. High |
52 | |
53 | DDRC = 0b00000000; //0= Eingang; 1 = Ausgang |
54 | PORTC = 0b00000000; //0= act. Low; 1 =act. High |
55 | |
56 | DDRD = 0b11110011; //0= Eingang; 1 = Ausgang |
57 | PORTD = 0b01001100; //0= act. Low; 1 =act. High |
58 | |
59 | |
60 | //------------------------------------------------------------------------
|
61 | // ADMUX-Register
|
62 | //------------------------------------------------------------------------
|
63 | |
64 | ADMUX = 0b00000000; // Für interne Referenzspannung ADMUX = 0b11000000; 88P = Internal 1.1V Voltage Reference with external capacitor at AREF pin |
65 | // auch ADMUX = 2; (Kanalnummer) oder ADMUX = 0b00000010;
|
66 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; // Initialisierung des ADC über das ADCSRA-Register |
67 | // ADCSRA = 10000111
|
68 | |
69 | |
70 | //------------------------------------------------------------------------
|
71 | // PWM Register
|
72 | //------------------------------------------------------------------------
|
73 | |
74 | TCCR1A = (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1) ; // 8bit PWM-Modus, nicht invertiernde PWM |
75 | TCCR1B = (1<<CS11); // PWM-Signal Takt Clock / 8 = 500Hz (LM3421 max 50kHz) |
76 | |
77 | //------------------------------------------------------------------------
|
78 | // Interrupt
|
79 | //------------------------------------------------------------------------
|
80 | |
81 | ACSR = 0x80; // Analogcomparator ausschalten |
82 | MCUCR &= ~00000011; // levelgesteuerter Interrupt an INT0 |
83 | sei(); // Interrupts freigeben |
84 | |
85 | //------------------------------------------------------------------------
|
86 | // Watch Dog
|
87 | //------------------------------------------------------------------------
|
88 | |
89 | // wdt_enable(WDTO_500MS);
|
90 | |
91 | //------------------------------------------------------------------------
|
92 | // Variablen deklarieren
|
93 | //------------------------------------------------------------------------
|
94 | |
95 | int On = 1; |
96 | int x1 =0; |
97 | int x = 0; |
98 | int Modus = 1; |
99 | int DIM_value = 100; |
100 | int32_t Taster_Time =0; |
101 | int Sleep_c = 1; |
102 | |
103 | |
104 | //************************************************************************
|
105 | //------------------------------------------------------------------------
|
106 | // Hauptschleife
|
107 | //------------------------------------------------------------------------
|
108 | //************************************************************************
|
109 | |
110 | //if ( !(PINB & (1<<PINB4)) ){
|
111 | goto Jump_ON; |
112 | |
113 | //}
|
114 | |
115 | while(1){ |
116 | |
117 | //Sleep_c = 0;
|
118 | |
119 | |
120 | x1 = x1 + 1; |
121 | |
122 | //------------------------------------------------------------------------
|
123 | // Watch Dog
|
124 | //------------------------------------------------------------------------
|
125 | |
126 | // wdt_reset();
|
127 | |
128 | |
129 | //------------------------------------------------------------------------
|
130 | // Clock Speed
|
131 | //------------------------------------------------------------------------
|
132 | /*
|
133 | The CLKPCE bit must be written to logic one to enable change of the CLKPS bits. The CLKPCE
|
134 | bit is only updated when the other bits in CLKPR are simultaneously written to zero. CLKPCE is
|
135 | cleared by hardware four cycles after it is written or when CLKPS bits are written. Rewriting the
|
136 | CLKPCE bit within this time-out period does neither extend the time-out period, nor clear the
|
137 | CLKPCE bit.
|
138 | */
|
139 | CLKPR = 0b10000000; |
140 | |
141 | CLKPR = 0b00000010; // Clock divided / 4 = 2 Mhz |
142 | |
143 | |
144 | // ___________OCR1A Register für PWM Signal ___________________
|
145 | |
146 | |
147 | OCR1A = 1023; //White |
148 | |
149 | //____________________________________________________
|
150 | |
151 | |
152 | |
153 | |
154 | // ---------------- Anschalten (Aufstarten) ------------------
|
155 | if ( !(PIND & Taster_INT0 ) & (On == 0) ) { |
156 | Jump_ON:; //Jump_DIM Marker |
157 | sleep_disable(); |
158 | //wdt_enable(WDTO_500MS);
|
159 | Sleep_c = 0; |
160 | |
161 | EIMSK &= ~(1 << INT0); |
162 | ADMUX = 0b11000000; // Internal Reference Enabled |
163 | |
164 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; |
165 | |
166 | On = 1; |
167 | PORTD|=Enable; |
168 | _delay_ms(150); |
169 | |
170 | }
|
171 | |
172 | |
173 | |
174 | // ---------------- Ausschalten (Sleepmodus) ------------------
|
175 | Taster_Time = 0; |
176 | |
177 | while ( !(PIND & Taster_INT0 ) & (On == 1) ) { |
178 | |
179 | Sleep_c = 1; |
180 | }
|
181 | |
182 | |
183 | // ---------------- uC geht schlafen ------------------
|
184 | if (Sleep_c == 1) { |
185 | Off2:; |
186 | EIMSK |= (1 << INT0); // Interupt auf INT0 freigeben |
187 | Off:; //OFF Marker |
188 | On = 0; |
189 | PORTD&=~Enable; |
190 | ADMUX = 0b00000000; // Internal Reference Disabled |
191 | ADCSRA = ~(1<<ADEN); //ADC Disable = Stromsparen 0.3mA |
192 | TCCR1A = ~(1<<COM1A1); // Disable PWM |
193 | //wdt_disable(); // Watchdog ausaschalten
|
194 | _delay_ms(150); |
195 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
196 | sleep_mode(); |
197 | |
198 | }
|
199 | |
200 | |
201 | if (Sleep_c == 0) { |
202 | |
203 | }
|
204 | |
205 | |
206 | }
|
207 | }
|
208 | |
209 | ISR(INT0_vect) { // Interupt Rutine kann leer sein muss aber existieren |
210 | }
|
lösche bitte den code und fang noch mal von vorne an. Da sind mehre Labels in dem Teil den du auslagern möchstest - das geht dann aber nicht. Man darf nicht in ein Funktion reinspringen. Bitte verwende überhaupt keine gotos, es gibt gründe dafür aber hier bestimmt nicht.
Lieber Peter II, ich habe ja teile gelöscht aber das Programm funktioniert einwandfrei auch mit gotos. Es macht das was ich will und es braucht diese auch. Das einzige was ich möchte ist das know-how, wie man Teile auslagert da ich diese mehrmals brauche. Auch die Version oben ist gerade auf einem ATMEGA88p und an und abschalten klappt.
Alain F. schrieb: > Lieber Peter II, ich habe ja teile gelöscht aber das Programm > funktioniert einwandfrei auch mit gotos ich sage ja nicht das es nicht funktioniert oder fehlerhaft ist. Es ist nicht mehr wartbar. Mit diesen goto geht es ebend nicht das in funktionen auszulagern. Du bist jetzt an einem punkt wo das Progamm immer schlimmer wird und du führer oder später nicht mehr duchsiehst. Wenn du ohne gotos arbeitest hättest du gleich ein saubere Programm aufbau und das auslagern von funktionen geht dann auch. Sieht als lernphase an, die (fast)jeder schon durchgemacht hat.
Programmiertechnisch und Übersichtlich wäre es von Vorteil. Ich kann die selben Stellen auch mehrmals kopieren aber das beeinträchtigt die Übersichtlichkeit und die Fehler bei Änderungen sind grösser. Es muss doch eine vernünftige Lösung dafür geben.
Alain F. schrieb: > Es muss doch eine vernünftige Lösung dafür geben. Die gibt es: Ordentlich programmieren, ohne gotos!
OK ignorieren wir mal die gotos. beim obigen Code kann man da auch darauf verzichten, weil die Sprünge im Sleep eh nicht gebraucht werden. Auch ohne gotos kommt diese Meldung: Build started 7.4.2012 at 00:20:06 avr-gcc -mmcu=atmega88p -Wall -gdwarf-2 -std=gnu99 -DF_CPU=2000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT ATMEGA8.o -MF dep/ATMEGA8.o.d -c ../ATMEGA8.c ../ATMEGA8.c: In function 'sleep_p': ../ATMEGA8.c:45:1: error: 'On' undeclared (first use in this function) ../ATMEGA8.c:45:1: note: each undeclared identifier is reported only once for each function it appears in ../ATMEGA8.c:48:1: warning: large integer implicitly truncated to unsigned type ../ATMEGA8.c:49:1: warning: large integer implicitly truncated to unsigned type ../ATMEGA8.c: In function 'main': ../ATMEGA8.c:115:5: warning: unused variable 'DIM_value' ../ATMEGA8.c:114:5: warning: unused variable 'Modus' ../ATMEGA8.c:113:5: warning: unused variable 'x' make: *** [ATMEGA8.o] Fehler 1 Build failed with 1 errors and 5 warnings... wenn ich diesen code habe:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <inttypes.h> |
4 | #include <avr/pgmspace.h> |
5 | #include <avr/wdt.h> |
6 | #include <avr/sleep.h> |
7 | #include <math.h> |
8 | #include <avr/eeprom.h> |
9 | |
10 | |
11 | #define F_CPU 2000000UL /* Quarz mit 8.0Mhz */ |
12 | #include <util/delay.h> |
13 | |
14 | |
15 | |
16 | #define Enable (1<<PD5)
|
17 | #define PWM (1<<PB1)
|
18 | |
19 | |
20 | |
21 | #define Taster_INT0 (1<<PD2)
|
22 | // PinB5 ON = Never off UnderVoltageCutOut OFF
|
23 | // PinB4 ON = Power on on Voltage
|
24 | |
25 | |
26 | #define fosc 2000000 //Taktfrequenz in Hz
|
27 | #define UpperLimit (unsigned int) (fosc*0.0022) // Anzahl Ticks für 2,2ms
|
28 | #define LowerLimit (unsigned int) (fosc*0.0008) // Anzahl Ticks für 0,8ms
|
29 | #define Middle (unsigned int) (fosc*0.0015) // Anzahl Ticks für 1,5ms
|
30 | |
31 | |
32 | //************************************************************************
|
33 | //------------------------------------------------------------------------
|
34 | //************************************************************************
|
35 | //------------------------------------------------------------------------
|
36 | // Hauptprogramm
|
37 | //------------------------------------------------------------------------
|
38 | //************************************************************************
|
39 | //------------------------------------------------------------------------
|
40 | //************************************************************************
|
41 | |
42 | |
43 | void sleep_p() { |
44 | EIMSK |= (1 << INT0); // Interupt auf INT0 freigeben |
45 | On = 0; |
46 | PORTD&=~Enable; |
47 | ADMUX = 0b00000000; // Internal Reference Disabled |
48 | ADCSRA = ~(1<<ADEN); //ADC Disable = Stromsparen 0.3mA |
49 | TCCR1A = ~(1<<COM1A1); // Disable PWM |
50 | //wdt_disable(); // Watchdog ausaschalten
|
51 | _delay_ms(150); |
52 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
53 | sleep_mode(); |
54 | }
|
55 | |
56 | |
57 | |
58 | int main (void) { |
59 | |
60 | |
61 | |
62 | |
63 | //------------------------------------------------------------------------
|
64 | // PORTX DDRX
|
65 | //------------------------------------------------------------------------
|
66 | DDRB = 0b00111110; //0= Eingang; 1 = Ausgang |
67 | PORTB = 0b00111110; //0= act. Low; 1 =act. High |
68 | |
69 | DDRC = 0b00000000; //0= Eingang; 1 = Ausgang |
70 | PORTC = 0b00000000; //0= act. Low; 1 =act. High |
71 | |
72 | DDRD = 0b11110011; //0= Eingang; 1 = Ausgang |
73 | PORTD = 0b01001100; //0= act. Low; 1 =act. High |
74 | |
75 | |
76 | //------------------------------------------------------------------------
|
77 | // ADMUX-Register
|
78 | //------------------------------------------------------------------------
|
79 | |
80 | ADMUX = 0b00000000; // Für interne Referenzspannung ADMUX = 0b11000000; 88P = Internal 1.1V Voltage Reference with external capacitor at AREF pin |
81 | // auch ADMUX = 2; (Kanalnummer) oder ADMUX = 0b00000010;
|
82 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; // Initialisierung des ADC über das ADCSRA-Register |
83 | // ADCSRA = 10000111
|
84 | |
85 | |
86 | //------------------------------------------------------------------------
|
87 | // PWM Register
|
88 | //------------------------------------------------------------------------
|
89 | |
90 | TCCR1A = (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1) ; // 8bit PWM-Modus, nicht invertiernde PWM |
91 | TCCR1B = (1<<CS11); // PWM-Signal Takt Clock / 8 = 500Hz (LM3421 max 50kHz) |
92 | |
93 | //------------------------------------------------------------------------
|
94 | // Interrupt
|
95 | //------------------------------------------------------------------------
|
96 | |
97 | ACSR = 0x80; // Analogcomparator ausschalten |
98 | MCUCR &= ~00000011; // levelgesteuerter Interrupt an INT0 |
99 | sei(); // Interrupts freigeben |
100 | |
101 | //------------------------------------------------------------------------
|
102 | // Watch Dog
|
103 | //------------------------------------------------------------------------
|
104 | |
105 | // wdt_enable(WDTO_500MS);
|
106 | |
107 | //------------------------------------------------------------------------
|
108 | // Variablen deklarieren
|
109 | //------------------------------------------------------------------------
|
110 | |
111 | int On = 1; |
112 | int x1 =0; |
113 | int x = 0; |
114 | int Modus = 1; |
115 | int DIM_value = 100; |
116 | int32_t Taster_Time =0; |
117 | int Sleep_c = 1; |
118 | |
119 | |
120 | //************************************************************************
|
121 | //------------------------------------------------------------------------
|
122 | // Hauptschleife
|
123 | //------------------------------------------------------------------------
|
124 | //************************************************************************
|
125 | |
126 | //if ( !(PINB & (1<<PINB4)) ){
|
127 | goto Jump_ON; |
128 | |
129 | //}
|
130 | |
131 | while(1){ |
132 | |
133 | //Sleep_c = 0;
|
134 | |
135 | |
136 | x1 = x1 + 1; |
137 | |
138 | //------------------------------------------------------------------------
|
139 | // Watch Dog
|
140 | //------------------------------------------------------------------------
|
141 | |
142 | // wdt_reset();
|
143 | |
144 | |
145 | //------------------------------------------------------------------------
|
146 | // Clock Speed
|
147 | //------------------------------------------------------------------------
|
148 | /*
|
149 | The CLKPCE bit must be written to logic one to enable change of the CLKPS bits. The CLKPCE
|
150 | bit is only updated when the other bits in CLKPR are simultaneously written to zero. CLKPCE is
|
151 | cleared by hardware four cycles after it is written or when CLKPS bits are written. Rewriting the
|
152 | CLKPCE bit within this time-out period does neither extend the time-out period, nor clear the
|
153 | CLKPCE bit.
|
154 | */
|
155 | CLKPR = 0b10000000; |
156 | |
157 | CLKPR = 0b00000010; // Clock divided / 4 = 2 Mhz |
158 | |
159 | |
160 | // ___________OCR1A Register für PWM Signal ___________________
|
161 | |
162 | |
163 | OCR1A = 1023; //White |
164 | |
165 | //____________________________________________________
|
166 | |
167 | |
168 | |
169 | |
170 | // ---------------- Anschalten (Aufstarten) ------------------
|
171 | if ( !(PIND & Taster_INT0 ) & (On == 0) ) { |
172 | Jump_ON:; //Jump_DIM Marker |
173 | sleep_disable(); |
174 | //wdt_enable(WDTO_500MS);
|
175 | Sleep_c = 0; |
176 | |
177 | EIMSK &= ~(1 << INT0); |
178 | ADMUX = 0b11000000; // Internal Reference Enabled |
179 | |
180 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; |
181 | |
182 | On = 1; |
183 | PORTD|=Enable; |
184 | _delay_ms(150); |
185 | |
186 | }
|
187 | |
188 | |
189 | |
190 | // ---------------- Ausschalten (Sleepmodus) ------------------
|
191 | Taster_Time = 0; |
192 | |
193 | while ( !(PIND & Taster_INT0 ) & (On == 1) ) { |
194 | |
195 | Sleep_c = 1; |
196 | }
|
197 | |
198 | |
199 | // ---------------- uC geht schlafen ------------------
|
200 | if (Sleep_c == 1) { |
201 | void Sleep_p(); |
202 | |
203 | }
|
204 | |
205 | |
206 | if (Sleep_c == 0) { |
207 | |
208 | }
|
209 | |
210 | |
211 | }
|
212 | }
|
213 | |
214 | ISR(INT0_vect) { // Interupt Rutine kann leer sein muss aber existieren |
215 | }
|
Alain F. schrieb: > ../ATMEGA8.c:45:1: error: 'On' undeclared (first use in this function) aber dein Butterbrot kannst du schon selber schmieren? Sorry, aber das musste sein
@Walter S.: Nein das mach mein Roboter für mich! Machst du das etwa noch immer selber? So konnte das zwar Compilieren und Brennen, aber das Programm funktioniert so nicht mehr.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <inttypes.h> |
4 | #include <avr/pgmspace.h> |
5 | #include <avr/wdt.h> |
6 | #include <avr/sleep.h> |
7 | #include <math.h> |
8 | #include <avr/eeprom.h> |
9 | |
10 | |
11 | #define F_CPU 2000000UL /* Quarz mit 8.0Mhz */ |
12 | #include <util/delay.h> |
13 | |
14 | |
15 | |
16 | #define Enable (1<<PD5)
|
17 | #define PWM (1<<PB1)
|
18 | |
19 | |
20 | |
21 | #define Taster_INT0 (1<<PD2)
|
22 | // PinB5 ON = Never off UnderVoltageCutOut OFF
|
23 | // PinB4 ON = Power on on Voltage
|
24 | |
25 | |
26 | #define fosc 2000000 //Taktfrequenz in Hz
|
27 | #define UpperLimit (unsigned int) (fosc*0.0022) // Anzahl Ticks für 2,2ms
|
28 | #define LowerLimit (unsigned int) (fosc*0.0008) // Anzahl Ticks für 0,8ms
|
29 | #define Middle (unsigned int) (fosc*0.0015) // Anzahl Ticks für 1,5ms
|
30 | |
31 | |
32 | //************************************************************************
|
33 | //------------------------------------------------------------------------
|
34 | //************************************************************************
|
35 | //------------------------------------------------------------------------
|
36 | // Hauptprogramm
|
37 | //------------------------------------------------------------------------
|
38 | //************************************************************************
|
39 | //------------------------------------------------------------------------
|
40 | //************************************************************************
|
41 | |
42 | |
43 | void sleep_p() { |
44 | EIMSK |= (1 << INT0); // Interupt auf INT0 freigeben |
45 | PORTD&=~Enable; |
46 | ADMUX = 0b00000000; // Internal Reference Disabled |
47 | ADCSRA = ~(1<<ADEN); //ADC Disable = Stromsparen 0.3mA |
48 | TCCR1A = ~(1<<COM1A1); // Disable PWM |
49 | //wdt_disable(); // Watchdog ausaschalten
|
50 | _delay_ms(150); |
51 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); |
52 | sleep_mode(); |
53 | }
|
54 | |
55 | |
56 | |
57 | int main (void) { |
58 | |
59 | |
60 | |
61 | |
62 | //------------------------------------------------------------------------
|
63 | // PORTX DDRX
|
64 | //------------------------------------------------------------------------
|
65 | DDRB = 0b00111110; //0= Eingang; 1 = Ausgang |
66 | PORTB = 0b00111110; //0= act. Low; 1 =act. High |
67 | |
68 | DDRC = 0b00000000; //0= Eingang; 1 = Ausgang |
69 | PORTC = 0b00000000; //0= act. Low; 1 =act. High |
70 | |
71 | DDRD = 0b11110011; //0= Eingang; 1 = Ausgang |
72 | PORTD = 0b01001100; //0= act. Low; 1 =act. High |
73 | |
74 | |
75 | //------------------------------------------------------------------------
|
76 | // ADMUX-Register
|
77 | //------------------------------------------------------------------------
|
78 | |
79 | ADMUX = 0b00000000; // Für interne Referenzspannung ADMUX = 0b11000000; 88P = Internal 1.1V Voltage Reference with external capacitor at AREF pin |
80 | // auch ADMUX = 2; (Kanalnummer) oder ADMUX = 0b00000010;
|
81 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; // Initialisierung des ADC über das ADCSRA-Register |
82 | // ADCSRA = 10000111
|
83 | |
84 | |
85 | //------------------------------------------------------------------------
|
86 | // PWM Register
|
87 | //------------------------------------------------------------------------
|
88 | |
89 | TCCR1A = (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1) ; // 8bit PWM-Modus, nicht invertiernde PWM |
90 | TCCR1B = (1<<CS11); // PWM-Signal Takt Clock / 8 = 500Hz (LM3421 max 50kHz) |
91 | |
92 | //------------------------------------------------------------------------
|
93 | // Interrupt
|
94 | //------------------------------------------------------------------------
|
95 | |
96 | ACSR = 0x80; // Analogcomparator ausschalten |
97 | MCUCR &= ~00000011; // levelgesteuerter Interrupt an INT0 |
98 | sei(); // Interrupts freigeben |
99 | |
100 | //------------------------------------------------------------------------
|
101 | // Watch Dog
|
102 | //------------------------------------------------------------------------
|
103 | |
104 | // wdt_enable(WDTO_500MS);
|
105 | |
106 | //------------------------------------------------------------------------
|
107 | // Variablen deklarieren
|
108 | //------------------------------------------------------------------------
|
109 | |
110 | static int On = 1; |
111 | int x1 =0; |
112 | int x = 0; |
113 | int Modus = 1; |
114 | int DIM_value = 100; |
115 | int32_t Taster_Time =0; |
116 | int Sleep_c = 1; |
117 | |
118 | |
119 | //************************************************************************
|
120 | //------------------------------------------------------------------------
|
121 | // Hauptschleife
|
122 | //------------------------------------------------------------------------
|
123 | //************************************************************************
|
124 | |
125 | //if ( !(PINB & (1<<PINB4)) ){
|
126 | goto Jump_ON; |
127 | |
128 | //}
|
129 | |
130 | while(1){ |
131 | |
132 | //Sleep_c = 0;
|
133 | |
134 | |
135 | x1 = x1 + 1; |
136 | |
137 | //------------------------------------------------------------------------
|
138 | // Watch Dog
|
139 | //------------------------------------------------------------------------
|
140 | |
141 | // wdt_reset();
|
142 | |
143 | |
144 | //------------------------------------------------------------------------
|
145 | // Clock Speed
|
146 | //------------------------------------------------------------------------
|
147 | /*
|
148 | The CLKPCE bit must be written to logic one to enable change of the CLKPS bits. The CLKPCE
|
149 | bit is only updated when the other bits in CLKPR are simultaneously written to zero. CLKPCE is
|
150 | cleared by hardware four cycles after it is written or when CLKPS bits are written. Rewriting the
|
151 | CLKPCE bit within this time-out period does neither extend the time-out period, nor clear the
|
152 | CLKPCE bit.
|
153 | */
|
154 | CLKPR = 0b10000000; |
155 | |
156 | CLKPR = 0b00000010; // Clock divided / 4 = 2 Mhz |
157 | |
158 | |
159 | // ___________OCR1A Register für PWM Signal ___________________
|
160 | |
161 | |
162 | OCR1A = 100; //White |
163 | |
164 | //____________________________________________________
|
165 | |
166 | |
167 | |
168 | |
169 | // ---------------- Anschalten (Aufstarten) ------------------
|
170 | if ( !(PIND & Taster_INT0 ) & (On == 0) ) { |
171 | Jump_ON:; //Jump_DIM Marker |
172 | sleep_disable(); |
173 | //wdt_enable(WDTO_500MS);
|
174 | Sleep_c = 0; |
175 | |
176 | EIMSK &= ~(1 << INT0); |
177 | ADMUX = 0b11000000; // Internal Reference Enabled |
178 | |
179 | ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0; |
180 | |
181 | On = 1; |
182 | PORTD|=Enable; |
183 | _delay_ms(150); |
184 | |
185 | }
|
186 | |
187 | |
188 | |
189 | // ---------------- Ausschalten (Sleepmodus) ------------------
|
190 | Taster_Time = 0; |
191 | |
192 | while ( !(PIND & Taster_INT0 ) & (On == 1) ) { |
193 | |
194 | Sleep_c = 1; |
195 | }
|
196 | |
197 | |
198 | // ---------------- uC geht schlafen ------------------
|
199 | if (Sleep_c == 1) { |
200 | On=0; |
201 | void Sleep_p(); |
202 | }
|
203 | |
204 | |
205 | if (Sleep_c == 0) { |
206 | |
207 | }
|
208 | |
209 | |
210 | }
|
211 | }
|
212 | |
213 | ISR(INT0_vect) { // Interupt Rutine kann leer sein muss aber existieren |
214 | }
|
Ach, das ist von einem Test. Der sollte nicht sein... ich bin langsam müde. Egal auch wenn ich das static weg mache dann klappt das Programm nicht mehr richtig.
Deklariere die Variable mal außerhalb der Main-Funktion.
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.