Forum: Compiler & IDEs LED leuchten zu schwach


von Rachid M. (rachid)


Lesenswert?

hallo,

bin ein AVR-anfänger.
Ich möchte 3 LED's zum blinken bringen: Erste LED leuchtet z.B. 2s dann 
geht aus dann leuchtet die zweite dann geht sie auch aus dann die die 
Dritte usw...
Das tuts doch aber die Erste LED leuchtet ganz normal, aber dir zweite 
und dritte leuchten sehr schwach dann. Ich würde gern wissen woran es 
liegen könnte.

Ich habe mein Schaltung so: 
http://www.electronic-idea.de/typo3/index.php?id=17&type=1  gebaut
hier ist mein Code:
1
/***************************************************************************************************
2
Identifikation *************************************************************************************
3
***************************************************************************************************/
4
/*-------------------------------------------------------------------------------------------------
5
Dateiname:    $Workfile:   test1.c  $
6
Version:      $Revision:   1.0  $ 
7
Copyright:    maoukil 
8
Beschreibung: Geblinkt wird in PortB (push-pull) drei LEDs.
9
-------------------------------------------------------------------------------------------------*/
10
11
/***************************************************************************************************
12
Includes *******************************************************************************************
13
***************************************************************************************************/
14
15
#include <avr/io.h>
16
#include <inttypes.h>
17
#include <avr/interrupt.h>
18
#include <avr/delay.h>
19
20
#ifndef SIGNAL
21
#include <avr/signal.h>
22
#endif
23
24
/*-------------------------------------------------------------------------------------------------
25
Der MCU-Takt. Wird gebraucht, um Timer1 mit den richtigen
26
Werten zu initialisieren. Voreinstellung ist 1MHz.
27
(Werkseinstellung für AVRs mit internem Oszillator).
28
Das Define wird nur gemacht, wenn F_CPU noch nicht definiert wurde.
29
F_CPU kann man so auch per Kommandozeile definieren, z.B. für 8MHz:
30
avr-gcc ... -DF_CPU=8000000
31
Der Wert von F_CPU hat rein informativen Character für
32
die korrekte Codeerzeugung im Programm!
33
Um die Taktrate zu ändern müssen die Fuses des Controllers
34
und/oder Quarz/Resonator/RC-Glied/Oszillator
35
angepasst werden!
36
-------------------------------------------------------------------------------------------------*/
37
#ifndef F_CPU
38
#define F_CPU 4000000
39
#endif
40
41
/***************************************************************************************************
42
Defines und Makros *********************************************************************************
43
***************************************************************************************************/
44
45
/*-------------------------------------------------------------------------------------------------
46
So viele IRQs (Interrupt Request (IRQ)) werden jede Sekunde ausgelöst.
47
Für optimale Genauigkeit muss
48
IRQS_PER_SECOND ein Teiler von F_CPU sein
49
und IRQS_PER_SECOND ein Vielfaches von 100.
50
Ausserdem muss gelten F_CPU / IRQS_PER_SECOND <= 65536
51
-------------------------------------------------------------------------------------------------*/
52
53
#define LED_1  0
54
#define LED_2  1
55
#define LED_3  2
56
#define PORT_LED PORTB
57
#define DDR_LED  DDRB     // DDR: Definiere Port X als Ausgang
58
#define IRQS_PER_SECOND   2000
59
#define IRQS_PER_10MS     (IRQS_PER_SECOND / 100) // Anzahl IRQs pro 10 Millisekunden
60
61
/***************************************************************************************************
62
Typdefinitionen ************************************************************************************
63
***************************************************************************************************/
64
65
66
67
/***************************************************************************************************
68
Konstanten *****************************************************************************************
69
***************************************************************************************************/
70
71
72
/***************************************************************************************************
73
Applikationsgroessen *******************************************************************************
74
***************************************************************************************************/
75
76
77
/***************************************************************************************************
78
Variablen ******************************************************************************************
79
***************************************************************************************************/
80
81
static volatile uint8_t timer_10ms; // Zähler-Variable. Wird in der ISR (Interrupt Service Routine,)  
82
                  // erniedrigt und in wait_10ms benutzt.
