Forum: Mikrocontroller und Digitale Elektronik ADC: LED blinkt nur


von Andre S. (pipesmoker)


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...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?

von reverse (Gast)


Lesenswert?

wenn das der ganze Code ist und die Hartware richtig angeschlossen ist, 
dann versteh ich nicht wieso es bei dir blinkt, außer wenn der uC immer 
resetet

von Andre S. (pipesmoker)


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!

von Dennis H. (c-logic) Benutzerseite


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.

von Andre S. (pipesmoker)


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

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.