ADC: LED blinkt nur

OP #2495732
Lesenswert?

Hallo Leute,
ich habe erst vor kurzem mit uC-Programmierung begonnen und bin 
praktisch noch ganz am Anfang.
Zur Zeit versuche ich, ein Bisschen mit dem ADC herumzuspielen und je 
nach Spannungsbereich verschiedene LEDs schalten zu lassen.
Allerdings blinken die LEDs bei mir immer nur und schalten nie auf 
'Dauerlicht'.

Ich bin dankbar fuer jeden Hinweis...
Gruss,
Pipesmoker
1
#define F_CPU 4000000UL  /* 4 MHz Interner Oszillator */
2
#include <avr/io.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5

6
/* Funktion fuer Verzoegerung um eine ms (4 Takte) */
7
void delay_ms(uint16_t ms) {
8
        while ( ms ) 
9
        {
10
                delay_ms(1);
11
                ms--;
12
    ms--;
13
    ms--;
14
    ms--;
15
        }
16
}
17

18

19
/* ADC initialisieren */
20
void ADC_Init(void) {
21
  uint16_t result;
22
  ADMUX = (1 << REFS1) | (1 << REFS0); //interne Referenzspannung nutzen
23
  ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); //Frequenzvorteiler nutzen
24
  ADCSRA |= (1 << ADEN); //ADC aktivieren
25
  ADCSRA |= (1 << ADSC); //eine ADC-Probewandlung
26
  while (ADCSRA & (1 << ADSC) ) {} //Auf Abschluss der Probewandlung warten
27
  result = ADCW;
28
}
29

30

31
/* Mehrfachmessung mit Mittelwert */
32
uint16_t ADC_Read_Avg(uint8_t channel, uint8_t average)
33
{
34
  uint32_t result = 0; //Ergebnis initialisieren
35

36
  uint8_t i;
37
  for (i=0; i < average; ++i)
38
  {
39
    result += ADC_Read(channel); //average Messungen ausfuehren
40
  }
41

42
  return (uint16_t)(result / average); //Mittelwert bilden
43
}
44

45

46
int main (void)
47
{
48
  uint16_t adcval;
49
  ADC_Init(); //Initialisierungsfunktion mit Probemessung
50

51
//  11 Ausgaenge definieren
52
  DDRB = 0xff; //alle PB-Pins als Ausgang definieren (=8 Stueck)
53
  DDRC |= (1 << PC3) | (1 << PC4) | (1 << PC5); //Ausgang PC3, 4 und 5
54

55
  DDRC &= ~((1 << PC6) | (1 << PC2) | (1 << PC1) | (1 << PC0));
56
        
57
        while (1) //Endlosschleife
58
        {
59

60
    adcval = ADC_Read_Avg(0, 10); //Mehrfachmessung, Kanal 0, 10 Messungen
61

62
    if (adcval > 512)
63
    {
64
      PORTC &= ~(1 << PC3);
65

66
    }
67

68
    else if (adcval <= 512) 
69
    {
70
      PORTC &= ~(1 << PC5);
71
    }
72
                
73
        }
74
}

Hoffe, ihr koennt mir weiterhelfen...
Moderator (Firma: Titel) Persönliche Seite #2495752
Lesenswert?

Andre S. schrieb:
> /* Funktion fuer Verzoegerung um eine ms (4 Takte) */
> void delay_ms(uint16_t ms) {
>         while ( ms )
>         {
>                 delay_ms(1);
>                 ms--;
>                 ms--;
>                 ms--;
>                 ms--;
>         }
> }
Dir ist klar, dass diese Funktion, wenn sie z.B. mit dem Wert 3  oder 
auch 5 oder auch 7 (usw... eben alles, was nicht durch 4 teilbar ist) 
aufgerufen wird, recht lang zum Beenden baucht?

Zudem ist das Ganze rekursiv:
> void delay_ms(uint16_t ms) {
>         while ( ms )
>         {
>                 delay_ms(1);
Ein Glück nur, dass die Funktion niemals aufgerufen wird...  ;-)

> Zur Zeit versuche ich, ein Bisschen mit dem ADC herumzuspielen und je
> nach Spannungsbereich verschiedene LEDs schalten zu lassen.
> Allerdings blinken die LEDs bei mir immer nur und schalten nie auf
> 'Dauerlicht'.
Wie schnell blinken die LEDs?
Welche LEDs blinken?
Wie sind die LEDs angeschlossen?
OP #2496838
Lesenswert?

Hallo,
> Dir ist klar, dass diese Funktion, wenn sie z.B. mit dem Wert 3  oder
> auch 5 oder auch 7 (usw... eben alles, was nicht durch 4 teilbar ist)
> aufgerufen wird, recht lang zum Beenden baucht?

darueber habe ich mir noch keine Gedanken gemacht, aber danke fuer den 
Hinweis!

> Ein Glück nur, dass die Funktion niemals aufgerufen wird...  ;-)

Naja, das war praktisch mein erstes Projekt - eine blinkende LED. Und 
die habe ich mit dieser Funktion verzoegert...

Die LEDs blinken nicht mehr, ich habe einfach den Programmer abgezogen 
weil ich mir irgendwann nicht mehr erklaeren konnte, was das eigentlich 
soll - und nach einer Stunde (und einem Reboot) habe ich alles wieder 
angesteckt, den Code nochmal auf den Controller geschrieben und siehe 
da, es hat funktioniert :-).

Trotzdem danke!
Persönliche Seite #2496958
Lesenswert?

Dieses hier ist doppelt gemoppelt

if (adcval > 512)
    {
      PORTC &= ~(1 << PC3);
    }
    else if (adcval <= 512)
    {
      PORTC &= ~(1 << PC5);
    }


if (adcval > 512)
{
  PORTC &= ~(1 << PC3);
}
else
{ //wenn adcval nicht größer als 512 ist,kann es nur kleiner oder gleich 
sein
  PORTC &= ~(1 << PC5);
}

Zum Problem:

Sind die Werte vielleicht Schaltungsbedingt einfach nur zu instabil ?
Welcher Controller ist da gemeinst ?

Wieso laut deines Programmes die LED's überhaupt blinken ist schon 
merkwürdig.
Denn laut Programm müßten die LED's am Ende nur ausgeschalten werden.
Allerdings sind sie schon nach dem RESET aus, per default.
OP #2497242
Lesenswert?

Ja, die Grenzen hatte ich hier fuers Forum so gesetzt. Ich habe ein paar 
mehr LEDs rangehangen und die Bereiche entsprechend fein aufgeteilt.

Die LEDs haben scheinbar geblinkt, weil ich vorher ein entsprechendes 
Programm dafuer geschrieben hatte, das 'neue' ADC-Programm wurde dann 
aber irgendwie nicht draufgeschoben, sondern ich muss (wie bereits 
geschrieben) den Programmer abziehen, habe irgendwann mal einen Reboot 
gemacht und dann lief alles wieder.
Trotzdem danke fuer deine Antwort.

Gruss,
pipesmoker

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren