Forum: Mikrocontroller und Digitale Elektronik Atmega16 Waveform Mode 14 und LEDs am PORTD


von philipp (Gast)


Lesenswert?

hallo an alle,
ich hab mal ne frage (beschäftige mich noch nicht so lang mit µC und das 
ist mein erster Eintrag hier ins Forum):

und zwar hab ich n Atmega16 und hab am PORTD (PD0,PD1,PD2,PD3, PD6) LEDs 
und am PD5 (OC1A) nen Speaker. Und jetzt ist es, dass wenn ich Fast PWM 
mache (WGM 14) um eben den Speaker mit ner bestimmten Frequenz toogeln 
zu lassen dann gehen die LEDs an dem PORT nicht mehr und ich weiß nicht 
warum? Folgende Einstellung hab ich genommen:

Port D einstellungen

DDRD = 0b11111111;
PORTD |= 0b00000000;


Timer 1:

DDRD = (1<<PD5);    //PD5 (OC1A) auf Ausgang
PORTD &= ~(1<<PD5); //PD5 (OC1A) auf low

TCCR1B = (1<<CS12) | (1<<WGM13) | (1<<WGM12);   //Prescaler 8, WGM
TCCR1A = (1<<WGM11) | (1<<COM1A1);              //WGM 14 (FAST ICR1 TOP
ICR1 = 142;                                     //16Mhz/8/440Hz (A4)
OCR1A = 1;                                      //Lautstärke

PS: In einem SwitchCase in der Main kann ich die LEDs ein ausschalten 
hat aber damit nichts zu tun, weil wenn ich den Timer1 ausmache, geht es 
wunderbar.
PPS: Gibt es eine Möglichkeit den Code schöner in einem Post zu 
formatieren?

Danke im Vorraus

von Karl H. (kbuchegg)


Lesenswert?

philipp schrieb:
> Und jetzt ist es, dass wenn ich Fast PWM
> mache (WGM 14) um eben den Speaker mit ner bestimmten Frequenz toogeln
> zu lassen dann gehen die LEDs an dem PORT nicht mehr und ich weiß nicht
> warum?

Ganz einfach:
Du hast einen Fehler im Programm.
Also zeig es als Ganzes.

> Folgende Einstellung hab ich genommen:

Schön. Hier liegt der Fehler nicht.

> PPS: Gibt es eine Möglichkeit den Code schöner in einem Post zu
> formatieren?

Hast du schon mal in der grauen Box über dem Eingabefeld gelesen, was da 
so alles drinnen steht. Solltest du tun. Da gibt es eine schöne große 
Überschrift "Formatierungen"

von philipp (Gast)


Angehängte Dateien:

Lesenswert?

erstmal danke für die schnelle antwort!
das problem ist, dass der halt schon riesig ist, und ich will ja keinen 
mit unnötiger leserei belästigen. und ich hab ihn auf mehrere c-files 
aufgeteilt. aber ich verusch mal das wichtigste hier reinzuschreiben.
PORT einstellung:
1
    DDRA  &= ~(1<<PA0) | ~(1<<PA1) | ~(1<<PA2);
2
    PORTA |= 0b00000000;
3
4
5
    DDRD = 0b11111111;
6
    PORTD |= 0b00000000;
7
8
    DDRC &= 0b00000000;
9
    PORTC |= 0x00;
Timer0:
1
  TCCR0 = 1<<WGM01^1<<CS01^1<<CS00;     // CTC, XTAL / 64
2
  OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms
3
  TIMSK |= 1<<OCIE0;
Timer1:
1
    DDRD = (1<<PD5);    //PD5 (OC1A) auf Ausgang
2
    PORTD &= ~(1<<PD5); //PD5 (OC1A) auf low
3
4
    TCCR1B = (1<<CS12) | (1<<WGM13) | (1<<WGM12);   //Prescaler 8, WGM 14 (FAST PWM TOP ICR1)
5
    TCCR1A = (1<<WGM11) | (1<<COM1A1);              //WGM 14 (FAST PWM TOP ICR1)
6
    ICR1 = 142;    //16Mhz/8/440Hz (A4)
7
    OCR1A = 1;      //Lautstärke/
Timer 2:
1
    TCCR2 |= ((1 << CS21));       // Prescaler 8
2
    ASSR   = (1<< AS2);             // Timer2 asynchron takten mit Uhrenquarz
3
    long_delay(1000);               // Einschwingzeit des 32kHz Quarzes
4
    TCCR2 = (1<<COM21) | (1<<WGM21) | (1<<WGM20); // Fast PWM, non inverted
