Hallo, ich programmiere eine Zündsteuerung in C auf dem ATMega 2561 für eine Thyristorschaltung. Die Steuerung soll durch Drücken eines Tasters gestartet werden und danach per Timer-Interrupts netzsynchrone Zündimpulse ausgeben. Das Ausgeben der Zündimpulse funktioniert einwandfrei, das heißt ich kann mir diese auf dem Oszilloskop anschauen und diese auch per Potentiometer verschieben. Nun zu dem Problem: Wenn ich nach dem Reset per Tastendruck die Steuerung einschalte, werden im ersten, sehr kurzen Moment, scheinbar zufällig, zu lange Impulse ausgegeben welche zu einem Kurzschluss führen. Nach diesem Einschaltvorgang sind aber alle Impulse sauber da und das Programm läuft einwandfrei. Beim erneuten Aus-/Einschalten tritt das Problem wieder auf. Zusätzlich verwende ich noch einen zweiten Taster, welcher nur zwischen zwei Thyristor-Gruppen wechselt, allerdings keine Interrupts ein- oder ausschaltet. Hier ist zu beobachten, dass ein Druck auf diesen Taster keines der oben genannten Probleme verursacht, sondern sauber die jeweiligen Impulse ausgegeben werden. Hier der gesamte Quellcode:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | #include <util/delay.h> |
4 | #include "ButtonPress.h" |
5 | |
6 | /*****************************VARIABLEN-Deklaration****************/
|
7 | int einschaltzustand = 0; |
8 | int zweiteHalbwelle = 0; |
9 | int ausschaltsicherung = 0; |
10 | volatile int Drehrichtung = 0; |
11 | |
12 | |
13 | uint16_t ADC_Wert; |
14 | |
15 | int ALPHA = 0; |
16 | int ALPHAmin = 6500; |
17 | int ALPHAmax = 18000; |
18 | |
19 | /*****************************PORT-Initialisierung*****************/
|
20 | void PortInit(void) |
21 | {
|
22 | DDRD &= ~(1<<PIND0); |
23 | DDRF &= ~(1<<PINF0); |
24 | DDRA &= ~((1<<PINA2) | (1<<PINA1)); |
25 | PORTA |= (1<<PINA2) | (1<<PINA1); |
26 | |
27 | DDRA |= (1<<PINA7) | (1<<PINA6) | (1<<PINA5) | (1<<PINA4); |
28 | PORTA &= ~((1<<PINA7) | (1<<PINA6) | (1<<PINA5) | (1<<PINA4)); |
29 | DDRB |= (1<<PINB2) | (1<<PINB3) | (1<<PINB4); |
30 | PORTB |= (1<<PINB2) | (1<<PINB3) | (1<<PINB4); |
31 | }
|
32 | |
33 | /*****************************TIMER1-Initialisierung***************/
|
34 | void Timer1Init(void) |
35 | {
|
36 | TCCR1B = 0x00; |
37 | TCCR1A = 0x00; |
38 | |
39 | TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B) | (1<<OCIE1C); |
40 | |
41 | EIMSK |= (1<<INT0); |
42 | EICRA |= (1<<ISC01); |
43 | |
44 | TCCR1B = 0x02; |
45 | }
|
46 | |
47 | void AdcInit(void) |
48 | {
|
49 | ADMUX |= (0<<MUX0) | (0<<MUX1) | (0<<MUX2); |
50 | ADMUX &= ~((1<<REFS0) | (1<<REFS1)); |
51 | ADMUX|=(0<<ADLAR); |
52 | ADCSRA |=(1<<ADSC); |
53 | ADCSRA |=(1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); |
54 | }
|
55 | |
56 | uint16_t ADC_Lesen(void) |
57 | {
|
58 | ADCSRA |=(1<<ADEN); |
59 | ADCSRA |= (1<<ADSC); |
60 | while (ADCSRA & (1<<ADSC)); |
61 | |
62 | ADCSRA &= ~(1<<ADEN); |
63 | return ADCW; |
64 | }
|
65 | |
66 | /*****************************Initialisierung***************/
|
67 | void Init(void) |
68 | {
|
69 | PortInit(); |
70 | Timer1Init(); |
71 | AdcInit(); |
72 | PORTB &= ~(1<<PINB3); |
73 | }
|
74 | |
75 | /******************************EXTERNER Interrupt*****************/
|
76 | ISR (INT0_vect) |
77 | {
|
78 | OCR1A = ALPHA; |
79 | TCNT1 = 0; |
80 | }
|
81 | |
82 | /******************************SOFTWARE Interrupts****************/
|
83 | ISR (TIMER1_COMPA_vect) |
84 | {
|
85 | if(Drehrichtung == 0) |
86 | {
|
87 | PORTA |= (1<<PINA4); |
88 | }
|
89 | else
|
90 | {
|
91 | //PORTA |= (1<<PINA7);
|
92 | }
|
93 | OCR1B = ALPHA + 2000; |
94 | |
95 | zweiteHalbwelle = 0; |
96 | ausschaltsicherung = 0; |
97 | }
|
98 | |
99 | ISR (TIMER1_COMPB_vect) |
100 | {
|
101 | if(Drehrichtung == 0) |
102 | {
|
103 | PORTA &= ~(1<<PINA4); |
104 | PORTA &= ~(1<<PINA5); |
105 | }
|
106 | else
|
107 | {
|
108 | PORTA &= ~(1<<PINA6); |
109 | PORTA &= ~(1<<PINA7); |
110 | }
|
111 | |
112 | ausschaltsicherung = 1; |
113 | |
114 | if(zweiteHalbwelle == 0) |
115 | {
|
116 | OCR1C = ALPHA + 20000; |
117 | |
118 | zweiteHalbwelle = 1; |
119 | }
|
120 | }
|
121 | |
122 | ISR (TIMER1_COMPC_vect) |
123 | {
|
124 | if(Drehrichtung == 0) |
125 | {
|
126 | PORTA |= (1<<PINA5); |
127 | }
|
128 | else
|
129 | {
|
130 | //PORTA |= (1<<PINA6);
|
131 | }
|
132 | |
133 | OCR1B = ALPHA + 22000; |
134 | |
135 | ausschaltsicherung = 0; |
136 | }
|
137 | |
138 | /****************************MAIN function*************************/
|
139 | int main(void) |
140 | {
|
141 | cli(); |
142 | Init(); |
143 | |
144 | while(1) |
145 | {
|
146 | ADC_Wert = ADC_Lesen(); |
147 | ALPHA = ((ALPHAmax - ALPHAmin)/(1024)) * (ADC_Wert) + ALPHAmin; |
148 | |
149 | if(ButtonPressed(0, PINA, 2, 500)) |
150 | {
|
151 | if(einschaltzustand == 0) |
152 | {
|
153 | sei(); |
154 | |
155 | PORTB |= (1<<PINB3); |
156 | |
157 | if(Drehrichtung == 1) |
158 | {
|
159 | PORTB &= ~(1<<PINB4); |
160 | }
|
161 | else
|
162 | {
|
163 | PORTB &= ~(1<<PINB2); |
164 | }
|
165 | |
166 | einschaltzustand = 1; |
167 | }
|
168 | else
|
169 | {
|
170 | if(ausschaltsicherung == 0) |
171 | {
|
172 | _delay_us(2500); |
173 | }
|
174 | else
|
175 | {
|
176 | cli(); |
177 | |
178 | PORTB |= (1<<PINB2); |
179 | PORTB |= (1<<PINB4); |
180 | PORTB &= ~(1<<PINB3); |
181 | |
182 | einschaltzustand = 0; |
183 | }
|
184 | }
|
185 | }
|
186 | |
187 | if(einschaltzustand == 1) |
188 | {
|
189 | if(ButtonPressed(1, PINA, 1, 500)) |
190 | {
|
191 | if(Drehrichtung == 0) |
192 | {
|
193 | PORTB &= ~(1<<PINB4); |
194 | PORTB |= (1<<PINB2); |
195 | Drehrichtung = 1; |
196 | }
|
197 | else
|
198 | {
|
199 | PORTB &= ~(1<<PINB2); |
200 | PORTB |= (1<<PINB4); |
201 | Drehrichtung = 0; |
202 | }
|
203 | }
|
204 | }
|
205 | }
|
206 | }
|
Hier der Quellcode für die "ButtonPress" Funktion, vielleicht hängt es auch damit zusammen:
1 | #include<avr/io.h> |
2 | |
3 | |
4 | |
5 | DDRC |= 1 << PINC5; |
6 | PORTC ^= 1 << PINC5; |
7 | DDRC &= ~(1 << PINC4); |
8 | PORTC |= 1 << PINC4; |
9 | |
10 | int Pressed = 0; |
11 | int Pressed_Confidence_Level = 0; |
12 | int Released_Confidence_Level = 0; |
13 | |
14 | |
15 | if (bit_is_clear(PINC, 4)) |
16 | {
|
17 | Pressed_Confidence_Level ++; |
18 | Released_Confidence_Level = 0; |
19 | if (Pressed_Confidence_Level >500) |
20 | {
|
21 | if (Pressed == 0) |
22 | {
|
23 | PORTC ^= 1 << PINB5; |
24 | Pressed = 1; |
25 | }
|
26 | Pressed_Confidence_Level = 0; |
27 | }
|
28 | }
|
29 | else
|
30 | {
|
31 | Released_Confidence_Level ++; |
32 | Pressed_Confidence_Level = 0; |
33 | if (Released_Confidence_Level >500) |
34 | {
|
35 | Pressed = 0; |
36 | Released_Confidence_Level = 0; |
37 | }
|
38 | }
|
Wenn mir jemand weiterhelfen kann wäre ich sehr dankbar, da ich mich schon seit 2 Tagen mit diesem Problem beschäftige und mir langsam die Lösungsansätze ausgehen... Vielen Dank!