83
84
/***************************************************************************************************
85
Funktionsprototypen für Modul-interne Funktionen ***************************************************
86
***************************************************************************************************/
87
88
void wait_10ms (const uint8_t);
89
void timer1_init();
90
91
/***************************************************************************************************
92
Hauptprogramm **************************************************************************************
93
***************************************************************************************************/
94
95
int main()
96
{
97
    
98
    DDR_LED  |= (1 << LED_1); // LED-Port auf Ausgang
99
    
100
  timer1_init(); // Timer1 initialisieren
101
    
102
    sei(); // Interrupts aktivieren
103
104
/*-------------------------------------------------------------------------------------------------
105
Endlosschleife
106
Die LED ist jeweils 1 Sekunde an und 1 Sekunde aus,
107
blinkt also mit einer Frequenz von 0.5 Hz
108
-------------------------------------------------------------------------------------------------*/
109
110
    while (1)
111
    {
112
        
113
        PORT_LED |= (1 << LED_1); // LED 1 an
114
        
115
        wait_10ms (200); // 1 Sekunde warten
116
        
117
        PORT_LED &= ~(1 << LED_1); // LED 1 aus
118
        
119
        wait_10ms (200); // 1 Sekunde warten
120
121
122
123
    PORT_LED |= (1 << LED_2); // LED 2 an
124
        
125
        wait_10ms (200); // 1 Sekunde warten
126
        
127
        PORT_LED &= ~(1 << LED_2); // LED 2 aus
128
        
129
        wait_10ms (200); // 1 Sekunde warten
130
131
132
133
    PORT_LED |= (1 << LED_3); // LED 3 an
134
        
135
        wait_10ms (200); // 1 Sekunde warten
136
        
137
        PORT_LED &= ~(1 << LED_3); // LED 3 aus
138
        
139
        wait_10ms (200); // 1 Sekunde warten
140
    }
141
142
    // main braucht keine return-Anweisung, weil wir nie hier hin kommen
143
}
144
145
146
/***************************************************************************************************
147
Funktionen *****************************************************************************************
148
***************************************************************************************************/
149
150
/*-------------------------------------------------------------------------------------------------
151
Gültigkeitsprüfung.
152
Bei ungeeigneten Werten gibt es einen Compilerfehler
153
-------------------------------------------------------------------------------------------------*/
154
155
#if (F_CPU/IRQS_PER_SECOND > 65536) || (IRQS_PER_10MS < 1) || (IRQS_PER_10MS > 255)
156
#   error Diese Werte fuer F_CPU und IRQS_PER_SECOND
157
#   error sind ausserhalb des gueltigen Bereichs!
158
#endif
159
160
/*-------------------------------------------------------------------------------------------------
161
Compiler-Warnung falls die Genauigkeit nicht optimal ist.
162
Wenn das nervt für deine Werte, einfach löschen :-)
163
-------------------------------------------------------------------------------------------------*/
164
165
#if (F_CPU % IRQS_PER_SECOND != 0) || (IRQS_PER_SECOND % 100 != 0)
166
#   warning Das Programm arbeitet nicht mit optimaler Genauigkeit.
167
#endif
168
169
// //////////////////////////////////////////////////////////////////////
170
// Implementierungen der Funktionen
171
// //////////////////////////////////////////////////////////////////////
172
173
#if !defined (TCNT1H)
174
#error Dieser Controller hat keinen 16-Bit Timer1!
175
#endif // TCNT1H
176
177
178
/***************************************************************************************************
179
void timer1_init()  ********************************************************************************
180
***************************************************************************************************/
181
182
/*-------------------------------------------------------------------------------------------------
183
Timer1 so initialisieren, daß er IRQS_PER_SECOND 
184
IRQs pro Sekunde erzeugt.
185
-------------------------------------------------------------------------------------------------*/
186
187
void timer1_init()
188
189
{
190
    TCCR1A = 0; // Timer1: keine PWM. TCCR1A Timer/Counter 1 Control Register A
191
192
/*-------------------------------------------------------------------------------------------------
193
Timer1 ist Zähler: Clear Timer on Compare Match (CTC, Mode #4)
194
Timer1 läuft mit vollem MCU-Takt: Prescale = 1
195
-------------------------------------------------------------------------------------------------*/
196
197
#if defined (CTC1) && !defined (WGM12)
198
   TCCR1B = (1 << CTC1)  | (1 << CS10);
199
#elif !defined (CTC1) && defined (WGM12)
200
   TCCR1B = (1 << WGM12) | (1 << CS10);
201
#else
202
#error Keine Ahnung, wie Timer1 fuer diesen AVR zu initialisieren ist!
203
#endif
204
205
/*-------------------------------------------------------------------------------------------------
206
OutputCompare für gewünschte Timer1 Frequenz
207
TCNT1 zählt immer 0...OCR1A, 0...OCR1A, ... 
208
Beim überlauf OCR1A -> OCR1A+1 wird TCNT1=0 gesetzt und im nächsten
209
MCU-Takt eine IRQ erzeugt.
210
-------------------------------------------------------------------------------------------------*/
211
212
    OCR1A = (unsigned short) ((unsigned long) F_CPU / IRQS_PER_SECOND-1);
213
214
#if defined (TIMSK1) // OutputCompareA-Interrupt für Timer1 aktivieren
215
    TIMSK1 |= (1 << OCIE1A);
216
#elif defined (TIMSK)
217
    TIMSK  |= (1 << OCIE1A);
218
#else   
219
#error Keine Ahnung, wie IRQs fuer diesen AVR zu initialisieren sind!
220
#endif
221
222
}
223
224
/***************************************************************************************************
225
void wait_10ms (const uint8_t t) *******************************************************************
226
***************************************************************************************************/
227
228
/*-------------------------------------------------------------------------------------------------
229
Wartet etwa t*10 ms. 
230
timer_10ms wird alle 10ms in der Timer1-ISR erniedrigt. 
231
Weil es bis zum nächsten IRQ nicht länger als 10ms dauert,
232
wartet diese Funktion zwischen (t-1)*10 ms und t*10 ms.
233
-------------------------------------------------------------------------------------------------*/
234
235
void wait_10ms (const uint8_t t)
236
237
{
238
    timer_10ms = t;
239
    while (timer_10ms);
240
}
241
242
/***************************************************************************************************
243
Die Interrupt Service Routine (ISR) ****************************************************************
244
***************************************************************************************************/
245
/*-------------------------------------------------------------------------------------------------
246
Die Interrupt Service Routine (ISR).
247
In interrupt_num_10ms werden die IRQs gezählt.
248
Sind IRQS_PER_10MS Interrups geschehen, 
249
dann sind 10 ms vergangen.
250
timer_10ms wird alle 10 ms um 1 vermindert und bleibt bei 0 stehen.
251
-------------------------------------------------------------------------------------------------*/
252
253
SIGNAL (SIG_OUTPUT_COMPARE1A)
254
{
255
    static uint8_t interrupt_num_10ms;
256
257
        if (++interrupt_num_10ms == IRQS_PER_10MS) // interrupt_num_10ms erhöhen und mit M
258
                           // aximalwert vergleichen
259
    {
260
        
261
        interrupt_num_10ms = 0; // 10 Millisekunden sind vorbei // interrupt_num_10ms zurücksetzen
262
              
263
        if (timer_10ms != 0) // Alle 10ms wird timer_10ms erniedrigt, falls es nicht schon 0 ist.
264
            timer_10ms--;    // Wird verwendet in wait_10ms
265
    }
266
}

von Falk (Gast)


Lesenswert?

@Rachid Maoukil

>Das tuts doch aber die Erste LED leuchtet ganz normal, aber dir zweite
>und dritte leuchten sehr schwach dann. Ich würde gern wissen woran es
liegen könnte.

Du musst die Ports für alle drei LEDs auf Ausgang schalten, die sind 
mämlich na dem Reset alles Eingänge.


int main()
{

// ist unvollständig
//    DDR_LED  |= (1 << LED_1); // LED-Port auf Ausgang

// so isses sbesser
    DDR_LED  |= (1 << LED_1) | (1 << LED_2) | (1 << LED_3); // LED-Ports 
auf Ausgang

...

MfG
Falk

von Rachid M. (rachid)


Lesenswert?

Super. Danke sehr

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.