5
    TCCR2 = 1;                     // Vorteiler 1 -> 7,8ms Überlaufperiode
6
    OCR2  = 128;                   // PWM, Tastverhältnis 50%
7
    while((ASSR & (1<< TCR2UB)));  // Warte auf das Ende des Zugriffs
8
    TIFR  &= ~(1<<TOV2);           // Interrupts löschen
9
    TIMSK |= (1<<TOIE2);           // Timer overflow Interrupt freischalten
Die while in der main:
1
    while(1)
2
    {
3
4
        tasterAlarmzeit(PINC, PINC4);
5
        tasterX(PIND, PIND7);
6
        tasterDCFempfang(PINC, PINC5);
7
        tasterSleep(PINC, PINC2);
8
9
        //Kippschalter AlarmEin
10
        if (PINC & (1<<PC3))
11
        {
12
            Modus |= MOD_AlarmEin;
13
        }
14
        else
15
        {
16
            Modus &= ~MOD_AlarmEin;
17
        }
18
19
20
21
        Zeitueberlaeufe();
22
23
24
        switch (Modus)
25
        {
26
        case 0b00000000:
27
        {
28
            Alarmzeit = 0;
29
            AlarmEin = 0;
30
            DCFempfang = 0;
31
32
            Uhrzeit();
33
            deimmAll(15);
34
35
36
            PORTD &= ~((1<<PD0) | (1<<PD1));
37
            PORTD &= ~((1<<PD2) | (1<<PD3));
38
            break;
39
        }
40
        //Sleep
41
        case 0b00000001:
42
        {
43
            Alarmzeit = 0;
44
            AlarmEin = 0;
45
            DCFempfang  = 0;
46
            TCCR1B &= ~(1<<CS12);
47
            Uhrzeit();
48
            deimmAll(1);
49
50
            PORTD &= ~((1<<PD0) | (1<<PD1));
51
            PORTD &= ~((1<<PD2) | (1<<PD3));
52
            break;
53
        }
54
        //Alarm ein
55
        case 0b00000010:
56
        {
57
            Alarmzeit = 0;
58
            AlarmEin = 0;
59
            DCFempfang  = 0;
60
61
            Uhrzeit();
62
            deimmAll(15);
63
64
            PORTD |= (1<<PD0) | (1<<PD1);
65
            PORTD &= ~((1<<PD2) | (1<<PD3));
66
            break;
67
        }
68
        case 0b00000011:
69
        //Sleep + Alarm
70
        {
71
            Alarmzeit = 0;
72
            AlarmEin = 0;
73
            DCFempfang  = 0;
74
75
            Uhrzeit();
76
            deimmAll(1);
77
78
            PORTD |= (1<<PD1);
79
            PORTD &= ~(1<<PD0);
80
            PORTD &= ~((1<<PD2) | (1<<PD3));
81
            break;
82
        }
83
        //DCF
84
        case 0b00000100:
85
        {
86
            Alarmzeit = 0;
87
            AlarmEin = 0;
88
            DCFempfang  = 1;
89
90
            Uhrzeit();
91
            deimmAll(15);
92
93
            PORTD |= (1<<PD2) | (1<<PD3);
94
            PORTD &= ~((1<<PD0) | (1<<PD1));
95
            break;
96
        }
97
        //DCF + Alarm
98
        case 0b00000110:
99
        {
100
            Alarmzeit = 0;
101
            AlarmEin = 0;
102
            DCFempfang  = 1;
103
104
            Uhrzeit();
105
            deimmAll(15);
106
107
            PORTD |= (1<<PD2) | (1<<PD3);
108
            PORTD |= (1<<PD0) | (1<<PD1);
109
            break;
110
        }
111
        //DCF + Sleep
112
        case 0b00000101:
113
        {
114
            Alarmzeit = 0;
115
            AlarmEin = 0;
116
            DCFempfang  = 1;
117
118
            Uhrzeit();
119
            deimmAll(1);
120
121
            PORTD &= ~((1<<PD0) | (1<<PD1));
122
            PORTD |= (1<<PD2);
123
            PORTD &= ~(1<<PD3);
124
            break;
125
        }
126
        //DCF + Alarm + Sleep
127
        case 0b00000111:
128
        {
129
            DCFempfang = 1;
130
131
            Alarmzeit = 0;
132
            Uhrzeitstellen = 0;
133
134
            Uhrzeit();
135
            deimm(1, 1);
136
            deimm(1, 2);
137
            deimm(1, 3);
138
139
            PORTD |= (1<<PD1);
140
            PORTD &= ~(1<<PD0);
141
            PORTD |= (1<<PD2);
142
            PORTD &= ~(1<<PD3);
143
            break;
144
        }
145
        // Weckzeit  hh einstellen
146
        case 0b00001000:
147
        {
148
            Weckzeit();
149
            hhW += encode_read1();
150
            deimm(15,1);
151
            deimm(1, 2);
152
            deimm(1, 3);
153
154
            PORTD &= ~((1<<PD0) | (1<<PD1));
155
            PORTD &= ~((1<<PD2) | (1<<PD3));
156
            break;
157
        }
158
        //Weckzeit mm einstellen
159
        case 0b00010000:
160
        {
161
            Weckzeit();
162
            mmW += encode_read1();
163
            deimm(1, 1);
164
            deimm(15,2);
165
            deimm(1, 3);
166
167
            PORTD &= ~((1<<PD0) | (1<<PD1));
168
            PORTD &= ~((1<<PD2) | (1<<PD3));
169
            break;
170
        }
171
        //Weckzeit hh + Sleep
172
        case 0b00001001:
173
        {
174
            Weckzeit();
175
            hhW += encode_read1();
176
            deimm(15,1);
177
            deimm(1, 2);
178
            deimm(1, 3);
179
180
            PORTD &= ~((1<<PD0) | (1<<PD1));
181
            PORTD &= ~((1<<PD2) | (1<<PD3));
182
            break;
183
        }
184
        //Weckzeit mm + Sleep
185
        case 0b00010001:
186
        {
187
            Weckzeit();
188
            mmW += encode_read1();
189
            deimm(1, 1);
190
            deimm(15,2);
191
            deimm(1, 3);
192
193
            PORTD &= ~((1<<PD0) | (1<<PD1));
194
            PORTD &= ~((1<<PD2) | (1<<PD3));
195
            break;
196
        }
197
        //Weckzeit hh + Alarm
198
        case 0b00001010:
199
        {
200
            Weckzeit();
201
            hhW += encode_read1();
202
            deimm(15, 1);
203
            deimm(1,2);
204
            deimm(1, 3);
205
206
            PORTD |= ((1<<PD0) | (1<<PD1));
207
            PORTD &= ~((1<<PD2) | (1<<PD3));
208
            break;
209
        }
210
        //Weckzeit mm + Alarm
211
        case 0b00010010:
212
        {
213
            Weckzeit();
214
            mmW += encode_read1();
215
            deimm(1, 1);
216
            deimm(15,2);
217
            deimm(1, 3);
218
219
            PORTD |= ((1<<PD0) | (1<<PD1));
220
            break;
221
        }
222
        //Weckzeit hh + Alarm + Sleep
223
        case 0b00001011:
224
        {
225
            Weckzeit();
226
            hhW += encode_read1();
227
            deimm(15, 1);
228
            deimm(1,2);
229
            deimm(1, 3);
230
231
            PORTD |= ((1<<PD0) | (1<<PD1));
232
            PORTD &= ~((1<<PD2) | (1<<PD3));
233
            break;
234
        }
235
        //Weckzeit mm + Alarm + Sleep
236
        case 0b00010011:
237
        {
238
            Weckzeit();
239
            mmW += encode_read1();
240
            deimm(1, 1);
241
            deimm(15,2);
242
            deimm(1, 3);
243
244
            PORTD |= ((1<<PD0) | (1<<PD1));
245
            break;
246
        }
247
        //Weckzeit hh + DCF
248
        case 0b00001100:
249
        {
250
            DCFempfang = 0;
251
            Weckzeit();
252
            hhW += encode_read1();
253
            deimm(15,1);
254
            deimm(1, 2);
255
            deimm(1, 3);
256
            break;
257
        }
258
        //Weckzeit mm + DCF
259
        case 0b00010100:
260
        {
261
            DCFempfang = 0;
262
            Weckzeit();
263
            mmW += encode_read1();
264
            deimm(1, 1);
265
            deimm(15,2);
266
            deimm(1, 3);
267
            break;
268
        }
269
        //Weckzeit hh + Alarm + DCF
270
        case 0b00001110:
271
        {
272
            DCFempfang = 0;
273
            Weckzeit();
274
            hhW += encode_read1();
275
            deimm(15,1);
276
            deimm(1, 2);
277
            deimm(1, 3);
278
            break;
279
        }
280
        //Weckzeit mm + Alarm + DCF
281
        case 0b00010110:
282
        {
283
            DCFempfang = 0;
284
            Weckzeit();
285
            mmW += encode_read1();
286
            deimm(1, 1);
287
            deimm(15,2);
288
            deimm(1, 3);
289
            break;
290
        }
291
        //Weckzeit hh + Alarm + Sleep + DCF
292
        case 0b00001111:
293
        {
294
            DCFempfang = 0;
295
            Weckzeit();
296
            hhW += encode_read1();
297
            deimm(15,1);
298
            deimm(1, 2);
299
            deimm(1, 3);
300
            break;
301
        }
302
        //Weckzeit mm + Alarm + Sleep + DCF
303
        case 0b00010111:
304
        {
305
            DCFempfang = 0;
306
            Weckzeit();
307
            mmW += encode_read1();
308
            deimm(1, 1);
309
            deimm(15,2);
310
            deimm(1, 3);
311
            break;
312
        }
313
        //Weckzeit hh + Sleep + DCF
314
        case 0b00001101:
315
        {
316
            DCFempfang = 0;
317
            Weckzeit();
318
            hhW += encode_read1();
319
            deimm(15,1);
320
            deimm(1, 2);
321
            deimm(1, 3);
322
            break;
323
        }
324
        //Weckzeit hh + Sleep + DCF
325
        case 0b00010101:
326
        {
327
            DCFempfang = 0;
328
            Weckzeit();
329
            mmW += encode_read1();
330
            deimm(1, 1);
331
            deimm(15,2);
332
            deimm(1, 3);
333
            break;
334
        }
335
        case 0b00100000:
336
        {
337
338
            PORTD |= (1<<PD6);
339
            break;
340
        }
341
    }
342
343
    }
344
}
Die Timer-Vektoren
1
// Timer 1 Sound
2
ISR( TIMER1_COMPA_vect)
3
{
4
//    if (AlarmEin)
5
//    {
6
//        laufschriftcounter++;
7
//        if (laufschriftcounter > 114) {laufschriftcounter = 0;}
8
//    }
9
}
10
11
12
// Timer0 compare interrupt FÜR DREHGEBER
13
14
ISR(TIMER0_COMP_vect)             // 1ms for manual movement
15
{
16
17
    if (Alarmzeit)
18
    {
19
      int8_t new, diff;
20
21
      new = 0;
22
      if( PHASE_A )
23
        new = 3;
24
      if( PHASE_B )
25
        new ^= 1;                   // convert gray to binary
26
      diff = last - new;                // difference last - new
27
      if( diff & 1 ){               // bit 0 = value (1)
28
        last = new;                 // store new as next last
29
        enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
30
      }
31
    }
32
33
34
    if (DCFempfang)
35
    {
36
37
        if (( PINA & ( 1 << PA2 )) )
38
        {
39
            pcounter = 0;
40
            dcfcounter++;
41
42
43
        }
44
        else
45
        {
46
47
48
            if (dcfcounter > 60 && dcfcounter < 120)
49
            {
50
51
                if (recieving == 0xFF)
52
                {
53
                    dcf[dcfbufferposition] = 0;
54
                    dcfbufferposition++;
55
                }
56
            }
57
58
            if (dcfcounter > 140 && dcfcounter < 220)
59
            {
60
                if (recieving == 0xFF)
61
                {
62
                    dcf[dcfbufferposition] = 1;
63
                    dcfbufferposition++;
64
                }
65
            }
66
67
            dcfcounter = 0;
68
69
            if (dcfbufferposition == 59)
70
            {
71
                DCFzeit();
72
                dcfbufferposition = 0;
73
            }
74
            pcounter++;
75
            if (pcounter > 1400)
76
            {
77
78
                pcounter = 0;
79
                dcfbufferposition = 0;
80
                recieving = 0xFF;
81
                ss = 0;
82
            }
83
        }
84
    }
85
86
}
87
88
// Timer2 overflow Interrupt FÜR UHRZEIT
89
90
ISR(TIMER2_OVF_vect) {
91
    static uint8_t ticks;               // Hilfsvariable für Messintervall
92
    static int16_t time_error;          // RTC Fehlerkompensation
93
94
    // Zeitkritische Dinge, welche am Anfang der ISR stehen müssen!
95
96
    OCR2=128;                          // Dummy-Write zur Sicherung des Timings
97
                                        // von Timer 2 im asynchronen Modus
98
99
    // RTC Fehler korrigieren
100
101
    if (time_error>999)                 // RTC zu schnell
102
    {
103
        TCNT2 = 2;                      // Zähler einen Schritt zurück setzen (2 Takte Verzögerung!)
104
        time_error -= 1000;
105
    }
106
    else if (time_error<-999)           // RTC zu langsam
107
    {
108
        TCNT2 = 4;                      // Zähler einen Schritt vor setzen (2 Takte Verzögerung!)
109
        time_error += 1000;
110
    }
111
112
    // ab hier ist es nicht mehr zeitkritisch
113
114
    // Echtzeituhr
115
    ticks++;                            // 1/128tel Sekunde
116
117
    if (ticks==128)
118
    {                   // Sekundenintervall
119
        time_error += rtc_cal;          // RTC Fehler akkumulieren
120
121
        ss++;
122
123
        // 24h Timer
124
        time++;
125
        if (time==86400) time=0;        // 24h Überlauf
126
127
        ticks=0;
128
        flag_1s =1;   // setzte Flag für 1s Verarbeitung in main Endlosschleife
129
    }
130
}

und sorry für die schlechte dokumentation, aber vielleicht fällt der 
fehler ja einem von euch profis gleich ins auge...

von philipp (Gast)


Lesenswert?

sorry, dass ich den code nochmal gepostet hab. das war nicht meine 
absicht. ich wollte es eigentlich nicht im anhang mitschicken, aber wäre 
eigentlich wohl doch besser gewesen.

von Karl H. (kbuchegg)


Lesenswert?

>     DDRD = (1<<PD5);    //PD5 (OC1A) auf Ausgang


gratuliere
Du hast dir soeben die restlichen Pins am Port D auf Eingang geschaltet.

von Karl H. (kbuchegg)


Lesenswert?

Hast du was dagegen, wenn ich den langen Codeteil in deinem Posting 
kürze?
Der ist unsinnig - sieht sich sowieso keiner an, weil alle die 
Codevorschau bevorzugen.

von philipp (Gast)


Lesenswert?

Vielen herzlich Dank K-H,
echt spitze wie du dass so schnell siehst! Geht jetzt jedenfalls...
Danke, Danke, Danke!!!

von Karl H. (kbuchegg)


Lesenswert?

Dein

  switch( modus )


ist ja heavy!
Das sind im grunde 4 oder 5 verschiedene Codeschnipsel, die sich durch 
die Zahlenwerte unterscheiden.
Die Schnipsel kann man ach in Funktionen auslagern, denen man die 
Zahlenwerte als Argument mitgibt.
Und schon schrumpft der ganze Case von 4 Seiten Code auf 1 oder 1 
einhalb zusammen. Was nicht nur der Übersicht gut tut.

von Karl H. (kbuchegg)


Lesenswert?

philipp schrieb:
> Vielen herzlich Dank K-H,
> echt spitze wie du dass so schnell siehst!

Ich les mir einfach den Code durch.
Meistens fang ich bei der main an.

Da du geschrieben hast, du hättest ein Problem mit dem Port D hab ich 
spezielles Augenmerk auf alles gelegt, was mit dem Port D zu tun hat.
Und eine direkte Zuweisung an eines der Port/Pin/DDR Register ist 
grundsätzlich immer suspekt. Also achte ich speziell auf alles, was mit 
Port D zu tun hat und bei dem 'in der Mitte' ein einsames = steht. Man 
kennt ja seine Pappenheimer und die Praxis des Code Copy&Paste

So einfach ist das.

von philipp (Gast)


Lesenswert?

ok super,
ich werd veruschen, den switch-kram mal in ne funktion auszulagern. 
haste eigentlich schon recht. Wär mir selber gar nicht aufgefallen. Muss 
aber eh noch einiges am code optimieren und kommentieren. Muss nämlich 
zugeben, dass ich viel von euch kopiert habe... dank dir jedenfalls und 
gute nacht!

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> So einfach ist das.

Allerdings hab ich dir gegenüber einen Vorteil.
Als Autor hast du immer eine Tendenz das im Code zu Lesen, was deiner 
Meinung nach dort stehen SOLLTE.
Wenn ich den Code lese, dann hab ich erst mal keinen Bezug zum Code. Ich 
lese das, was tatsächlich dort steht. Und das muss nicht immer das 
gleiche sein, was du liest :-) Wer beide gehen unterschiedlich an die 
Sache ran. Du weißt was konzeptionell an dieser Stelle passieren sollte. 
Ich weiß das nicht, ich muss mir das aus dem Code erschliessen. Daher 
achte ich mehr auf die kleinen Details, die du überliest.

(Wenn du verstehst was ich meine. Ist im Grunde das gleiche mit 
Rechtschriebfehler. Die sieht man selber auch oft erst, wenn man mit der 
Nase drauf gestossen wird und andere sehen sie sofort. Nur mit dem 
Unterschied, dass in einer Programmiersprache wie C all die 
Sonderzeichen eine wesentliche Bedeutung tragen, während ein vergessenes 
Komma in einem deutschen Satz kein Beinbruch ist)

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
Noch kein Account? Hier anmelden.